Merge "Use mutex to implement queueing" into androidx-main
diff --git a/.github/workflows/update_prebuilts.yml b/.github/workflows/update_prebuilts.yml
index 0eff299..e6c5cde 100644
--- a/.github/workflows/update_prebuilts.yml
+++ b/.github/workflows/update_prebuilts.yml
@@ -23,6 +23,8 @@
         uses: actions/checkout@v2
       - name: "Run update prebuilt snapshot ids script"
         shell: bash
+        # this does not update metalava because it needs to match the
+        # metalava buildId used by androidx
         run: development/update_playground.sh
       - name: "Check if anything changed"
         shell: bash
diff --git a/.github/workflows/validate_gradle_wrapper.yml b/.github/workflows/validate_gradle_wrapper.yml
new file mode 100644
index 0000000..2e9a731
--- /dev/null
+++ b/.github/workflows/validate_gradle_wrapper.yml
@@ -0,0 +1,16 @@
+name: "Validate Gradle Wrapper"
+
+on: 
+  pull_request:
+    paths:
+    - 'gradlew'
+    - 'gradlew.bat'
+    - 'gradle/wrapper/'
+
+jobs:
+  validation:
+    name: "Validation"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - uses: gradle/wrapper-validation-action@v1
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index 22ecc41..01ee732 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -1,6 +1,26 @@
 // Signature format: 4.0
 package androidx.activity {
 
+  public final class BackEventCompat {
+    ctor @RequiresApi(34) public BackEventCompat(android.window.BackEvent backEvent);
+    ctor @VisibleForTesting public BackEventCompat(float touchX, float touchY, float progress, int swipeEdge);
+    method public float getProgress();
+    method public int getSwipeEdge();
+    method public float getTouchX();
+    method public float getTouchY();
+    method @RequiresApi(34) public android.window.BackEvent toBackEvent();
+    property public final float progress;
+    property public final int swipeEdge;
+    property public final float touchX;
+    property public final float touchY;
+    field public static final androidx.activity.BackEventCompat.Companion Companion;
+    field public static final int EDGE_LEFT = 0; // 0x0
+    field public static final int EDGE_RIGHT = 1; // 0x1
+  }
+
+  public static final class BackEventCompat.Companion {
+  }
+
   public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.activity.FullyDrawnReporterOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.core.view.MenuHost androidx.activity.OnBackPressedDispatcherOwner androidx.core.content.OnConfigurationChangedProvider androidx.core.app.OnMultiWindowModeChangedProvider androidx.core.app.OnNewIntentProvider androidx.core.app.OnPictureInPictureModeChangedProvider androidx.core.content.OnTrimMemoryProvider androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
@@ -85,7 +105,10 @@
 
   public abstract class OnBackPressedCallback {
     ctor public OnBackPressedCallback(boolean enabled);
+    method @MainThread public void handleOnBackCancelled();
     method @MainThread public abstract void handleOnBackPressed();
+    method @MainThread public void handleOnBackProgressed(androidx.activity.BackEventCompat backEvent);
+    method @MainThread public void handleOnBackStarted(androidx.activity.BackEventCompat backEvent);
     method @MainThread public final boolean isEnabled();
     method @MainThread public final void remove();
     method @MainThread public final void setEnabled(boolean);
@@ -95,8 +118,12 @@
   public final class OnBackPressedDispatcher {
     ctor public OnBackPressedDispatcher();
     ctor public OnBackPressedDispatcher(optional Runnable? fallbackOnBackPressed);
+    ctor public OnBackPressedDispatcher(Runnable? fallbackOnBackPressed, androidx.core.util.Consumer<java.lang.Boolean>? onHasEnabledCallbacksChanged);
     method @MainThread public void addCallback(androidx.activity.OnBackPressedCallback onBackPressedCallback);
     method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner owner, androidx.activity.OnBackPressedCallback onBackPressedCallback);
+    method @MainThread @VisibleForTesting public void dispatchOnBackCancelled();
+    method @MainThread @VisibleForTesting public void dispatchOnBackProgressed(androidx.activity.BackEventCompat backEvent);
+    method @MainThread @VisibleForTesting public void dispatchOnBackStarted(androidx.activity.BackEventCompat backEvent);
     method @MainThread public boolean hasEnabledCallbacks();
     method @MainThread public void onBackPressed();
     method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void setOnBackInvokedDispatcher(android.window.OnBackInvokedDispatcher invoker);
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 10c4134..3abd207 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -1,6 +1,26 @@
 // Signature format: 4.0
 package androidx.activity {
 
+  public final class BackEventCompat {
+    ctor @RequiresApi(34) public BackEventCompat(android.window.BackEvent backEvent);
+    ctor @VisibleForTesting public BackEventCompat(float touchX, float touchY, float progress, int swipeEdge);
+    method public float getProgress();
+    method public int getSwipeEdge();
+    method public float getTouchX();
+    method public float getTouchY();
+    method @RequiresApi(34) public android.window.BackEvent toBackEvent();
+    property public final float progress;
+    property public final int swipeEdge;
+    property public final float touchX;
+    property public final float touchY;
+    field public static final androidx.activity.BackEventCompat.Companion Companion;
+    field public static final int EDGE_LEFT = 0; // 0x0
+    field public static final int EDGE_RIGHT = 1; // 0x1
+  }
+
+  public static final class BackEventCompat.Companion {
+  }
+
   public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.activity.result.ActivityResultRegistryOwner androidx.activity.contextaware.ContextAware androidx.activity.FullyDrawnReporterOwner androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.core.view.MenuHost androidx.activity.OnBackPressedDispatcherOwner androidx.core.content.OnConfigurationChangedProvider androidx.core.app.OnMultiWindowModeChangedProvider androidx.core.app.OnNewIntentProvider androidx.core.app.OnPictureInPictureModeChangedProvider androidx.core.content.OnTrimMemoryProvider androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
     ctor public ComponentActivity();
     ctor @ContentView public ComponentActivity(@LayoutRes int);
@@ -84,7 +104,10 @@
 
   public abstract class OnBackPressedCallback {
     ctor public OnBackPressedCallback(boolean enabled);
+    method @MainThread public void handleOnBackCancelled();
     method @MainThread public abstract void handleOnBackPressed();
+    method @MainThread public void handleOnBackProgressed(androidx.activity.BackEventCompat backEvent);
+    method @MainThread public void handleOnBackStarted(androidx.activity.BackEventCompat backEvent);
     method @MainThread public final boolean isEnabled();
     method @MainThread public final void remove();
     method @MainThread public final void setEnabled(boolean);
@@ -94,8 +117,12 @@
   public final class OnBackPressedDispatcher {
     ctor public OnBackPressedDispatcher();
     ctor public OnBackPressedDispatcher(optional Runnable? fallbackOnBackPressed);
+    ctor public OnBackPressedDispatcher(Runnable? fallbackOnBackPressed, androidx.core.util.Consumer<java.lang.Boolean>? onHasEnabledCallbacksChanged);
     method @MainThread public void addCallback(androidx.activity.OnBackPressedCallback onBackPressedCallback);
     method @MainThread public void addCallback(androidx.lifecycle.LifecycleOwner owner, androidx.activity.OnBackPressedCallback onBackPressedCallback);
+    method @MainThread @VisibleForTesting public void dispatchOnBackCancelled();
+    method @MainThread @VisibleForTesting public void dispatchOnBackProgressed(androidx.activity.BackEventCompat backEvent);
+    method @MainThread @VisibleForTesting public void dispatchOnBackStarted(androidx.activity.BackEventCompat backEvent);
     method @MainThread public boolean hasEnabledCallbacks();
     method @MainThread public void onBackPressed();
     method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public void setOnBackInvokedDispatcher(android.window.OnBackInvokedDispatcher invoker);
diff --git a/activity/activity/lint-baseline.xml b/activity/activity/lint-baseline.xml
index d97aee4..75b58da 100644
--- a/activity/activity/lint-baseline.xml
+++ b/activity/activity/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="PrereleaseSdkCoreDependency"
diff --git a/activity/activity/src/androidTest/java/androidx/activity/BackEventCompatTest.kt b/activity/activity/src/androidTest/java/androidx/activity/BackEventCompatTest.kt
new file mode 100644
index 0000000..e04d827
--- /dev/null
+++ b/activity/activity/src/androidTest/java/androidx/activity/BackEventCompatTest.kt
@@ -0,0 +1,63 @@
+/*
+ * 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.activity
+
+import android.window.BackEvent
+import android.window.BackEvent.EDGE_LEFT
+import androidx.annotation.RequiresApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BackEventCompatTest {
+
+    @Test
+    fun testCreateBackEventCompat() {
+        val event = BackEventCompat(1f, 2f, 3f, BackEventCompat.EDGE_LEFT)
+        assertThat(event.touchX).isEqualTo(1f)
+        assertThat(event.touchY).isEqualTo(2f)
+        assertThat(event.progress).isEqualTo(3f)
+        assertThat(event.swipeEdge).isEqualTo(BackEventCompat.EDGE_LEFT)
+    }
+
+    @RequiresApi(34)
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun testCreateBackEventCompatFromBackEvent() {
+        val event = BackEventCompat(BackEvent(1f, 2f, 3f, EDGE_LEFT))
+        assertThat(event.touchX).isEqualTo(1f)
+        assertThat(event.touchY).isEqualTo(2f)
+        assertThat(event.progress).isEqualTo(3f)
+        assertThat(event.swipeEdge).isEqualTo(BackEventCompat.EDGE_LEFT)
+    }
+
+    @RequiresApi(34)
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun testToBackEventFromBackEventCompat() {
+        val event = BackEventCompat(1f, 2f, 3f, BackEventCompat.EDGE_LEFT).toBackEvent()
+        assertThat(event.touchX).isEqualTo(1f)
+        assertThat(event.touchY).isEqualTo(2f)
+        assertThat(event.progress).isEqualTo(3f)
+        assertThat(event.swipeEdge).isEqualTo(BackEventCompat.EDGE_LEFT)
+    }
+}
\ No newline at end of file
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
index 1ff31b7..3d31980 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherInvokerTest.kt
@@ -17,6 +17,7 @@
 package androidx.activity
 
 import android.os.Build
+import android.window.BackEvent.EDGE_LEFT
 import android.window.OnBackInvokedCallback
 import android.window.OnBackInvokedDispatcher
 import androidx.annotation.RequiresApi
@@ -180,4 +181,57 @@
 
         assertThat(unregisterCount).isEqualTo(1)
     }
+
+    @Test
+    fun testSimpleAnimatedCallback() {
+        var registerCount = 0
+        var unregisterCount = 0
+        val invoker = object : OnBackInvokedDispatcher {
+            override fun registerOnBackInvokedCallback(p0: Int, p1: OnBackInvokedCallback) {
+                registerCount++
+            }
+
+            override fun unregisterOnBackInvokedCallback(p0: OnBackInvokedCallback) {
+                unregisterCount++
+            }
+        }
+
+        val dispatcher = OnBackPressedDispatcher()
+
+        dispatcher.setOnBackInvokedDispatcher(invoker)
+
+        var startedCount = 0
+        var progressedCount = 0
+        var cancelledCount = 0
+        val callback = object : OnBackPressedCallback(true) {
+            override fun handleOnBackStarted(backEvent: BackEventCompat) {
+                startedCount++
+            }
+
+            override fun handleOnBackProgressed(backEvent: BackEventCompat) {
+                progressedCount++
+            }
+            override fun handleOnBackPressed() { }
+            override fun handleOnBackCancelled() {
+                cancelledCount++
+            }
+        }
+
+        dispatcher.addCallback(callback)
+
+        assertThat(registerCount).isEqualTo(1)
+
+        dispatcher.dispatchOnBackStarted(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
+        assertThat(startedCount).isEqualTo(1)
+
+        dispatcher.dispatchOnBackProgressed(BackEventCompat(0.1F, 0.1F, 0.1F, EDGE_LEFT))
+        assertThat(progressedCount).isEqualTo(1)
+
+        dispatcher.dispatchOnBackCancelled()
+        assertThat(cancelledCount).isEqualTo(1)
+
+        callback.remove()
+
+        assertThat(unregisterCount).isEqualTo(1)
+    }
 }
diff --git a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
index 51cf3de..afbe0ea 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/OnBackPressedDispatcherTest.kt
@@ -441,6 +441,80 @@
             withActivity { realDispatcher.onBackPressed() }
         }
     }
+
+    @Test
+    fun testOnHasEnabledCallbacks() {
+        var reportedHasEnabledCallbacks = false
+        var reportCount = 0
+        val dispatcher = OnBackPressedDispatcher(
+            fallbackOnBackPressed = null,
+            onHasEnabledCallbacksChanged = {
+                reportedHasEnabledCallbacks = it
+                reportCount++
+            }
+        )
+
+        assertWithMessage("initial reportCount")
+            .that(reportCount)
+            .isEqualTo(0)
+        assertWithMessage("initial reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isFalse()
+
+        val callbackA = dispatcher.addCallback(enabled = false) {}
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(0)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isFalse()
+
+        callbackA.isEnabled = true
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(1)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isTrue()
+
+        val callbackB = dispatcher.addCallback {}
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(1)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isTrue()
+
+        callbackA.remove()
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(1)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isTrue()
+
+        callbackB.remove()
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(2)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isFalse()
+
+        dispatcher.addCallback {}
+
+        assertWithMessage("reportCount")
+            .that(reportCount)
+            .isEqualTo(3)
+        assertWithMessage("reportedHasEnabledCallbacks")
+            .that(reportedHasEnabledCallbacks)
+            .isTrue()
+    }
 }
 
 open class CountingOnBackPressedCallback(
diff --git a/activity/activity/src/main/java/androidx/activity/BackEventCompat.kt b/activity/activity/src/main/java/androidx/activity/BackEventCompat.kt
new file mode 100644
index 0000000..cbc3521
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/BackEventCompat.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.activity
+
+import android.os.Build
+import android.window.BackEvent
+import androidx.annotation.DoNotInline
+import androidx.annotation.IntDef
+import androidx.annotation.OptIn
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.core.os.BuildCompat
+
+/**
+ * Compat around the [BackEvent] class
+ */
+class BackEventCompat @VisibleForTesting constructor(
+    /**
+     * Absolute X location of the touch point of this event.
+     */
+    val touchX: Float,
+    /**
+     * Absolute Y location of the touch point of this event.
+     */
+    val touchY: Float,
+    /**
+     * Value between 0 and 1 on how far along the back gesture is.
+     */
+    val progress: Float,
+    /**
+     * Indicates which edge the swipe starts from.
+     */
+    val swipeEdge: @SwipeEdge Int
+) {
+
+    @RequiresApi(34)
+    @OptIn(BuildCompat.PrereleaseSdkCheck::class)
+    constructor(backEvent: BackEvent) : this (
+        Api34Impl.touchX(backEvent),
+        Api34Impl.touchY(backEvent),
+        Api34Impl.progress(backEvent),
+        Api34Impl.swipeEdge(backEvent)
+    )
+
+    /**
+     */
+    @Target(AnnotationTarget.TYPE)
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @Retention(AnnotationRetention.SOURCE)
+    @IntDef(EDGE_LEFT, EDGE_RIGHT)
+    annotation class SwipeEdge
+
+    /**
+     * Convert this compat object to [BackEvent] object.
+     *
+     * @return [BackEvent] object
+     *
+     * @throws UnsupportedOperationException if this API is called on an API prior to 34.
+     */
+    @RequiresApi(34)
+    @OptIn(BuildCompat.PrereleaseSdkCheck::class)
+    @Suppress("PrereleaseSdkCoreDependency")
+    fun toBackEvent(): BackEvent {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.createOnBackEvent(touchX, touchY, progress, swipeEdge)
+        } else {
+            throw UnsupportedOperationException("This method is only supported on API level 34+")
+        }
+    }
+
+    override fun toString(): String {
+        return "BackEventCompat{touchX=$touchX, touchY=$touchY, progress=$progress, " +
+            "swipeEdge=$swipeEdge}"
+    }
+
+    companion object {
+        /** Indicates that the edge swipe starts from the left edge of the screen  */
+        const val EDGE_LEFT = 0
+
+        /** Indicates that the edge swipe starts from the right edge of the screen  */
+        const val EDGE_RIGHT = 1
+    }
+}
+
+@RequiresApi(34)
+internal object Api34Impl {
+    @DoNotInline
+    fun createOnBackEvent(touchX: Float, touchY: Float, progress: Float, swipeEdge: Int) =
+        BackEvent(touchX, touchY, progress, swipeEdge)
+
+    @DoNotInline
+    fun progress(backEvent: BackEvent) = backEvent.progress
+
+    @DoNotInline
+    fun touchX(backEvent: BackEvent) = backEvent.touchX
+
+    @DoNotInline
+    fun touchY(backEvent: BackEvent) = backEvent.touchY
+
+    @DoNotInline
+    fun swipeEdge(backEvent: BackEvent) = backEvent.swipeEdge
+}
\ No newline at end of file
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt
index 3101ef7..69038fe 100644
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt
@@ -67,11 +67,41 @@
     fun remove() = cancellables.forEach { it.cancel() }
 
     /**
+     * Callback for handling the system UI generated equivalent to
+     * [OnBackPressedDispatcher.dispatchOnBackStarted].
+     *
+     * This will only be called by the framework on API 34 and above.
+     */
+    @Suppress("CallbackMethodName") /* mirror handleOnBackPressed local style */
+    @MainThread
+    open fun handleOnBackStarted(backEvent: BackEventCompat) {}
+
+    /**
+     * Callback for handling the system UI generated equivalent to
+     * [OnBackPressedDispatcher.dispatchOnBackProgressed].
+     *
+     * This will only be called by the framework on API 34 and above.
+     */
+    @Suppress("CallbackMethodName") /* mirror handleOnBackPressed local style */
+    @MainThread
+    open fun handleOnBackProgressed(backEvent: BackEventCompat) {}
+
+    /**
      * Callback for handling the [OnBackPressedDispatcher.onBackPressed] event.
      */
     @MainThread
     abstract fun handleOnBackPressed()
 
+    /**
+     * Callback for handling the system UI generated equivalent to
+     * [OnBackPressedDispatcher.dispatchOnBackCancelled].
+     *
+     * This will only be called by the framework on API 34 and above.
+     */
+    @Suppress("CallbackMethodName") /* mirror handleOnBackPressed local style */
+    @MainThread
+    open fun handleOnBackCancelled() {}
+
     @JvmName("addCancellable")
     internal fun addCancellable(cancellable: Cancellable) {
         cancellables.add(cancellable)
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
index 5319d9e..ef664f3 100644
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedDispatcher.kt
@@ -16,11 +16,15 @@
 package androidx.activity
 
 import android.os.Build
+import android.window.BackEvent
+import android.window.OnBackAnimationCallback
 import android.window.OnBackInvokedCallback
 import android.window.OnBackInvokedDispatcher
 import androidx.annotation.DoNotInline
 import androidx.annotation.MainThread
 import androidx.annotation.RequiresApi
+import androidx.annotation.VisibleForTesting
+import androidx.core.util.Consumer
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleEventObserver
 import androidx.lifecycle.LifecycleOwner
@@ -51,14 +55,25 @@
  * When constructing an instance of this class, the [fallbackOnBackPressed] can be set to
  * receive a callback if [onBackPressed] is called when [hasEnabledCallbacks] returns `false`.
  */
-class OnBackPressedDispatcher @JvmOverloads constructor(
-    private val fallbackOnBackPressed: Runnable? = null
+// Implementation/API compatibility note: previous releases included only the Runnable? constructor,
+// which permitted both first-argument and trailing lambda call syntax to specify
+// fallbackOnBackPressed. To avoid silently breaking source compatibility the new
+// primary constructor has no optional parameters to avoid ambiguity/wrong overload resolution
+// when a single parameter is provided as a trailing lambda.
+class OnBackPressedDispatcher constructor(
+    private val fallbackOnBackPressed: Runnable?,
+    private val onHasEnabledCallbacksChanged: Consumer<Boolean>?
 ) {
     private val onBackPressedCallbacks = ArrayDeque<OnBackPressedCallback>()
-    private var enabledChangedCallback: (() -> Unit)? = null
     private var onBackInvokedCallback: OnBackInvokedCallback? = null
     private var invokedDispatcher: OnBackInvokedDispatcher? = null
     private var backInvokedCallbackRegistered = false
+    private var hasEnabledCallbacks = false
+
+    @JvmOverloads
+    constructor(
+        fallbackOnBackPressed: Runnable? = null
+    ) : this(fallbackOnBackPressed, null)
 
     /**
      * Sets the [OnBackInvokedDispatcher] for handling system back for Android SDK T+.
@@ -68,12 +83,11 @@
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     fun setOnBackInvokedDispatcher(invoker: OnBackInvokedDispatcher) {
         invokedDispatcher = invoker
-        updateBackInvokedCallbackState()
+        updateBackInvokedCallbackState(hasEnabledCallbacks)
     }
 
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-    internal fun updateBackInvokedCallbackState() {
-        val shouldBeRegistered = hasEnabledCallbacks()
+    private fun updateBackInvokedCallbackState(shouldBeRegistered: Boolean) {
         val dispatcher = invokedDispatcher
         val onBackInvokedCallback = onBackInvokedCallback
         if (dispatcher != null && onBackInvokedCallback != null) {
@@ -94,12 +108,30 @@
         }
     }
 
+    private fun updateEnabledCallbacks() {
+        val hadEnabledCallbacks = hasEnabledCallbacks
+        val hasEnabledCallbacks = onBackPressedCallbacks.any { it.isEnabled }
+        this.hasEnabledCallbacks = hasEnabledCallbacks
+        if (hasEnabledCallbacks != hadEnabledCallbacks) {
+            onHasEnabledCallbacksChanged?.accept(hasEnabledCallbacks)
+            if (Build.VERSION.SDK_INT >= 33) {
+                updateBackInvokedCallbackState(hasEnabledCallbacks)
+            }
+        }
+    }
+
     init {
         if (Build.VERSION.SDK_INT >= 33) {
-            enabledChangedCallback = {
-                updateBackInvokedCallbackState()
+            onBackInvokedCallback = if (Build.VERSION.SDK_INT >= 34) {
+                Api34Impl.createOnBackAnimationCallback(
+                    { backEvent -> onBackStarted(backEvent) },
+                    { backEvent -> onBackProgressed(backEvent) },
+                    { onBackPressed() },
+                    { onBackCancelled() }
+                )
+            } else {
+                Api33Impl.createOnBackInvokedCallback { onBackPressed() }
             }
-            onBackInvokedCallback = Api33Impl.createOnBackInvokedCallback { onBackPressed() }
         }
     }
 
@@ -137,10 +169,8 @@
         onBackPressedCallbacks.add(onBackPressedCallback)
         val cancellable = OnBackPressedCancellable(onBackPressedCallback)
         onBackPressedCallback.addCancellable(cancellable)
-        if (Build.VERSION.SDK_INT >= 33) {
-            updateBackInvokedCallbackState()
-            onBackPressedCallback.enabledChangedCallback = enabledChangedCallback
-        }
+        updateEnabledCallbacks()
+        onBackPressedCallback.enabledChangedCallback = ::updateEnabledCallbacks
         return cancellable
     }
 
@@ -178,21 +208,51 @@
         onBackPressedCallback.addCancellable(
             LifecycleOnBackPressedCancellable(lifecycle, onBackPressedCallback)
         )
-        if (Build.VERSION.SDK_INT >= 33) {
-            updateBackInvokedCallbackState()
-            onBackPressedCallback.enabledChangedCallback = enabledChangedCallback
-        }
+        updateEnabledCallbacks()
+        onBackPressedCallback.enabledChangedCallback = ::updateEnabledCallbacks
     }
 
     /**
-     * Checks if there is at least one [enabled][OnBackPressedCallback.isEnabled]
+     * Returns `true` if there is at least one [enabled][OnBackPressedCallback.isEnabled]
      * callback registered with this dispatcher.
      *
      * @return True if there is at least one enabled callback.
      */
     @MainThread
-    fun hasEnabledCallbacks(): Boolean = onBackPressedCallbacks.any {
-        it.isEnabled
+    fun hasEnabledCallbacks(): Boolean = hasEnabledCallbacks
+
+    @VisibleForTesting
+    @MainThread
+    fun dispatchOnBackStarted(backEvent: BackEventCompat) {
+        onBackStarted(backEvent)
+    }
+
+    @MainThread
+    private fun onBackStarted(backEvent: BackEventCompat) {
+        val callback = onBackPressedCallbacks.lastOrNull {
+            it.isEnabled
+        }
+        if (callback != null) {
+            callback.handleOnBackStarted(backEvent)
+            return
+        }
+    }
+
+    @VisibleForTesting
+    @MainThread
+    fun dispatchOnBackProgressed(backEvent: BackEventCompat) {
+        onBackProgressed(backEvent)
+    }
+
+    @MainThread
+    private fun onBackProgressed(backEvent: BackEventCompat) {
+        val callback = onBackPressedCallbacks.lastOrNull {
+            it.isEnabled
+        }
+        if (callback != null) {
+            callback.handleOnBackProgressed(backEvent)
+            return
+        }
     }
 
     /**
@@ -216,16 +276,31 @@
         fallbackOnBackPressed?.run()
     }
 
+    @VisibleForTesting
+    @MainThread
+    fun dispatchOnBackCancelled() {
+        onBackCancelled()
+    }
+
+    @MainThread
+    private fun onBackCancelled() {
+        val callback = onBackPressedCallbacks.lastOrNull {
+            it.isEnabled
+        }
+        if (callback != null) {
+            callback.handleOnBackCancelled()
+            return
+        }
+    }
+
     private inner class OnBackPressedCancellable(
         private val onBackPressedCallback: OnBackPressedCallback
     ) : Cancellable {
         override fun cancel() {
             onBackPressedCallbacks.remove(onBackPressedCallback)
             onBackPressedCallback.removeCancellable(this)
-            if (Build.VERSION.SDK_INT >= 33) {
-                onBackPressedCallback.enabledChangedCallback = null
-                updateBackInvokedCallbackState()
-            }
+            onBackPressedCallback.enabledChangedCallback?.invoke()
+            onBackPressedCallback.enabledChangedCallback = null
         }
     }
 
@@ -286,6 +361,35 @@
             return OnBackInvokedCallback { onBackInvoked() }
         }
     }
+
+    @RequiresApi(34)
+    internal object Api34Impl {
+        @DoNotInline
+        fun createOnBackAnimationCallback(
+            onBackStarted: (backEvent: BackEventCompat) -> Unit,
+            onBackProgressed: (backEvent: BackEventCompat) -> Unit,
+            onBackInvoked: () -> Unit,
+            onBackCancelled: () -> Unit
+        ): OnBackInvokedCallback {
+            return object : OnBackAnimationCallback {
+                override fun onBackStarted(backEvent: BackEvent) {
+                    onBackStarted(BackEventCompat(backEvent))
+                }
+
+                override fun onBackProgressed(backEvent: BackEvent) {
+                    onBackProgressed(BackEventCompat(backEvent))
+                }
+
+                override fun onBackInvoked() {
+                    onBackInvoked()
+                }
+
+                override fun onBackCancelled() {
+                    onBackCancelled()
+                }
+            }
+        }
+    }
 }
 
 /**
diff --git a/annotation/annotation-experimental-lint/lint-baseline.xml b/annotation/annotation-experimental-lint/lint-baseline.xml
deleted file mode 100644
index 1fd57e2..0000000
--- a/annotation/annotation-experimental-lint/lint-baseline.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="    @ExperimentalKotlinAnnotation"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/kotlin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="    @ExperimentalKotlinAnnotation"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/optin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="    @set:ExperimentalKotlinAnnotation"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/kotlin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="    @set:ExperimentalKotlinAnnotation"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/optin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="        @ExperimentalKotlinAnnotation"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/kotlin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="        @ExperimentalKotlinAnnotation"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="integration-tests/src/main/java/sample/optin/AnnotatedKotlinMembers.kt"/>
-    </issue>
-
-</issues>
diff --git a/annotation/annotation/api/api_lint.ignore b/annotation/annotation/api/api_lint.ignore
new file mode 100644
index 0000000..9f6c2ee
--- /dev/null
+++ b/annotation/annotation/api/api_lint.ignore
@@ -0,0 +1,17 @@
+// Baseline format: 1.0
+GetterSetterNames: field FloatRange.fromInclusive:
+    Invalid name for boolean property `fromInclusive`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field FloatRange.toInclusive:
+    Invalid name for boolean property `toInclusive`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field IntDef.flag:
+    Invalid name for boolean property `flag`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field IntDef.open:
+    Invalid name for boolean property `open`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LongDef.flag:
+    Invalid name for boolean property `flag`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field LongDef.open:
+    Invalid name for boolean property `open`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field RequiresPermission.conditional:
+    Invalid name for boolean property `conditional`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field StringDef.open:
+    Invalid name for boolean property `open`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/annotation/annotation/api/current.ignore b/annotation/annotation/api/current.ignore
index 7cc038b..8c6aaac 100644
--- a/annotation/annotation/api/current.ignore
+++ b/annotation/annotation/api/current.ignore
@@ -1,13 +1,5 @@
 // Baseline format: 1.0
-ChangedValue: androidx.annotation.FloatRange#from():
-    Method androidx.annotation.FloatRange.from has changed value from java.lang.Double.NEGATIVE_INFINITY to kotlin.jvm.internal.DoubleCompanionObject.NEGATIVE_INFINITY
-ChangedValue: androidx.annotation.FloatRange#to():
-    Method androidx.annotation.FloatRange.to has changed value from java.lang.Double.POSITIVE_INFINITY to kotlin.jvm.internal.DoubleCompanionObject.POSITIVE_INFINITY
-ChangedValue: androidx.annotation.IntRange#from():
-    Method androidx.annotation.IntRange.from has changed value from java.lang.Long.MIN_VALUE to kotlin.jvm.internal.LongCompanionObject.MIN_VALUE
-ChangedValue: androidx.annotation.IntRange#to():
-    Method androidx.annotation.IntRange.to has changed value from java.lang.Long.MAX_VALUE to kotlin.jvm.internal.LongCompanionObject.MAX_VALUE
-ChangedValue: androidx.annotation.Size#max():
-    Method androidx.annotation.Size.max has changed value from java.lang.Long.MAX_VALUE to kotlin.jvm.internal.LongCompanionObject.MAX_VALUE
-ChangedValue: androidx.annotation.Size#min():
-    Method androidx.annotation.Size.min has changed value from java.lang.Long.MIN_VALUE to kotlin.jvm.internal.LongCompanionObject.MIN_VALUE
+ParameterNameChange: androidx.annotation.InspectableProperty.ValueType#valueOf(String) parameter #0:
+    Attempted to change parameter name from name to value in method androidx.annotation.InspectableProperty.ValueType.valueOf
+ParameterNameChange: androidx.annotation.RestrictTo.Scope#valueOf(String) parameter #0:
+    Attempted to change parameter name from name to value in method androidx.annotation.RestrictTo.Scope.valueOf
diff --git a/annotation/annotation/api/current.txt b/annotation/annotation/api/current.txt
index 660800c..71556c1 100644
--- a/annotation/annotation/api/current.txt
+++ b/annotation/annotation/api/current.txt
@@ -138,32 +138,32 @@
     method @Deprecated public abstract boolean hasAttributeId() default true;
     method @Deprecated public abstract String name() default "";
     method @Deprecated public abstract androidx.annotation.InspectableProperty.ValueType valueType() default androidx.annotation.InspectableProperty.ValueType.INFERRED;
-    property public abstract int attributeId;
-    property public abstract androidx.annotation.InspectableProperty.EnumEntry[] enumMapping;
-    property public abstract androidx.annotation.InspectableProperty.FlagEntry[] flagMapping;
-    property public abstract boolean hasAttributeId;
-    property public abstract String name;
-    property public abstract androidx.annotation.InspectableProperty.ValueType valueType;
+    property @Deprecated public abstract int attributeId;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.EnumEntry[] enumMapping;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.FlagEntry[] flagMapping;
+    property @Deprecated public abstract boolean hasAttributeId;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.ValueType valueType;
   }
 
   @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface InspectableProperty.EnumEntry {
     method @Deprecated public abstract String name();
     method @Deprecated public abstract int value();
-    property public abstract String name;
-    property public abstract int value;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract int value;
   }
 
   @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface InspectableProperty.FlagEntry {
     method @Deprecated public abstract int mask() default 0;
     method @Deprecated public abstract String name();
     method @Deprecated public abstract int target();
-    property public abstract int mask;
-    property public abstract String name;
-    property public abstract int target;
+    property @Deprecated public abstract int mask;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract int target;
   }
 
   @Deprecated public enum InspectableProperty.ValueType {
-    method @Deprecated public static androidx.annotation.InspectableProperty.ValueType valueOf(String name) throws java.lang.IllegalArgumentException;
+    method @Deprecated public static androidx.annotation.InspectableProperty.ValueType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method @Deprecated public static androidx.annotation.InspectableProperty.ValueType[] values();
     enum_constant @Deprecated public static final androidx.annotation.InspectableProperty.ValueType COLOR;
     enum_constant @Deprecated public static final androidx.annotation.InspectableProperty.ValueType GRAVITY;
@@ -293,7 +293,7 @@
   }
 
   public enum RestrictTo.Scope {
-    method public static androidx.annotation.RestrictTo.Scope valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.annotation.RestrictTo.Scope valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.annotation.RestrictTo.Scope[] values();
     enum_constant @Deprecated public static final androidx.annotation.RestrictTo.Scope GROUP_ID;
     enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY;
@@ -342,7 +342,7 @@
   @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER}) public @interface UiThread {
   }
 
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface VisibleForTesting {
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface VisibleForTesting {
     method public abstract int otherwise() default androidx.annotation.VisibleForTesting.PRIVATE;
     property public abstract int otherwise;
     field public static final androidx.annotation.VisibleForTesting.Companion Companion;
diff --git a/annotation/annotation/api/restricted_current.ignore b/annotation/annotation/api/restricted_current.ignore
index 7cc038b..8c6aaac 100644
--- a/annotation/annotation/api/restricted_current.ignore
+++ b/annotation/annotation/api/restricted_current.ignore
@@ -1,13 +1,5 @@
 // Baseline format: 1.0
-ChangedValue: androidx.annotation.FloatRange#from():
-    Method androidx.annotation.FloatRange.from has changed value from java.lang.Double.NEGATIVE_INFINITY to kotlin.jvm.internal.DoubleCompanionObject.NEGATIVE_INFINITY
-ChangedValue: androidx.annotation.FloatRange#to():
-    Method androidx.annotation.FloatRange.to has changed value from java.lang.Double.POSITIVE_INFINITY to kotlin.jvm.internal.DoubleCompanionObject.POSITIVE_INFINITY
-ChangedValue: androidx.annotation.IntRange#from():
-    Method androidx.annotation.IntRange.from has changed value from java.lang.Long.MIN_VALUE to kotlin.jvm.internal.LongCompanionObject.MIN_VALUE
-ChangedValue: androidx.annotation.IntRange#to():
-    Method androidx.annotation.IntRange.to has changed value from java.lang.Long.MAX_VALUE to kotlin.jvm.internal.LongCompanionObject.MAX_VALUE
-ChangedValue: androidx.annotation.Size#max():
-    Method androidx.annotation.Size.max has changed value from java.lang.Long.MAX_VALUE to kotlin.jvm.internal.LongCompanionObject.MAX_VALUE
-ChangedValue: androidx.annotation.Size#min():
-    Method androidx.annotation.Size.min has changed value from java.lang.Long.MIN_VALUE to kotlin.jvm.internal.LongCompanionObject.MIN_VALUE
+ParameterNameChange: androidx.annotation.InspectableProperty.ValueType#valueOf(String) parameter #0:
+    Attempted to change parameter name from name to value in method androidx.annotation.InspectableProperty.ValueType.valueOf
+ParameterNameChange: androidx.annotation.RestrictTo.Scope#valueOf(String) parameter #0:
+    Attempted to change parameter name from name to value in method androidx.annotation.RestrictTo.Scope.valueOf
diff --git a/annotation/annotation/api/restricted_current.txt b/annotation/annotation/api/restricted_current.txt
index 660800c..71556c1 100644
--- a/annotation/annotation/api/restricted_current.txt
+++ b/annotation/annotation/api/restricted_current.txt
@@ -138,32 +138,32 @@
     method @Deprecated public abstract boolean hasAttributeId() default true;
     method @Deprecated public abstract String name() default "";
     method @Deprecated public abstract androidx.annotation.InspectableProperty.ValueType valueType() default androidx.annotation.InspectableProperty.ValueType.INFERRED;
-    property public abstract int attributeId;
-    property public abstract androidx.annotation.InspectableProperty.EnumEntry[] enumMapping;
-    property public abstract androidx.annotation.InspectableProperty.FlagEntry[] flagMapping;
-    property public abstract boolean hasAttributeId;
-    property public abstract String name;
-    property public abstract androidx.annotation.InspectableProperty.ValueType valueType;
+    property @Deprecated public abstract int attributeId;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.EnumEntry[] enumMapping;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.FlagEntry[] flagMapping;
+    property @Deprecated public abstract boolean hasAttributeId;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract androidx.annotation.InspectableProperty.ValueType valueType;
   }
 
   @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface InspectableProperty.EnumEntry {
     method @Deprecated public abstract String name();
     method @Deprecated public abstract int value();
-    property public abstract String name;
-    property public abstract int value;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract int value;
   }
 
   @Deprecated @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface InspectableProperty.FlagEntry {
     method @Deprecated public abstract int mask() default 0;
     method @Deprecated public abstract String name();
     method @Deprecated public abstract int target();
-    property public abstract int mask;
-    property public abstract String name;
-    property public abstract int target;
+    property @Deprecated public abstract int mask;
+    property @Deprecated public abstract String name;
+    property @Deprecated public abstract int target;
   }
 
   @Deprecated public enum InspectableProperty.ValueType {
-    method @Deprecated public static androidx.annotation.InspectableProperty.ValueType valueOf(String name) throws java.lang.IllegalArgumentException;
+    method @Deprecated public static androidx.annotation.InspectableProperty.ValueType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method @Deprecated public static androidx.annotation.InspectableProperty.ValueType[] values();
     enum_constant @Deprecated public static final androidx.annotation.InspectableProperty.ValueType COLOR;
     enum_constant @Deprecated public static final androidx.annotation.InspectableProperty.ValueType GRAVITY;
@@ -293,7 +293,7 @@
   }
 
   public enum RestrictTo.Scope {
-    method public static androidx.annotation.RestrictTo.Scope valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.annotation.RestrictTo.Scope valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.annotation.RestrictTo.Scope[] values();
     enum_constant @Deprecated public static final androidx.annotation.RestrictTo.Scope GROUP_ID;
     enum_constant public static final androidx.annotation.RestrictTo.Scope LIBRARY;
@@ -342,7 +342,7 @@
   @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER, kotlin.annotation.AnnotationTarget.CONSTRUCTOR, kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER}) public @interface UiThread {
   }
 
-  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface VisibleForTesting {
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface VisibleForTesting {
     method public abstract int otherwise() default androidx.annotation.VisibleForTesting.PRIVATE;
     property public abstract int otherwise;
     field public static final androidx.annotation.VisibleForTesting.Companion Companion;
diff --git a/annotation/annotation/build.gradle b/annotation/annotation/build.gradle
index 21e996b..224bb34 100644
--- a/annotation/annotation/build.gradle
+++ b/annotation/annotation/build.gradle
@@ -1,5 +1,6 @@
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import androidx.build.Publish
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
@@ -14,6 +15,8 @@
     linux()
     ios()
 
+    defaultPlatform(PlatformIdentifier.JVM)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
index ce28be8..0d4fe97 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
@@ -34,10 +34,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME: String = "actions.intent.CREATE_CALL"
-
 /** A capability corresponding to actions.intent.CREATE_CALL */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = CreateCall.CAPABILITY_NAME)
 class CreateCall private constructor() {
     internal enum class SlotMetadata(val path: String) {
         CALL_FORMAT("call.callFormat"),
@@ -178,6 +176,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [CreateCall] capability. */
+        const val CAPABILITY_NAME: String = "actions.intent.CREATE_CALL"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
index 23f7b24..967a905 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
@@ -35,10 +35,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME: String = "actions.intent.CREATE_MESSAGE"
-
 /** A capability corresponding to actions.intent.CREATE_MESSAGE */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = CreateMessage.CAPABILITY_NAME)
 class CreateMessage private constructor() {
     internal enum class SlotMetadata(val path: String) {
         TEXT("message.text"),
@@ -176,6 +174,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [CreateMessage] capability. */
+        const val CAPABILITY_NAME: String = "actions.intent.CREATE_MESSAGE"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/AlarmSerializer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/AlarmSerializer.kt
index a794bbf..2e46f1d 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/AlarmSerializer.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/AlarmSerializer.kt
@@ -46,10 +46,6 @@
   "Alarm",
   Alarm::Builder,
   Alarm.Builder<*>::build
-).bindStringField(
-  "namespace",
-  { it.namespace },
-  Alarm.Builder<*>::setNamespace
 ).bindSpecField(
   "alarmSchedule",
   { it.alarmSchedule },
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/GenericErrorStatusSerializer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/GenericErrorStatusSerializer.kt
new file mode 100644
index 0000000..f81d7c2
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/GenericErrorStatusSerializer.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.appactions.interaction.capabilities.serializers.types
+
+import androidx.appactions.builtintypes.types.GenericErrorStatus
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpecBuilder
+import androidx.appactions.interaction.capabilities.serializers.properties.NAME_TYPE_SPEC
+import androidx.appactions.interaction.capabilities.serializers.properties.TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+
+val GENERIC_ERROR_STATUS_TYPE_SPEC: TypeSpec<GenericErrorStatus> = TypeSpecBuilder.newBuilder(
+  "GenericErrorStatus",
+  GenericErrorStatus::Builder,
+  GenericErrorStatus.Builder<*>::build
+).bindSpecField(
+  "disambiguatingDescription",
+  { it.disambiguatingDescription },
+  GenericErrorStatus.Builder<*>::setDisambiguatingDescription,
+  TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+).bindSpecField(
+  "name",
+  { it.name },
+  GenericErrorStatus.Builder<*>::setName,
+  NAME_TYPE_SPEC
+).bindStringField(
+  "identifier",
+  { it.identifier },
+  GenericErrorStatus.Builder<*>::setIdentifier
+).bindIdentifier {
+  it.identifier
+}.build()
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/ObjectCreationLimitReachedStatusSerializer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/ObjectCreationLimitReachedStatusSerializer.kt
new file mode 100644
index 0000000..a7fc6df
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/ObjectCreationLimitReachedStatusSerializer.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.appactions.interaction.capabilities.serializers.types
+
+import androidx.appactions.builtintypes.types.ObjectCreationLimitReachedStatus
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpecBuilder
+import androidx.appactions.interaction.capabilities.serializers.properties.NAME_TYPE_SPEC
+import androidx.appactions.interaction.capabilities.serializers.properties.TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+
+val OBJECT_CREATION_LIMIT_REACHED_STATUS_TYPE_SPEC: TypeSpec<ObjectCreationLimitReachedStatus> =
+TypeSpecBuilder.newBuilder(
+  "ObjectCreationLimitReachedStatus",
+  ObjectCreationLimitReachedStatus::Builder,
+  ObjectCreationLimitReachedStatus.Builder<*>::build
+).bindSpecField(
+  "disambiguatingDescription",
+  { it.disambiguatingDescription },
+  ObjectCreationLimitReachedStatus.Builder<*>::setDisambiguatingDescription,
+  TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+).bindSpecField(
+  "name",
+  { it.name },
+  ObjectCreationLimitReachedStatus.Builder<*>::setName,
+  NAME_TYPE_SPEC
+).bindStringField(
+  "identifier",
+  { it.identifier },
+  ObjectCreationLimitReachedStatus.Builder<*>::setIdentifier
+).bindIdentifier {
+  it.identifier
+}.build()
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/SuccessStatusSerializer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/SuccessStatusSerializer.kt
new file mode 100644
index 0000000..223a883
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/SuccessStatusSerializer.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.appactions.interaction.capabilities.serializers.types
+
+import androidx.appactions.builtintypes.types.SuccessStatus
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpecBuilder
+import androidx.appactions.interaction.capabilities.serializers.properties.NAME_TYPE_SPEC
+import androidx.appactions.interaction.capabilities.serializers.properties.TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+
+val SUCCESS_STATUS_TYPE_SPEC: TypeSpec<SuccessStatus> = TypeSpecBuilder.newBuilder(
+  "SuccessStatus",
+  SuccessStatus::Builder,
+  SuccessStatus.Builder<*>::build
+).bindSpecField(
+  "disambiguatingDescription",
+  { it.disambiguatingDescription },
+  SuccessStatus.Builder<*>::setDisambiguatingDescription,
+  TEXT_ONLY_DISAMBIGUATING_DESCRIPTION_TYPE_SPEC
+).bindSpecField(
+  "name",
+  { it.name },
+  SuccessStatus.Builder<*>::setName,
+  NAME_TYPE_SPEC
+).bindStringField(
+  "identifier",
+  { it.identifier },
+  SuccessStatus.Builder<*>::setIdentifier
+).bindIdentifier {
+  it.identifier
+}.build()
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/TimerSerializer.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/TimerSerializer.kt
index c86674b..8071544 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/TimerSerializer.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/serializers/types/TimerSerializer.kt
@@ -27,10 +27,6 @@
   "Timer",
   Timer::Builder,
   Timer.Builder<*>::build
-).bindStringField(
-  "namespace",
-  { it.namespace },
-  Timer.Builder<*>::setNamespace
 ).bindSpecField(
   "duration",
   { it.duration },
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
index 103466c..8323ad5 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
@@ -24,10 +24,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import java.time.LocalTime
 
-private const val CAPABILITY_NAME = "actions.intent.GET_EXERCISE_OBSERVATION"
-
 /** A capability corresponding to actions.intent.GET_EXERCISE_OBSERVATION */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = GetExerciseObservation.CAPABILITY_NAME)
 class GetExerciseObservation private constructor() {
     internal enum class SlotMetadata(val path: String) {
         START_TIME("exerciseObservation.startTime"),
@@ -98,6 +96,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [GetExerciseObservation] capability.  */
+        const val CAPABILITY_NAME = "actions.intent.GET_EXERCISE_OBSERVATION"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
index 5f93001..6c1975a 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
@@ -24,10 +24,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import java.time.LocalTime
 
-private const val CAPABILITY_NAME = "actions.intent.GET_HEALTH_OBSERVATION"
-
 /** A capability corresponding to actions.intent.GET_HEALTH_OBSERVATION */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = GetHealthObservation.CAPABILITY_NAME)
 class GetHealthObservation private constructor() {
 
     internal enum class SlotMetadata(val path: String) {
@@ -103,6 +101,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [GetHealthObservation] capability */
+        const val CAPABILITY_NAME = "actions.intent.GET_HEALTH_OBSERVATION"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
index 51856a7..c641d2b 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
@@ -24,10 +24,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import androidx.appactions.interaction.capabilities.core.properties.StringValue
 
-private const val CAPABILITY_NAME = "actions.intent.PAUSE_EXERCISE"
-
 /** A capability corresponding to actions.intent.PAUSE_EXERCISE */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = PauseExercise.CAPABILITY_NAME)
 class PauseExercise private constructor() {
     internal enum class SlotMetadata(val path: String) {
         NAME("exercise.name")
@@ -87,6 +85,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [PauseExercise] capability */
+        const val CAPABILITY_NAME = "actions.intent.PAUSE_EXERCISE"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
index 2321ea7..2aa6b15 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
@@ -24,10 +24,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import androidx.appactions.interaction.capabilities.core.properties.StringValue
 
-private const val CAPABILITY_NAME = "actions.intent.RESUME_EXERCISE"
-
 /** A capability corresponding to actions.intent.RESUME_EXERCISE */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = ResumeExercise.CAPABILITY_NAME)
 class ResumeExercise private constructor() {
     internal enum class SlotMetadata(val path: String) {
         NAME("exercise.name")
@@ -87,6 +85,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [ResumeExercise] capability */
+        const val CAPABILITY_NAME = "actions.intent.RESUME_EXERCISE"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
index fe45625..fe43281 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
@@ -25,10 +25,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.StringValue
 import java.time.Duration
 
-private const val CAPABILITY_NAME = "actions.intent.START_EXERCISE"
-
 /** A capability corresponding to actions.intent.START_EXERCISE */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StartExercise.CAPABILITY_NAME)
 class StartExercise private constructor() {
     internal enum class SlotMetadata(val path: String) {
         NAME("exercise.name"),
@@ -103,6 +101,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StartExercise] capability */
+        const val CAPABILITY_NAME = "actions.intent.START_EXERCISE"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
index 31c7fe9..5ebdedd 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
@@ -24,10 +24,8 @@
 import androidx.appactions.interaction.capabilities.core.properties.Property
 import androidx.appactions.interaction.capabilities.core.properties.StringValue
 
-private const val CAPABILITY_NAME = "actions.intent.STOP_EXERCISE"
-
 /** A capability corresponding to actions.intent.STOP_EXERCISE */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StopExercise.CAPABILITY_NAME)
 class StopExercise private constructor() {
     internal enum class SlotMetadata(val path: String) {
         NAME("exercise.name")
@@ -87,6 +85,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StopExercise] capability */
+        const val CAPABILITY_NAME = "actions.intent.STOP_EXERCISE"
         // TODO(b/273602015): Update to use Name property from builtintype library.
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/CreateAlarm.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/CreateAlarm.kt
index b449a2c..1f69695 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/CreateAlarm.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/CreateAlarm.kt
@@ -36,10 +36,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.CREATE_ALARM"
-
 /** A capability corresponding to actions.intent.CREATE_ALARM */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = CreateAlarm.CAPABILITY_NAME)
 class CreateAlarm private constructor() {
     internal enum class SlotMetadata(val path: String) {
         SCHEDULE("alarm.alarmSchedule"),
@@ -214,6 +212,8 @@
     class Confirmation internal constructor()
 
     companion object {
+        /** Canonical name for [CreateAlarm] capability */
+        const val CAPABILITY_NAME = "actions.intent.CREATE_ALARM"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/DismissAlarm.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/DismissAlarm.kt
index 9b5d1da..bae20f5 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/DismissAlarm.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/DismissAlarm.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.DISMISS_ALARM"
-
 /** A capability corresponding to actions.intent.DISMISS_ALARM */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = DismissAlarm.CAPABILITY_NAME)
 class DismissAlarm private constructor() {
     internal enum class SlotMetadata(val path: String) {
         ALARM("alarm")
@@ -143,6 +141,8 @@
     class Confirmation internal constructor()
 
     companion object {
+        /** Canonical name for [DismissAlarm] capability */
+        const val CAPABILITY_NAME = "actions.intent.DISMISS_ALARM"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
index 14f1cf4c..5619640 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.PAUSE_TIMER"
-
 /** A capability corresponding to actions.intent.PAUSE_TIMER */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = PauseTimer.CAPABILITY_NAME)
 class PauseTimer private constructor() {
     internal enum class SlotMetadata(val path: String) {
         TIMER("timer")
@@ -154,6 +152,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [PauseTimer] capability */
+        const val CAPABILITY_NAME = "actions.intent.PAUSE_TIMER"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
index d4e20ed..709b970 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.RESET_TIMER"
-
 /** A capability corresponding to actions.intent.RESET_TIMER */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = ResetTimer.CAPABILITY_NAME)
 class ResetTimer private constructor() {
     internal enum class SlotMetadata(val path: String) {
         TIMER("timer")
@@ -151,6 +149,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [ResetTimer] capability */
+        const val CAPABILITY_NAME = "actions.intent.RESET_TIMER"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
index d069208..63626e5 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.RESUME_TIMER"
-
 /** A capability corresponding to actions.intent.RESUME_TIMER */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = ResumeTimer.CAPABILITY_NAME)
 class ResumeTimer private constructor() {
     internal enum class SlotMetadata(val path: String) {
         TIMER("timer")
@@ -151,6 +149,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [ResumeTimer] capability */
+        const val CAPABILITY_NAME = "actions.intent.RESUME_TIMER"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/SnoozeAlarm.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/SnoozeAlarm.kt
index 2c98081..c2237a5 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/SnoozeAlarm.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/SnoozeAlarm.kt
@@ -32,10 +32,8 @@
 import androidx.appactions.interaction.protobuf.Value
 import java.time.Duration
 
-private const val CAPABILITY_NAME = "actions.intent.SNOOZE_ALARM"
-
 /** A capability corresponding to actions.intent.SNOOZE_ALARM */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = SnoozeAlarm.CAPABILITY_NAME)
 class SnoozeAlarm private constructor() {
     internal enum class SlotMetadata(val path: String) {
         DURATION("snoozeDuration"),
@@ -175,6 +173,8 @@
     class Confirmation internal constructor()
 
     companion object {
+        /** Canonical name for [SnoozeAlarm] capability */
+        const val CAPABILITY_NAME = "actions.intent.SNOOZE_ALARM"
         private val ACTION_SPEC =
                 ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                         .setArguments(Arguments::class.java,
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
index 3f1e930..fd95b6e 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
@@ -30,10 +30,8 @@
 import androidx.appactions.interaction.protobuf.Value
 import java.time.Duration
 
-private const val CAPABILITY_NAME = "actions.intent.START_TIMER"
-
 /** A capability corresponding to actions.intent.START_TIMER */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StartTimer.CAPABILITY_NAME)
 class StartTimer private constructor() {
     internal enum class SlotMetadata(val path: String) {
         IDENTIFIER("timer.identifier"),
@@ -177,6 +175,8 @@
     class Confirmation internal constructor()
 
     companion object {
+        /** Canonical name for [StartTimer] capability */
+        const val CAPABILITY_NAME = "actions.intent.START_TIMER"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
index c41372e..5d123eb 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.STOP_TIMER"
-
 /** A capability corresponding to actions.intent.STOP_TIMER */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StopTimer.CAPABILITY_NAME)
 class StopTimer private constructor() {
     internal enum class SlotMetadata(val path: String) {
         TIMER("timer")
@@ -151,6 +149,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StopTimer] capability */
+        const val CAPABILITY_NAME = "actions.intent.STOP_TIMER"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
index 80e2583..3e86726 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.START_EMERGENCY_SHARING"
-
 /** A capability corresponding to actions.intent.START_EMERGENCY_SHARING */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StartEmergencySharing.CAPABILITY_NAME)
 class StartEmergencySharing private constructor() {
     class CapabilityBuilder :
         Capability.Builder<
@@ -145,6 +143,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StartEmergencySharing] capability */
+        const val CAPABILITY_NAME = "actions.intent.START_EMERGENCY_SHARING"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
index e59813b..4dc3801 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
@@ -38,10 +38,8 @@
 import java.time.Duration
 import java.time.ZonedDateTime
 
-private const val CAPABILITY_NAME = "actions.intent.START_SAFETY_CHECK"
-
 /** A capability corresponding to actions.intent.START_SAFETY_CHECK */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StartSafetyCheck.CAPABILITY_NAME)
 class StartSafetyCheck private constructor() {
     internal enum class SlotMetadata(val path: String) {
         DURATION("safetycheck.duration"),
@@ -225,6 +223,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StartSafetyCheck] capability */
+        const val CAPABILITY_NAME = "actions.intent.START_SAFETY_CHECK"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
index 7d1636a..2a77295 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.STOP_EMERGENCY_SHARING"
-
 /** A capability corresponding to actions.intent.STOP_EMERGENCY_SHARING */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StopEmergencySharing.CAPABILITY_NAME)
 class StopEmergencySharing private constructor() {
     class CapabilityBuilder :
         Capability.Builder<
@@ -145,6 +143,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StopEmergencySharing] capability */
+        const val CAPABILITY_NAME = "actions.intent.STOP_EMERGENCY_SHARING"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
index cc29f26..47cbbaa 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
@@ -31,10 +31,8 @@
 import androidx.appactions.interaction.protobuf.Struct
 import androidx.appactions.interaction.protobuf.Value
 
-private const val CAPABILITY_NAME = "actions.intent.STOP_SAFETY_CHECK"
-
 /** A capability corresponding to actions.intent.STOP_SAFETY_CHECK */
-@CapabilityFactory(name = CAPABILITY_NAME)
+@CapabilityFactory(name = StopSafetyCheck.CAPABILITY_NAME)
 class StopSafetyCheck private constructor() {
     class CapabilityBuilder :
         Capability.Builder<
@@ -145,6 +143,8 @@
     sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
 
     companion object {
+        /** Canonical name for [StopSafetyCheck] capability */
+        const val CAPABILITY_NAME = "actions.intent.STOP_SAFETY_CHECK"
         private val ACTION_SPEC =
             ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
                 .setArguments(Arguments::class.java, Arguments::Builder, Arguments.Builder::build)
diff --git a/appactions/interaction/interaction-service/src/test/resources/robolectric.properties b/appactions/interaction/interaction-service/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/appactions/interaction/interaction-service/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/appcompat/appcompat-resources/api/api_lint.ignore b/appcompat/appcompat-resources/api/api_lint.ignore
index 0cfa261..dd0cf8d 100644
--- a/appcompat/appcompat-resources/api/api_lint.ignore
+++ b/appcompat/appcompat-resources/api/api_lint.ignore
@@ -17,6 +17,8 @@
     Missing nullability on parameter `tint` in method `setTintList`
 MissingNullability: androidx.appcompat.graphics.drawable.DrawableWrapperCompat#DrawableWrapperCompat(android.graphics.drawable.Drawable) parameter #0:
     Missing nullability on parameter `drawable` in method `DrawableWrapperCompat`
+MissingNullability: androidx.appcompat.graphics.drawable.DrawableWrapperCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.appcompat.graphics.drawable.DrawableWrapperCompat#getCurrent():
     Missing nullability on method `getCurrent` return
 MissingNullability: androidx.appcompat.graphics.drawable.DrawableWrapperCompat#getPadding(android.graphics.Rect) parameter #0:
diff --git a/appcompat/appcompat/api/api_lint.ignore b/appcompat/appcompat/api/api_lint.ignore
index ff1d34f..90541cfd 100644
--- a/appcompat/appcompat/api/api_lint.ignore
+++ b/appcompat/appcompat/api/api_lint.ignore
@@ -91,12 +91,8 @@
     Invalid nullability on parameter `filters` in method `setFilters`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.appcompat.widget.AppCompatToggleButton#setFilters(android.text.InputFilter[]) parameter #0:
     Invalid nullability on parameter `filters` in method `setFilters`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.appcompat.widget.LinearLayoutCompat#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.appcompat.widget.ListPopupWindow#getListView():
     Invalid nullability on method `getListView` return. Overrides of unannotated super method cannot be Nullable.
-InvalidNullabilityOverride: androidx.appcompat.widget.SwitchCompat#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.appcompat.widget.SwitchCompat#getCustomSelectionActionModeCallback():
     Invalid nullability on method `getCustomSelectionActionModeCallback` return. Overrides of unannotated super method cannot be Nullable.
 InvalidNullabilityOverride: androidx.appcompat.widget.SwitchCompat#setFilters(android.text.InputFilter[]) parameter #0:
@@ -555,6 +551,8 @@
     Missing nullability on parameter `attrs` in method `createView`
 MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#DrawerArrowDrawable(android.content.Context) parameter #0:
     Missing nullability on parameter `context` in method `DrawerArrowDrawable`
+MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#getPaint():
     Missing nullability on method `getPaint` return
 MissingNullability: androidx.appcompat.graphics.drawable.DrawerArrowDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
@@ -727,6 +725,8 @@
     Missing nullability on parameter `p` in method `generateLayoutParams`
 MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#getDividerDrawable():
     Missing nullability on method `getDividerDrawable` return
+MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
     Missing nullability on parameter `event` in method `onInitializeAccessibilityEvent`
 MissingNullability: androidx.appcompat.widget.LinearLayoutCompat#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo) parameter #0:
@@ -797,6 +797,8 @@
     Missing nullability on parameter `source` in method `onShareTargetSelected`
 MissingNullability: androidx.appcompat.widget.ShareActionProvider.OnShareTargetSelectedListener#onShareTargetSelected(androidx.appcompat.widget.ShareActionProvider, android.content.Intent) parameter #1:
     Missing nullability on parameter `intent` in method `onShareTargetSelected`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
 MissingNullability: androidx.appcompat.widget.SwitchCompat#getTextOff():
     Missing nullability on method `getTextOff` return
 MissingNullability: androidx.appcompat.widget.SwitchCompat#getTextOn():
@@ -831,6 +833,8 @@
     Missing nullability on parameter `thumb` in method `setThumbDrawable`
 MissingNullability: androidx.appcompat.widget.SwitchCompat#setTrackDrawable(android.graphics.drawable.Drawable) parameter #0:
     Missing nullability on parameter `track` in method `setTrackDrawable`
+MissingNullability: androidx.appcompat.widget.SwitchCompat#verifyDrawable(android.graphics.drawable.Drawable) parameter #0:
+    Missing nullability on parameter `who` in method `verifyDrawable`
 MissingNullability: androidx.appcompat.widget.Toolbar#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
     Missing nullability on parameter `p` in method `checkLayoutParams`
 MissingNullability: androidx.appcompat.widget.Toolbar#generateDefaultLayoutParams():
diff --git a/appcompat/appcompat/lint-baseline.xml b/appcompat/appcompat/lint-baseline.xml
index dc8d901..35c6cb0 100644
--- a/appcompat/appcompat/lint-baseline.xml
+++ b/appcompat/appcompat/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="NewApi"
@@ -434,24 +434,6 @@
     </issue>
 
     <issue
-        id="PrereleaseSdkCoreDependency"
-        message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
-        errorLine1="        if (BuildCompat.isAtLeastT()) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/DropDownListView.java"/>
-    </issue>
-
-    <issue
-        id="PrereleaseSdkCoreDependency"
-        message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
-        errorLine1="        if (BuildCompat.isAtLeastT()) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appcompat/widget/DropDownListView.java"/>
-    </issue>
-
-    <issue
         id="KotlinPropertyAccess"
         message="The getter return type (`View`) and setter parameter type (`ScrollingTabContainerView`) getter and setter methods for property `tabContainer` should have exactly the same type to allow be accessed as a property from Kotlin; see https://android.github.io/kotlin-guides/interop.html#property-prefixes"
         errorLine1="    public View getTabContainer() {"
@@ -3448,6 +3430,15 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected synchronized void onDraw(Canvas canvas) {"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/appcompat/widget/AppCompatSeekBar.java"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="            int defStyleAttr, int mode, Resources.Theme popupTheme) {"
         errorLine2="                                        ~~~~~~~~~~~~~~~">
         <location
@@ -7111,6 +7102,15 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected void onDraw(Canvas canvas) {"
+        errorLine2="                          ~~~~~~">
+        <location
+            file="src/main/java/androidx/appcompat/widget/SwitchCompat.java"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set,"
         errorLine2="                  ~~~~~~~~~~~~~~">
         <location
@@ -7966,6 +7966,15 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/appcompat/widget/ViewStubCompat.java"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public View inflate() {"
         errorLine2="           ~~~~">
         <location
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java
index 069c76c..5719451 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/LocalesActivityA.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,4 +20,3 @@
  * An activity for locales with a unique class name.
  */
 public class LocalesActivityA extends LocalesUpdateActivity {}
-
diff --git a/appintegration/OWNERS b/appintegration/OWNERS
new file mode 100644
index 0000000..c29ded6
--- /dev/null
+++ b/appintegration/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1293429
+yim@google.com
diff --git a/appsearch/appsearch-builtin-types/api/current.txt b/appsearch/appsearch-builtin-types/api/current.txt
index a3244de..1e295d6 100644
--- a/appsearch/appsearch-builtin-types/api/current.txt
+++ b/appsearch/appsearch-builtin-types/api/current.txt
@@ -29,8 +29,10 @@
     ctor public Alarm.Builder(androidx.appsearch.builtintypes.Alarm);
     ctor public Alarm.Builder(String, String);
     method public androidx.appsearch.builtintypes.Alarm.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Alarm.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Alarm build();
     method public androidx.appsearch.builtintypes.Alarm.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Alarm.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Alarm.Builder setBlackoutPeriodEndDate(String?);
     method public androidx.appsearch.builtintypes.Alarm.Builder setBlackoutPeriodStartDate(String?);
     method public androidx.appsearch.builtintypes.Alarm.Builder setCreationTimestampMillis(long);
@@ -66,8 +68,10 @@
     ctor public AlarmInstance.Builder(androidx.appsearch.builtintypes.AlarmInstance);
     ctor public AlarmInstance.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.AlarmInstance.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.AlarmInstance build();
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.AlarmInstance.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setDocumentScore(int);
@@ -90,8 +94,10 @@
     ctor public ContactPoint.Builder(androidx.appsearch.builtintypes.ContactPoint);
     ctor public ContactPoint.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.ContactPoint.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.ContactPoint build();
     method public androidx.appsearch.builtintypes.ContactPoint.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.ContactPoint.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setAddresses(java.util.List<java.lang.String!>);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setDescription(String?);
@@ -117,8 +123,10 @@
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeyword(androidx.appsearch.builtintypes.properties.Keyword);
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeyword(String);
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeywords(Iterable<androidx.appsearch.builtintypes.properties.Keyword!>);
+    method public androidx.appsearch.builtintypes.ImageObject.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.ImageObject build();
     method public androidx.appsearch.builtintypes.ImageObject.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.ImageObject.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.ImageObject.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.ImageObject.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.ImageObject.Builder setDocumentScore(int);
@@ -159,8 +167,10 @@
     ctor public Person.Builder(androidx.appsearch.builtintypes.Person);
     ctor public Person.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.Person.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Person.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Person build();
     method public androidx.appsearch.builtintypes.Person.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Person.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Person.Builder setAdditionalNames(java.util.List<androidx.appsearch.builtintypes.Person.AdditionalName!>);
     method public androidx.appsearch.builtintypes.Person.Builder setAffiliations(java.util.List<java.lang.String!>);
     method public androidx.appsearch.builtintypes.Person.Builder setBot(boolean);
@@ -182,6 +192,21 @@
     method public androidx.appsearch.builtintypes.Person.Builder setUrl(String?);
   }
 
+  @androidx.appsearch.annotation.Document(name="builtin:PotentialAction") public class PotentialAction {
+    method public String? getDescription();
+    method public String? getName();
+    method public String? getUri();
+  }
+
+  public static final class PotentialAction.Builder {
+    ctor public PotentialAction.Builder();
+    ctor public PotentialAction.Builder(androidx.appsearch.builtintypes.PotentialAction);
+    method public androidx.appsearch.builtintypes.PotentialAction build();
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setDescription(String?);
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setName(String?);
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setUri(String?);
+  }
+
   @androidx.appsearch.annotation.Document(name="builtin:Stopwatch") public class Stopwatch extends androidx.appsearch.builtintypes.Thing {
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public long calculateBaseTimeMillis(android.content.Context);
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public long calculateCurrentAccumulatedDurationMillis(android.content.Context);
@@ -201,8 +226,10 @@
     ctor public Stopwatch.Builder(androidx.appsearch.builtintypes.Stopwatch);
     ctor public Stopwatch.Builder(String, String);
     method public androidx.appsearch.builtintypes.Stopwatch.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Stopwatch.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Stopwatch build();
     method public androidx.appsearch.builtintypes.Stopwatch.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Stopwatch.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Stopwatch.Builder setAccumulatedDurationMillis(long);
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public androidx.appsearch.builtintypes.Stopwatch.Builder setBaseTimeMillis(android.content.Context, long, long);
     method public androidx.appsearch.builtintypes.Stopwatch.Builder setBaseTimeMillis(long, long, int);
@@ -227,8 +254,10 @@
     ctor public StopwatchLap.Builder(androidx.appsearch.builtintypes.StopwatchLap);
     ctor public StopwatchLap.Builder(String, String);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.StopwatchLap.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.StopwatchLap build();
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.StopwatchLap.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setAccumulatedLapDurationMillis(long);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setDescription(String?);
@@ -251,6 +280,7 @@
     method public String? getImage();
     method public String? getName();
     method public String getNamespace();
+    method public java.util.List<androidx.appsearch.builtintypes.PotentialAction!> getPotentialActions();
     method public String? getUrl();
   }
 
@@ -258,8 +288,10 @@
     ctor public Thing.Builder(androidx.appsearch.builtintypes.Thing);
     ctor public Thing.Builder(String, String);
     method public androidx.appsearch.builtintypes.Thing.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Thing.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Thing build();
     method public androidx.appsearch.builtintypes.Thing.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Thing.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Thing.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.Thing.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.Thing.Builder setDocumentScore(int);
@@ -295,8 +327,10 @@
     ctor public Timer.Builder(androidx.appsearch.builtintypes.Timer);
     ctor public Timer.Builder(String, String);
     method public androidx.appsearch.builtintypes.Timer.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Timer.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Timer build();
     method public androidx.appsearch.builtintypes.Timer.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Timer.Builder clearPotentialActions();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public androidx.appsearch.builtintypes.Timer.Builder setBaseTimeMillis(android.content.Context, long, long);
     method public androidx.appsearch.builtintypes.Timer.Builder setBaseTimeMillis(long, long, int);
     method public androidx.appsearch.builtintypes.Timer.Builder setCreationTimestampMillis(long);
diff --git a/appsearch/appsearch-builtin-types/api/restricted_current.txt b/appsearch/appsearch-builtin-types/api/restricted_current.txt
index a9939c7..e402ed8 100644
--- a/appsearch/appsearch-builtin-types/api/restricted_current.txt
+++ b/appsearch/appsearch-builtin-types/api/restricted_current.txt
@@ -31,8 +31,10 @@
     ctor public Alarm.Builder(androidx.appsearch.builtintypes.Alarm);
     ctor public Alarm.Builder(String, String);
     method public androidx.appsearch.builtintypes.Alarm.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Alarm.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Alarm build();
     method public androidx.appsearch.builtintypes.Alarm.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Alarm.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Alarm.Builder setBlackoutPeriodEndDate(String?);
     method public androidx.appsearch.builtintypes.Alarm.Builder setBlackoutPeriodStartDate(String?);
     method public androidx.appsearch.builtintypes.Alarm.Builder setCreationTimestampMillis(long);
@@ -68,8 +70,10 @@
     ctor public AlarmInstance.Builder(androidx.appsearch.builtintypes.AlarmInstance);
     ctor public AlarmInstance.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.AlarmInstance.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.AlarmInstance build();
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.AlarmInstance.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.AlarmInstance.Builder setDocumentScore(int);
@@ -92,8 +96,10 @@
     ctor public ContactPoint.Builder(androidx.appsearch.builtintypes.ContactPoint);
     ctor public ContactPoint.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.ContactPoint.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.ContactPoint build();
     method public androidx.appsearch.builtintypes.ContactPoint.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.ContactPoint.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setAddresses(java.util.List<java.lang.String!>);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.ContactPoint.Builder setDescription(String?);
@@ -119,8 +125,10 @@
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeyword(androidx.appsearch.builtintypes.properties.Keyword);
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeyword(String);
     method public androidx.appsearch.builtintypes.ImageObject.Builder addKeywords(Iterable<androidx.appsearch.builtintypes.properties.Keyword!>);
+    method public androidx.appsearch.builtintypes.ImageObject.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.ImageObject build();
     method public androidx.appsearch.builtintypes.ImageObject.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.ImageObject.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.ImageObject.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.ImageObject.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.ImageObject.Builder setDocumentScore(int);
@@ -161,8 +169,10 @@
     ctor public Person.Builder(androidx.appsearch.builtintypes.Person);
     ctor public Person.Builder(String, String, String);
     method public androidx.appsearch.builtintypes.Person.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Person.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Person build();
     method public androidx.appsearch.builtintypes.Person.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Person.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Person.Builder setAdditionalNames(java.util.List<androidx.appsearch.builtintypes.Person.AdditionalName!>);
     method public androidx.appsearch.builtintypes.Person.Builder setAffiliations(java.util.List<java.lang.String!>);
     method public androidx.appsearch.builtintypes.Person.Builder setBot(boolean);
@@ -184,6 +194,21 @@
     method public androidx.appsearch.builtintypes.Person.Builder setUrl(String?);
   }
 
+  @androidx.appsearch.annotation.Document(name="builtin:PotentialAction") public class PotentialAction {
+    method public String? getDescription();
+    method public String? getName();
+    method public String? getUri();
+  }
+
+  public static final class PotentialAction.Builder {
+    ctor public PotentialAction.Builder();
+    ctor public PotentialAction.Builder(androidx.appsearch.builtintypes.PotentialAction);
+    method public androidx.appsearch.builtintypes.PotentialAction build();
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setDescription(String?);
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setName(String?);
+    method public androidx.appsearch.builtintypes.PotentialAction.Builder setUri(String?);
+  }
+
   @androidx.appsearch.annotation.Document(name="builtin:Stopwatch") public class Stopwatch extends androidx.appsearch.builtintypes.Thing {
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public long calculateBaseTimeMillis(android.content.Context);
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public long calculateCurrentAccumulatedDurationMillis(android.content.Context);
@@ -203,8 +228,10 @@
     ctor public Stopwatch.Builder(androidx.appsearch.builtintypes.Stopwatch);
     ctor public Stopwatch.Builder(String, String);
     method public androidx.appsearch.builtintypes.Stopwatch.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Stopwatch.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Stopwatch build();
     method public androidx.appsearch.builtintypes.Stopwatch.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Stopwatch.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Stopwatch.Builder setAccumulatedDurationMillis(long);
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public androidx.appsearch.builtintypes.Stopwatch.Builder setBaseTimeMillis(android.content.Context, long, long);
     method public androidx.appsearch.builtintypes.Stopwatch.Builder setBaseTimeMillis(long, long, int);
@@ -229,8 +256,10 @@
     ctor public StopwatchLap.Builder(androidx.appsearch.builtintypes.StopwatchLap);
     ctor public StopwatchLap.Builder(String, String);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.StopwatchLap.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.StopwatchLap build();
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.StopwatchLap.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setAccumulatedLapDurationMillis(long);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.StopwatchLap.Builder setDescription(String?);
@@ -253,6 +282,7 @@
     method public String? getImage();
     method public String? getName();
     method public String getNamespace();
+    method public java.util.List<androidx.appsearch.builtintypes.PotentialAction!> getPotentialActions();
     method public String? getUrl();
   }
 
@@ -260,8 +290,10 @@
     ctor public Thing.Builder(androidx.appsearch.builtintypes.Thing);
     ctor public Thing.Builder(String, String);
     method public androidx.appsearch.builtintypes.Thing.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Thing.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Thing build();
     method public androidx.appsearch.builtintypes.Thing.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Thing.Builder clearPotentialActions();
     method public androidx.appsearch.builtintypes.Thing.Builder setCreationTimestampMillis(long);
     method public androidx.appsearch.builtintypes.Thing.Builder setDescription(String?);
     method public androidx.appsearch.builtintypes.Thing.Builder setDocumentScore(int);
@@ -297,8 +329,10 @@
     ctor public Timer.Builder(androidx.appsearch.builtintypes.Timer);
     ctor public Timer.Builder(String, String);
     method public androidx.appsearch.builtintypes.Timer.Builder addAlternateName(String);
+    method public androidx.appsearch.builtintypes.Timer.Builder addPotentialAction(androidx.appsearch.builtintypes.PotentialAction);
     method public androidx.appsearch.builtintypes.Timer build();
     method public androidx.appsearch.builtintypes.Timer.Builder clearAlternateNames();
+    method public androidx.appsearch.builtintypes.Timer.Builder clearPotentialActions();
     method @RequiresApi(api=android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) public androidx.appsearch.builtintypes.Timer.Builder setBaseTimeMillis(android.content.Context, long, long);
     method public androidx.appsearch.builtintypes.Timer.Builder setBaseTimeMillis(long, long, int);
     method public androidx.appsearch.builtintypes.Timer.Builder setCreationTimestampMillis(long);
diff --git a/appsearch/appsearch-builtin-types/lint-baseline.xml b/appsearch/appsearch-builtin-types/lint-baseline.xml
deleted file mode 100644
index c0364fb..0000000
--- a/appsearch/appsearch-builtin-types/lint-baseline.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Status {}"
-        errorLine2="                      ~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/builtintypes/AlarmInstance.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class BootCountUtil {"
-        errorLine2="             ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/utils/BootCountUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class DateTimeFormatValidator {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/utils/DateTimeFormatValidator.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface NameType {"
-        errorLine2="                          ~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/builtintypes/Person.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public static final String DEFAULT_DATABASE = &quot;__shortcut_adapter_db__&quot;;"
-        errorLine2="                               ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/ShortcutAdapter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public static GenericDocument extractDocument(@NonNull final ShortcutInfoCompat shortcut) {"
-        errorLine2="                                  ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/ShortcutAdapter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Status {}"
-        errorLine2="                      ~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/builtintypes/Stopwatch.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Status {}"
-        errorLine2="                      ~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/builtintypes/Timer.java"/>
-    </issue>
-
-</issues>
diff --git a/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/PotentialActionTest.java b/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/PotentialActionTest.java
new file mode 100644
index 0000000..a0117d7
--- /dev/null
+++ b/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/PotentialActionTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.appsearch.builtintypes;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.appsearch.app.GenericDocument;
+
+import org.junit.Test;
+
+public class PotentialActionTest {
+    @Test
+    public void testBuilder() {
+        PotentialAction potentialAction = new PotentialAction.Builder()
+                .setName("actions.intent.CREATE_CALL")
+                .setDescription("Call John")
+                .build();
+
+        assertThat(potentialAction.getName()).isEqualTo("actions.intent.CREATE_CALL");
+        assertThat(potentialAction.getDescription()).isEqualTo("Call John");
+    }
+
+    @Test
+    public void testBuilderCopy_returnsActionWithAllFieldsCopied() {
+        PotentialAction potentialAction1 = new PotentialAction.Builder()
+                .setName("actions.intent.CREATE_CALL")
+                .setDescription("Call John")
+                .build();
+
+        PotentialAction potentialAction2 = new PotentialAction.Builder(potentialAction1).build();
+        assertThat(potentialAction1.getName()).isEqualTo(potentialAction2.getName());
+        assertThat(potentialAction1.getDescription()).isEqualTo(potentialAction2.getDescription());
+        assertThat(potentialAction1.getUri()).isEqualTo(potentialAction2.getUri());
+    }
+
+    @Test
+    public void testActionToGenericDocument() throws Exception {
+        PotentialAction potentialAction = new PotentialAction.Builder()
+                .setName("actions.intent.CREATE_CALL")
+                .setDescription("Call John")
+                .setUri("tel:555-123-4567")
+                .build();
+
+        GenericDocument genericDocument = GenericDocument.fromDocumentClass(potentialAction);
+        assertThat(genericDocument.getSchemaType()).isEqualTo("builtin:PotentialAction");
+        assertThat(genericDocument.getPropertyString("name"))
+                .isEqualTo("actions.intent.CREATE_CALL");
+        assertThat(genericDocument.getPropertyString("description"))
+                .isEqualTo("Call John");
+        assertThat(genericDocument.getPropertyString("uri"))
+                .isEqualTo("tel:555-123-4567");
+    }
+}
diff --git a/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/ThingTest.java b/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/ThingTest.java
index 9093ced..92198a9 100644
--- a/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/ThingTest.java
+++ b/appsearch/appsearch-builtin-types/src/androidTest/java/androidx/appsearch/builtintypes/ThingTest.java
@@ -23,9 +23,9 @@
 import org.junit.Test;
 
 import java.util.Arrays;
+import java.util.List;
 
 public class ThingTest {
-
     @Test
     public void testBuilder() {
         long now = System.currentTimeMillis();
@@ -39,6 +39,16 @@
                 .setDescription("this is my first schema.org object")
                 .setImage("content://images/thing1")
                 .setUrl("content://things/1")
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setName("Start Action")
+                        .setDescription("Starts the thing")
+                        .setUri("package://start")
+                        .build())
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setName("Stop Action")
+                        .setDescription("Stops the thing")
+                        .setUri("package://stop")
+                        .build())
                 .build();
 
         assertThat(thing.getNamespace()).isEqualTo("namespace");
@@ -53,6 +63,17 @@
         assertThat(thing.getDescription()).isEqualTo("this is my first schema.org object");
         assertThat(thing.getImage()).isEqualTo("content://images/thing1");
         assertThat(thing.getUrl()).isEqualTo("content://things/1");
+        assertThat(thing.getPotentialActions()).hasSize(2);
+
+        PotentialAction startAction = thing.getPotentialActions().get(0);
+        assertThat(startAction.getName()).isEqualTo("Start Action");
+        assertThat(startAction.getDescription()).isEqualTo("Starts the thing");
+        assertThat(startAction.getUri()).isEqualTo("package://start");
+
+        PotentialAction stopAction = thing.getPotentialActions().get(1);
+        assertThat(stopAction.getName()).isEqualTo("Stop Action");
+        assertThat(stopAction.getDescription()).isEqualTo("Stops the thing");
+        assertThat(stopAction.getUri()).isEqualTo("package://stop");
     }
 
     @Test
@@ -68,6 +89,11 @@
                 .setDescription("this is my first schema.org object")
                 .setImage("content://images/thing1")
                 .setUrl("content://things/1")
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setName("Stop Action")
+                        .setDescription("Stops the thing")
+                        .setUri("package://stop")
+                        .build())
                 .build();
         Thing thing2 = new Thing.Builder(thing1).build();
 
@@ -83,6 +109,12 @@
         assertThat(thing2.getDescription()).isEqualTo("this is my first schema.org object");
         assertThat(thing2.getImage()).isEqualTo("content://images/thing1");
         assertThat(thing2.getUrl()).isEqualTo("content://things/1");
+        assertThat(thing2.getPotentialActions()).isNotNull();
+        assertThat(thing2.getPotentialActions()).hasSize(1);
+        assertThat(thing2.getPotentialActions().get(0).getName()).isEqualTo("Stop Action");
+        assertThat(thing2.getPotentialActions().get(0).getDescription())
+                .isEqualTo("Stops the thing");
+        assertThat(thing2.getPotentialActions().get(0).getUri()).isEqualTo("package://stop");
     }
 
     @Test
@@ -98,11 +130,25 @@
                 .setDescription("this is my first schema.org object")
                 .setImage("content://images/thing1")
                 .setUrl("content://things/1")
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setDescription("View this thing")
+                        .setUri("package://view")
+                        .build())
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setDescription("Edit this thing")
+                        .setUri("package://edit")
+                        .build())
                 .build();
         Thing thing2 = new Thing.Builder(thing1)
                 .clearAlternateNames()
                 .setImage("content://images/thing2")
                 .setUrl("content://things/2")
+                .clearPotentialActions()
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setName("DeleteAction")
+                        .setDescription("Delete this thing")
+                        .setUri("package://delete")
+                        .build())
                 .build();
 
         assertThat(thing2.getNamespace()).isEqualTo("namespace");
@@ -115,11 +161,99 @@
         assertThat(thing2.getDescription()).isEqualTo("this is my first schema.org object");
         assertThat(thing2.getImage()).isEqualTo("content://images/thing2");
         assertThat(thing2.getUrl()).isEqualTo("content://things/2");
+
+        List<PotentialAction> potentialActions = thing2.getPotentialActions();
+        assertThat(potentialActions).hasSize(1);
+        assertThat(potentialActions.get(0).getName()).isEqualTo("DeleteAction");
+        assertThat(potentialActions.get(0).getDescription()).isEqualTo("Delete this thing");
+        assertThat(potentialActions.get(0).getUri()).isEqualTo("package://delete");
     }
 
     @Test
+    public void testBuilderCopy_builderReuse() {
+        long now = System.currentTimeMillis();
+        Thing.Builder builder = new Thing.Builder("namespace", "thing1")
+                .setDocumentScore(1)
+                .setCreationTimestampMillis(now)
+                .setDocumentTtlMillis(30000)
+                .setName("my first thing")
+                .addAlternateName("my first object")
+                .addAlternateName("माझी पहिली गोष्ट")
+                .setDescription("this is my first schema.org object")
+                .setImage("content://images/thing1")
+                .setUrl("content://things/1")
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setDescription("View this thing")
+                        .setUri("package://view")
+                        .build())
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setDescription("Edit this thing")
+                        .setUri("package://edit")
+                        .build());
+
+        Thing thing1 = builder.build();
+
+        builder.clearAlternateNames()
+                .setImage("content://images/thing2")
+                .setUrl("content://things/2")
+                .clearPotentialActions()
+                .addPotentialAction(new PotentialAction.Builder()
+                        .setName("DeleteAction")
+                        .setDescription("Delete this thing")
+                        .setUri("package://delete")
+                        .build());
+
+        Thing thing2 = builder.build();
+
+        // Check that thing1 wasn't altered
+        assertThat(thing1.getNamespace()).isEqualTo("namespace");
+        assertThat(thing1.getId()).isEqualTo("thing1");
+        assertThat(thing1.getDocumentScore()).isEqualTo(1);
+        assertThat(thing1.getCreationTimestampMillis()).isEqualTo(now);
+        assertThat(thing1.getDocumentTtlMillis()).isEqualTo(30000);
+        assertThat(thing1.getName()).isEqualTo("my first thing");
+        assertThat(thing1.getAlternateNames())
+                .containsExactly("my first object", "माझी पहिली गोष्ट");
+        assertThat(thing1.getDescription()).isEqualTo("this is my first schema.org object");
+        assertThat(thing1.getImage()).isEqualTo("content://images/thing1");
+        assertThat(thing1.getUrl()).isEqualTo("content://things/1");
+
+        List<PotentialAction> actions1 = thing1.getPotentialActions();
+        assertThat(actions1).hasSize(2);
+        assertThat(actions1.get(0).getDescription()).isEqualTo("View this thing");
+        assertThat(actions1.get(0).getUri()).isEqualTo("package://view");
+        assertThat(actions1.get(1).getDescription()).isEqualTo("Edit this thing");
+        assertThat(actions1.get(1).getUri()).isEqualTo("package://edit");
+
+        // Check that thing2 has the new values
+        assertThat(thing2.getNamespace()).isEqualTo("namespace");
+        assertThat(thing2.getId()).isEqualTo("thing1");
+        assertThat(thing2.getDocumentScore()).isEqualTo(1);
+        assertThat(thing2.getCreationTimestampMillis()).isEqualTo(now);
+        assertThat(thing2.getDocumentTtlMillis()).isEqualTo(30000);
+        assertThat(thing2.getName()).isEqualTo("my first thing");
+        assertThat(thing2.getAlternateNames()).isEmpty();
+        assertThat(thing2.getDescription()).isEqualTo("this is my first schema.org object");
+        assertThat(thing2.getImage()).isEqualTo("content://images/thing2");
+        assertThat(thing2.getUrl()).isEqualTo("content://things/2");
+
+        List<PotentialAction> actions2 = thing2.getPotentialActions();
+        assertThat(actions2).hasSize(1);
+        assertThat(actions2.get(0).getName()).isEqualTo("DeleteAction");
+        assertThat(actions2.get(0).getDescription()).isEqualTo("Delete this thing");
+        assertThat(actions2.get(0).getUri()).isEqualTo("package://delete");
+    }
+
+
+    @Test
     public void testToGenericDocument() throws Exception {
         long now = System.currentTimeMillis();
+        PotentialAction potentialAction = new PotentialAction.Builder()
+                .setDescription("Make a phone call")
+                .setName("actions.intent.CALL")
+                .setUri("package://call")
+                .build();
+
         Thing thing = new Thing.Builder("namespace", "thing1")
                 .setDocumentScore(1)
                 .setCreationTimestampMillis(now)
@@ -130,6 +264,7 @@
                 .setDescription("this is my first schema.org object")
                 .setImage("content://images/thing1")
                 .setUrl("content://things/1")
+                .addPotentialAction(potentialAction)
                 .build();
 
         GenericDocument document = GenericDocument.fromDocumentClass(thing);
@@ -147,5 +282,12 @@
                 .isEqualTo("this is my first schema.org object");
         assertThat(document.getPropertyString("image")).isEqualTo("content://images/thing1");
         assertThat(document.getPropertyString("url")).isEqualTo("content://things/1");
+
+        assertThat(document.getPropertyString("potentialActions[0].name"))
+                .isEqualTo("actions.intent.CALL");
+        assertThat(document.getPropertyString("potentialActions[0].description"))
+                .isEqualTo("Make a phone call");
+        assertThat(document.getPropertyString("potentialActions[0].uri"))
+                .isEqualTo("package://call");
     }
 }
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/app/ShortcutAdapter.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/app/ShortcutAdapter.java
index 9798755..9d17a58 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/app/ShortcutAdapter.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/app/ShortcutAdapter.java
@@ -41,7 +41,7 @@
         // Hide constructor as utility classes are not meant to be instantiated.
     }
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     public static final String DEFAULT_DATABASE = "__shortcut_adapter_db__";
 
@@ -127,7 +127,7 @@
     /**
      * Extracts {@link GenericDocument} from given {@link ShortcutInfoCompat} if applicable.
      * Returns null if document cannot be found in the given shortcut.
-     * @hide
+     * @exportToFramework:hide
      */
     @Nullable
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Alarm.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Alarm.java
index da4a47a..4c4a2bb 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Alarm.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Alarm.java
@@ -65,12 +65,13 @@
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
             @Nullable String image, @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
             boolean enabled, @Nullable int[] daysOfWeek, int hour, int minute,
             @Nullable String blackoutPeriodStartDate, @Nullable String blackoutPeriodEndDate,
             @Nullable String ringtone, boolean shouldVibrate,
             @Nullable AlarmInstance previousInstance, @Nullable AlarmInstance nextInstance) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mEnabled = enabled;
         mDaysOfWeek = daysOfWeek;
         mHour = hour;
@@ -396,6 +397,7 @@
         public Alarm build() {
             return new Alarm(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions,
                     mEnabled, mDaysOfWeek, mHour, mMinute, mBlackoutPeriodStartDate,
                     mBlackoutPeriodEndDate, mRingtone, mShouldVibrate, mPreviousInstance,
                     mNextInstance);
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/AlarmInstance.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/AlarmInstance.java
index 59a142a..8559735 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/AlarmInstance.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/AlarmInstance.java
@@ -42,7 +42,7 @@
  */
 @Document(name = "builtin:AlarmInstance")
 public class AlarmInstance extends Thing {
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({STATUS_UNKNOWN, STATUS_SCHEDULED, STATUS_FIRING, STATUS_DISMISSED, STATUS_SNOOZED,
             STATUS_MISSED})
@@ -74,10 +74,11 @@
     AlarmInstance(@NonNull String namespace, @NonNull String id, int documentScore,
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
-            @Nullable String image, @Nullable String url, @NonNull String scheduledTime,
+            @Nullable String image, @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions, @NonNull String scheduledTime,
             int status, long snoozeDurationMillis) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mScheduledTime = Preconditions.checkNotNull(scheduledTime);
         mStatus = status;
         mSnoozeDurationMillis = snoozeDurationMillis;
@@ -197,6 +198,7 @@
         public AlarmInstance build() {
             return new AlarmInstance(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions,
                     mScheduledTime, mStatus, mSnoozeDurationMillis);
         }
     }
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ContactPoint.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ContactPoint.java
index 84333a6..739e5a6 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ContactPoint.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ContactPoint.java
@@ -57,12 +57,13 @@
             @Nullable String description,
             @Nullable String image,
             @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
             @NonNull String label,
             @NonNull List<String> addresses,
             @NonNull List<String> emails,
             @NonNull List<String> telephones) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mLabel = label;
         mAddresses = Collections.unmodifiableList(addresses);
         mEmails = Collections.unmodifiableList(emails);
@@ -181,6 +182,7 @@
                     /*description=*/ mDescription,
                     /*image=*/ mImage,
                     /*url=*/ mUrl,
+                    /*potentialActions=*/ mPotentialActions,
                     /*label=*/ mLabel,
                     /*addresses=*/ new ArrayList<>(mAddresses),
                     /*emails=*/ new ArrayList<>(mEmails),
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ImageObject.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ImageObject.java
index 2586d9c..b756437 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ImageObject.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/ImageObject.java
@@ -51,10 +51,12 @@
     ImageObject(@NonNull String namespace, @NonNull String id, int documentScore,
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
-            @Nullable String image, @Nullable String url, @NonNull List<Keyword> keywords,
+            @Nullable String image, @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
+            @NonNull List<Keyword> keywords,
             @Nullable String sha256, @Nullable String thumbnailSha256) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mKeywords = checkNotNull(keywords);
         mSha256 = sha256;
         mThumbnailSha256 = thumbnailSha256;
@@ -157,7 +159,7 @@
         public ImageObject build() {
             return new ImageObject(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
-                    new ArrayList<>(mKeywords), mSha256, mThumbnailSha256);
+                    mPotentialActions, new ArrayList<>(mKeywords), mSha256, mThumbnailSha256);
         }
 
         /**
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Person.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Person.java
index 700b734..36299d4 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Person.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Person.java
@@ -45,7 +45,7 @@
 public class Person extends Thing {
     /** Holds type information for additional names for Person. */
     public static class AdditionalName {
-        /** @hide */
+        /** @exportToFramework:hide */
         @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef({
                 TYPE_UNKNOWN,
@@ -158,6 +158,7 @@
             @Nullable String description,
             @Nullable String image,
             @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
             @Nullable String givenName,
             @Nullable String middleName,
             @Nullable String familyName,
@@ -172,7 +173,7 @@
             @NonNull List<String> relations,
             @NonNull List<ContactPoint> contactPoints) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mGivenName = givenName;
         mMiddleName = middleName;
         mFamilyName = familyName;
@@ -524,6 +525,7 @@
                     /*description=*/ mDescription,
                     /*image=*/ mImage,
                     /*url=*/ mUrl,
+                    /*potentialActions=*/ mPotentialActions,
                     /*givenName=*/ mGivenName,
                     /*middleName=*/ mMiddleName,
                     /*familyName=*/ mFamilyName,
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/PotentialAction.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/PotentialAction.java
new file mode 100644
index 0000000..7d4e7e4
--- /dev/null
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/PotentialAction.java
@@ -0,0 +1,169 @@
+/*
+ * 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.appsearch.builtintypes;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appsearch.annotation.Document;
+import androidx.core.util.Preconditions;
+
+/**
+ * An AppSearch document representing an action. This action schema type is used for the nested
+ * potentialActions field in entity schema types such as builtin:Thing or builtin:Timer.
+ *
+ * <ul>
+ * <li><b>name</b> - This is a unique identifier for the action, such as
+ * "actions.intent.CREATE_CALL". See <a
+ * href=developer.android.com/reference/app-actions/built-in-intents/communications/create-call>
+ * developer.android.com/reference/app-actions/built-in-intents/communications/create-call</a>
+ * for an sample Action type.
+ * </li>
+ * <li><b>description</b> - A brief description of what the action does, such as "Create call" or
+ * "Create Message".</li>
+ * <li><b>uri</b> - A deeplink URI linking to an action. Invoking the action can be done by
+ * creating an {@link android.content.Intent} object by calling
+ * {@link android.content.Intent#parseUri} with the deeplink URI. Creating a deeplink URI, and
+ * adding intent extras, can be done by building an intent and calling
+ * {@link android.content.Intent#toUri}.
+ * </li>
+ * </ul>
+ */
+// TODO(b/274671459): Add additional information, if needed, to dispatch actions.
+@Document(name = "builtin:PotentialAction")
+public class PotentialAction {
+    @Document.Namespace
+    final String mNamespace;
+
+    @Document.Id
+    final String mId;
+
+    @Document.StringProperty
+    private final String mName;
+
+    @Document.StringProperty
+    private final String mDescription;
+
+    @Document.StringProperty
+    private final String mUri;
+
+    PotentialAction(@NonNull String namespace, @NonNull String id, @Nullable String name,
+            @Nullable String description, @Nullable String uri) {
+        mNamespace = Preconditions.checkNotNull(namespace);
+        mId = Preconditions.checkNotNull(id);
+        mName = name;
+        mDescription = description;
+        mUri = uri;
+    }
+
+    /** Returns a string describing the action. */
+    @Nullable
+    public String getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Returns the BII action ID, which comes from Action IDs of Built-in intents listed at <a
+     * href=developer.android.com/reference/app-actions/built-in-intents/bii-index>
+     * developer.android.com/reference/app-actions/built-in-intents/bii-index</a>. For example,
+     * the "Start Exercise" BII has an action id of "actions.intent.START_EXERCISE".
+     */
+    @Nullable
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Returns the deeplink URI.
+     *
+     * <p> A deeplink URI is a URI that lets a user access a specific content or feature within an
+     * app directly. Users can create one by adding parameters to the app's base URI. To use a
+     * deeplink URI in an Android application, users can create an {@link android.content.Intent}
+     * object by calling {@link android.content.Intent#parseUri} with the deeplink URI. Creating a
+     * deeplink URI, and adding intent extras, can be done by building an intent and calling
+     * {@link android.content.Intent#toUri}.
+     */
+    @Nullable
+    public String getUri() {
+        return mUri;
+    }
+
+    /** Builder for {@link PotentialAction}. */
+    public static final class Builder {
+        @Nullable private String mName;
+        @Nullable private String mDescription;
+        @Nullable private String mUri;
+
+        /**
+         * Constructor for {@link PotentialAction.Builder}.
+         *
+         * <p> As PotentialAction is used as a DocumentProperty of Thing, it does not need an id or
+         * namespace.
+         */
+        public Builder() { }
+
+        /**
+         * Constructor with all the existing values.
+         *
+         * <p> As PotentialAction is used as a DocumentProperty of Thing, it does not need an id or
+         * namespace.
+         */
+        public Builder(@NonNull PotentialAction potentialAction) {
+            mName = potentialAction.getName();
+            mDescription = potentialAction.getDescription();
+            mUri = potentialAction.getUri();
+        }
+
+        /** Sets the name of the action. */
+        @NonNull
+        public Builder setName(@Nullable String name) {
+            mName = name;
+            return this;
+        }
+
+        /** Sets the description of the action, such as "Call". */
+        @NonNull
+        public Builder setDescription(@Nullable String description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the deeplink URI of the Action.
+         *
+         * <p> A deeplink URI is a URI that lets a user access a specific content or feature within
+         * an app directly. Users can create one by adding parameters to the app's base URI. To use
+         * a deeplink URI in an Android application, users can create an
+         * {@link android.content.Intent} object by calling
+         * {@link android.content.Intent#parseUri} with the deeplink URI. Creating a deeplink URI,
+         * and adding intent extras, can be done by building an intent and calling
+         * {@link android.content.Intent#toUri}.
+         */
+        @NonNull
+        public Builder setUri(@Nullable String uri) {
+            mUri = uri;
+            return this;
+        }
+
+        /** Builds the {@link PotentialAction}. */
+        @NonNull
+        public PotentialAction build() {
+            // As PotentialAction is used as a DocumentProperty of Thing, it does not need an id or
+            // namespace.
+            return new PotentialAction(/*namespace=*/"", /*id=*/"", mName, mDescription, mUri);
+        }
+    }
+}
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Stopwatch.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Stopwatch.java
index a3fc290..7d0cc6f 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Stopwatch.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Stopwatch.java
@@ -41,7 +41,7 @@
  */
 @Document(name = "builtin:Stopwatch")
 public class Stopwatch extends Thing {
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({STATUS_UNKNOWN, STATUS_RESET, STATUS_RUNNING, STATUS_PAUSED})
     @Retention(RetentionPolicy.SOURCE)
@@ -77,11 +77,12 @@
     Stopwatch(@NonNull String namespace, @NonNull String id, int documentScore,
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
-            @Nullable String image, @Nullable String url, long baseTimeMillis,
-            long baseTimeMillisInElapsedRealtime, int bootCount, int status,
+            @Nullable String image, @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
+            long baseTimeMillis, long baseTimeMillisInElapsedRealtime, int bootCount, int status,
             long accumulatedDurationMillis, @NonNull List<StopwatchLap> laps) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mBaseTimeMillis = baseTimeMillis;
         mBaseTimeMillisInElapsedRealtime = baseTimeMillisInElapsedRealtime;
         mBootCount = bootCount;
@@ -318,6 +319,7 @@
         public Stopwatch build() {
             return new Stopwatch(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions,
                     mBaseTimeMillis, mBaseTimeMillisInElapsedRealtime, mBootCount, mStatus,
                     mAccumulatedDurationMillis, mLaps);
         }
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/StopwatchLap.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/StopwatchLap.java
index 1923629..f5b979a 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/StopwatchLap.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/StopwatchLap.java
@@ -45,10 +45,11 @@
     StopwatchLap(@NonNull String namespace, @NonNull String id, int documentScore,
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
-            @Nullable String image, @Nullable String url, int lapNumber,
-            long lapDurationMillis, long accumulatedLapDurationMillis) {
+            @Nullable String image, @Nullable String url,
+            @NonNull List<PotentialAction> potentialActions,
+            int lapNumber, long lapDurationMillis, long accumulatedLapDurationMillis) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mLapNumber = lapNumber;
         mLapDurationMillis = lapDurationMillis;
         mAccumulatedLapDurationMillis = accumulatedLapDurationMillis;
@@ -146,6 +147,7 @@
         public StopwatchLap build() {
             return new StopwatchLap(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions,
                     mLapNumber, mLapDurationMillis, mAccumulatedLapDurationMillis);
         }
     }
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Thing.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Thing.java
index 58629bc..954e949 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Thing.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Thing.java
@@ -65,10 +65,14 @@
     @Document.StringProperty
     private final String mUrl;
 
+    @Document.DocumentProperty
+    private final List<PotentialAction> mPotentialActions;
+
     Thing(@NonNull String namespace, @NonNull String id, int documentScore,
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
-            @Nullable String image, @Nullable String url) {
+            @Nullable String image, @Nullable String url,
+            @Nullable List<PotentialAction> potentialActions) {
         mNamespace = Preconditions.checkNotNull(namespace);
         mId = Preconditions.checkNotNull(id);
         mDocumentScore = documentScore;
@@ -85,6 +89,13 @@
         mDescription = description;
         mImage = image;
         mUrl = url;
+        // AppSearch may pass null if old schema lacks the potentialActions field during
+        // GenericDocument to Java class conversion.
+        if (potentialActions == null) {
+            mPotentialActions = Collections.emptyList();
+        } else {
+            mPotentialActions = Collections.unmodifiableList(potentialActions);
+        }
     }
 
     /** Returns the namespace (or logical grouping) for this item. */
@@ -154,6 +165,12 @@
         return mUrl;
     }
 
+    /** Returns the actions that can be taken on this object. */
+    @NonNull
+    public List<PotentialAction> getPotentialActions() {
+        return mPotentialActions;
+    }
+
     /** Builder for {@link Thing}. */
     public static final class Builder extends BuilderImpl<Builder> {
         /** Constructs {@link Thing.Builder} with given {@code namespace} and {@code id} */
@@ -181,6 +198,8 @@
         protected String mDescription;
         protected String mImage;
         protected String mUrl;
+        protected List<PotentialAction> mPotentialActions = new ArrayList<>();
+        private boolean mBuilt = false;
 
         BuilderImpl(@NonNull String namespace, @NonNull String id) {
             mNamespace = Preconditions.checkNotNull(namespace);
@@ -201,6 +220,7 @@
             mDescription = thing.getDescription();
             mImage = thing.getImage();
             mUrl = thing.getUrl();
+            mPotentialActions = new ArrayList<>(thing.getPotentialActions());
         }
 
         /**
@@ -214,6 +234,7 @@
         @NonNull
         @SuppressWarnings("unchecked")
         public T setDocumentScore(int documentScore) {
+            resetIfBuilt();
             mDocumentScore = documentScore;
             return (T) this;
         }
@@ -233,6 +254,7 @@
         @NonNull
         @SuppressWarnings("unchecked")
         public T setCreationTimestampMillis(long creationTimestampMillis) {
+            resetIfBuilt();
             mCreationTimestampMillis = creationTimestampMillis;
             return (T) this;
         }
@@ -251,6 +273,7 @@
         @NonNull
         @SuppressWarnings("unchecked")
         public T setDocumentTtlMillis(long documentTtlMillis) {
+            resetIfBuilt();
             mDocumentTtlMillis = documentTtlMillis;
             return (T) this;
         }
@@ -258,6 +281,7 @@
         /** Sets the name of the item. */
         @NonNull
         public T setName(@Nullable String name) {
+            resetIfBuilt();
             mName = name;
             return (T) this;
         }
@@ -265,6 +289,7 @@
         /** Adds an alias for the item. */
         @NonNull
         public T addAlternateName(@NonNull String alternateName) {
+            resetIfBuilt();
             Preconditions.checkNotNull(alternateName);
             mAlternateNames.add(alternateName);
             return (T) this;
@@ -273,6 +298,7 @@
         /** Clears the aliases, if any, for the item. */
         @NonNull
         public T clearAlternateNames() {
+            resetIfBuilt();
             mAlternateNames.clear();
             return (T) this;
         }
@@ -280,6 +306,7 @@
         /** Sets the description for the item. */
         @NonNull
         public T setDescription(@Nullable String description) {
+            resetIfBuilt();
             mDescription = description;
             return (T) this;
         }
@@ -287,6 +314,7 @@
         /** Sets the URL for an image of the item. */
         @NonNull
         public T setImage(@Nullable String image) {
+            resetIfBuilt();
             mImage = image;
             return (T) this;
         }
@@ -307,15 +335,46 @@
          */
         @NonNull
         public T setUrl(@Nullable String url) {
+            resetIfBuilt();
             mUrl = url;
             return (T) this;
         }
+        /**
+         * Add a new action to the list of potential actions for this document.
+         */
+        @NonNull
+        public T addPotentialAction(@NonNull PotentialAction newPotentialAction) {
+            resetIfBuilt();
+            Preconditions.checkNotNull(newPotentialAction);
+            mPotentialActions.add(newPotentialAction);
+            return (T) this;
+        }
+
+        /**
+         * Clear all the potential actions for this document.
+         */
+        @NonNull
+        public T clearPotentialActions() {
+            resetIfBuilt();
+            mPotentialActions.clear();
+            return (T) this;
+        }
+
+        private void resetIfBuilt() {
+            if (mBuilt) {
+                mAlternateNames = new ArrayList<>(mAlternateNames);
+                mPotentialActions = new ArrayList<>(mPotentialActions);
+                mBuilt = false;
+            }
+        }
 
         /** Builds a {@link Thing} object. */
         @NonNull
         public Thing build() {
+            mBuilt = true;
             return new Thing(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
-                    mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl);
+                    mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions);
         }
     }
 }
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Timer.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Timer.java
index 11d8961..60c9030 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Timer.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/builtintypes/Timer.java
@@ -37,7 +37,7 @@
  */
 @Document(name = "builtin:Timer")
 public class Timer extends Thing {
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({STATUS_UNKNOWN, STATUS_STARTED, STATUS_PAUSED, STATUS_EXPIRED, STATUS_MISSED,
             STATUS_RESET})
@@ -91,12 +91,13 @@
             long creationTimestampMillis, long documentTtlMillis, @Nullable String name,
             @Nullable List<String> alternateNames, @Nullable String description,
             @Nullable String image, @Nullable String url,
+            @Nullable List<PotentialAction> potentialActions,
             long durationMillis, long originalDurationMillis, long startTimeMillis,
             long baseTimeMillis, long baseTimeMillisInElapsedRealtime, int bootCount,
             long remainingDurationMillis, @Nullable String ringtone, int status,
             boolean shouldVibrate) {
         super(namespace, id, documentScore, creationTimestampMillis, documentTtlMillis, name,
-                alternateNames, description, image, url);
+                alternateNames, description, image, url, potentialActions);
         mDurationMillis = durationMillis;
         mOriginalDurationMillis = originalDurationMillis;
         mStartTimeMillis = startTimeMillis;
@@ -477,6 +478,7 @@
         public Timer build() {
             return new Timer(mNamespace, mId, mDocumentScore, mCreationTimestampMillis,
                     mDocumentTtlMillis, mName, mAlternateNames, mDescription, mImage, mUrl,
+                    mPotentialActions,
                     mDurationMillis, mOriginalDurationMillis, mStartTimeMillis, mBaseTimeMillis,
                     mBaseTimeMillisInElapsedRealtime, mBootCount, mRemainingDurationMillis,
                     mRingtone, mStatus, mShouldVibrate);
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/BootCountUtil.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/BootCountUtil.java
index 912c6fa..b1c7e1a 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/BootCountUtil.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/BootCountUtil.java
@@ -30,7 +30,7 @@
 /**
  * Helper class for device boot count.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(LIBRARY)
 public class BootCountUtil {
diff --git a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/DateTimeFormatValidator.java b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/DateTimeFormatValidator.java
index 452cde7..e62d87b 100644
--- a/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/DateTimeFormatValidator.java
+++ b/appsearch/appsearch-builtin-types/src/main/java/androidx/appsearch/utils/DateTimeFormatValidator.java
@@ -30,7 +30,7 @@
 /**
  * Helper class used to validate date time formats.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(LIBRARY)
 public final class DateTimeFormatValidator {
diff --git a/appsearch/appsearch-debug-view/lint-baseline.xml b/appsearch/appsearch-debug-view/lint-baseline.xml
deleted file mode 100644
index 3befe35..0000000
--- a/appsearch/appsearch-debug-view/lint-baseline.xml
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class AppSearchDebugActivity extends FragmentActivity {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DebugAppSearchManager implements Closeable {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DocumentFragment extends Fragment {"
-        errorLine2="             ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/DocumentFragment.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DocumentListFragment extends Fragment {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/DocumentListFragment.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DocumentListItemAdapter extends"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/DocumentListItemAdapter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DocumentListModel extends ViewModel {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class DocumentModel extends ViewModel {"
-        errorLine2="             ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/model/DocumentModel.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class MenuFragment extends Fragment {"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/MenuFragment.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SchemaTypeListFragment extends Fragment {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/SchemaTypeListFragment.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SchemaTypeListItemAdapter extends"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/SchemaTypeListItemAdapter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SchemaTypeListModel extends ViewModel {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public abstract class ScrollListener extends RecyclerView.OnScrollListener {"
-        errorLine2="                      ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/debugview/view/ScrollListener.java"/>
-    </issue>
-
-</issues>
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
index 1453274..a6a79da 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/DebugAppSearchManager.java
@@ -54,7 +54,7 @@
  *
  * <p>Instances of {@link DebugAppSearchManager} are created by calling {@link #create}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DebugAppSearchManager implements Closeable {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
index 6425c63..3833198 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentListModel.java
@@ -45,7 +45,7 @@
  *
  * <p>Instances of {@link DocumentListModel} are created by {@link DocumentListModelFactory}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DocumentListModel extends ViewModel {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
index 41d2ed1..10a2e5b 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/DocumentModel.java
@@ -40,7 +40,7 @@
  *
  * <p>Instances of the ViewModel are created by {@link DocumentModelFactory}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DocumentModel extends ViewModel {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
index 70cc1ee..a135dd4 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/model/SchemaTypeListModel.java
@@ -45,7 +45,7 @@
  * <p>This model captures the data for displaying a list of {@link AppSearchSchema} objects that
  * compose of the schema. This also captures the overall schema version.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class SchemaTypeListModel extends ViewModel {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
index 57c60d9..8c979f8 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/AppSearchDebugActivity.java
@@ -64,7 +64,7 @@
  *     startActivity(intent);
  * </pre>
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class AppSearchDebugActivity extends FragmentActivity {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentFragment.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentFragment.java
index 7ba316f..0d520de 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentFragment.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentFragment.java
@@ -43,7 +43,7 @@
 /**
  * A fragment for displaying a {@link GenericDocument} object.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DocumentFragment extends Fragment {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListFragment.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListFragment.java
index 6a89d55..1504119 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListFragment.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListFragment.java
@@ -49,7 +49,7 @@
 /**
  * A fragment for displaying a list of {@link GenericDocument} objects.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DocumentListFragment extends Fragment {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListItemAdapter.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListItemAdapter.java
index b30152b..5e18173 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListItemAdapter.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/DocumentListItemAdapter.java
@@ -37,7 +37,7 @@
  *
  * <p>Documents can be manually changed by calling {@link #setDocuments}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class DocumentListItemAdapter extends
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/MenuFragment.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/MenuFragment.java
index c7abf48..e8dcddb 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/MenuFragment.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/MenuFragment.java
@@ -31,7 +31,7 @@
 /**
  * A fragment for displaying page navigation shortcuts of the debug view.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class MenuFragment extends Fragment {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListFragment.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListFragment.java
index 9bc7100..75ee280 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListFragment.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListFragment.java
@@ -48,7 +48,7 @@
 /**
  * A fragment for displaying a list of {@link AppSearchSchema} objects.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class SchemaTypeListFragment extends Fragment {
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListItemAdapter.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListItemAdapter.java
index 277b050..6857464 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListItemAdapter.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/SchemaTypeListItemAdapter.java
@@ -37,7 +37,7 @@
  *
  * <p>Schema types can be manually changed by calling {@link #setSchemaTypes}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public class SchemaTypeListItemAdapter extends
diff --git a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/ScrollListener.java b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/ScrollListener.java
index a2dd0e98..9a844f5 100644
--- a/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/ScrollListener.java
+++ b/appsearch/appsearch-debug-view/src/main/java/androidx/appsearch/debugview/view/ScrollListener.java
@@ -25,7 +25,7 @@
 /**
  * Listens for scrolling and loads the next page of results if the end of the view is reached.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public abstract class ScrollListener extends RecyclerView.OnScrollListener {
diff --git a/appsearch/appsearch-local-storage/lint-baseline.xml b/appsearch/appsearch-local-storage/lint-baseline.xml
deleted file mode 100644
index b1a0b02..0000000
--- a/appsearch/appsearch-local-storage/lint-baseline.xml
+++ /dev/null
@@ -1,328 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class AlwaysSupportedFeatures implements Features {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class AppSearchImpl implements Closeable {"
-        errorLine2="                   ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public interface AppSearchLogger {"
-        errorLine2="                 ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/AppSearchLogger.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class AppSearchLoggerHelper {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/AppSearchLoggerHelper.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class CallStats {"
-        errorLine2="             ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/CallStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class CallerAccess {"
-        errorLine2="             ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class FutureUtil {"
-        errorLine2="                   ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/util/FutureUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class GenericDocumentToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class InitializeStats {"
-        errorLine2="                   ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/InitializeStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class JetpackOptimizeStrategy implements OptimizeStrategy{"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/JetpackOptimizeStrategy.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public interface LimitConfig {"
-        errorLine2="                 ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/LimitConfig.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="            public Builder setLogger(@NonNull AppSearchLogger logger) {"
-        errorLine2="                           ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/LocalStorage.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="            public Builder setLogger(@NonNull AppSearchLogger logger) {"
-        errorLine2="                           ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/LocalStorage.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class ObserverManager {"
-        errorLine2="             ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/ObserverManager.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class OptimizeStats {"
-        errorLine2="                   ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/OptimizeStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public interface OptimizeStrategy {"
-        errorLine2="                 ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/OptimizeStrategy.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class PrefixUtil {"
-        errorLine2="             ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class PutDocumentStats {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class RemoveStats {"
-        errorLine2="                   ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class ResultCodeToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/ResultCodeToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SchemaToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SearchResultToProtoConverter {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SearchSpecToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SearchSpecToProtoConverterUtil {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SearchStats {"
-        errorLine2="                   ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/SearchStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SearchSuggestionSpecToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SetSchemaResponseToProtoConverter {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/SetSchemaResponseToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SetSchemaStats {"
-        errorLine2="                   ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/stats/SetSchemaStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class TypePropertyPathToProtoConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/converter/TypePropertyPathToProtoConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class UnlimitedLimitConfig implements LimitConfig {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/UnlimitedLimitConfig.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public interface VisibilityChecker {"
-        errorLine2="                 ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class VisibilityDocumentV1 extends GenericDocument {"
-        errorLine2="      ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityStore {"
-        errorLine2="             ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityStoreMigrationHelperFromV0 {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityStoreMigrationHelperFromV1 {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityUtil {"
-        errorLine2="             ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java"/>
-    </issue>
-
-</issues>
diff --git a/appsearch/appsearch-local-storage/proguard-rules.pro b/appsearch/appsearch-local-storage/proguard-rules.pro
index 82c4b719..335e9e8 100644
--- a/appsearch/appsearch-local-storage/proguard-rules.pro
+++ b/appsearch/appsearch-local-storage/proguard-rules.pro
@@ -19,7 +19,7 @@
   <fields>;
 }
 -keep class com.google.android.icing.BreakIteratorBatcher { *; }
--keepclassmembers public class com.google.android.icing.IcingSearchEngine {
+-keepclassmembers public class com.google.android.icing.IcingSearchEngineImpl {
   private long nativePointer;
 }
 
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
index 63bba79..daf7d3a 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
@@ -113,6 +113,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -493,8 +494,8 @@
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         mAppSearchImpl.close();
         mAppSearchImpl = AppSearchImpl.create(
-                mAppSearchDir, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
-                /*visibilityChecker=*/null);
+                mAppSearchDir, new UnlimitedLimitConfig(), new DefaultIcingOptionsConfig(),
+                initStatsBuilder, ALWAYS_OPTIMIZE, /*visibilityChecker=*/null);
 
         // Check recovery state
         InitializeStats initStats = initStatsBuilder.build();
@@ -2491,6 +2492,7 @@
         AppSearchImpl appSearchImpl2 = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -2560,6 +2562,7 @@
         AppSearchImpl appSearchImpl2 = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -2636,6 +2639,7 @@
         AppSearchImpl appSearchImpl2 = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -2763,6 +2767,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -2843,6 +2848,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -2901,6 +2907,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -2939,6 +2946,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3053,6 +3061,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3150,6 +3159,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3208,6 +3218,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3328,7 +3339,10 @@
     @Test
     public void testRemoveByQuery_withJoinSpec_throwsException() {
         Exception e = assertThrows(IllegalArgumentException.class,
-                () -> mAppSearchImpl.removeByQuery("", "", "",
+                () -> mAppSearchImpl.removeByQuery(
+                        /*packageName=*/"",
+                        /*databaseName=*/"",
+                        /*queryExpression=*/"",
                         new SearchSpec.Builder()
                                 .setJoinSpec(new JoinSpec.Builder("childProp").build())
                                 .build(),
@@ -3359,6 +3373,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3443,6 +3458,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3501,6 +3517,7 @@
                         return Integer.MAX_VALUE;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3548,6 +3565,7 @@
                         return 2;
                     }
                 },
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
@@ -3649,6 +3667,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -3699,6 +3718,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -3747,6 +3767,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -3797,6 +3818,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -4139,6 +4161,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -4177,6 +4200,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -4207,6 +4231,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -4302,6 +4327,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 tempFolder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 mockVisibilityChecker);
@@ -4388,6 +4414,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 rejectChecker);
@@ -4489,6 +4516,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 visibilityChecker);
@@ -4548,6 +4576,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 rejectChecker);
@@ -4873,6 +4902,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 visibilityChecker);
@@ -5028,6 +5058,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 visibilityChecker);
@@ -5114,6 +5145,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 visibilityChecker);
@@ -5204,6 +5236,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/null,
                 ALWAYS_OPTIMIZE,
                 visibilityChecker);
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
index bca29e4..c9828f5 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchLoggerTest.java
@@ -22,6 +22,7 @@
 import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.app.InternalSetSchemaResponse;
+import androidx.appsearch.app.JoinSpec;
 import androidx.appsearch.app.SearchResultPage;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.exceptions.AppSearchException;
@@ -54,6 +55,7 @@
 import org.junit.rules.TemporaryFolder;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -74,6 +76,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -348,6 +351,7 @@
         AppSearchImpl appSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 initStatsBuilder,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -378,6 +382,7 @@
         AppSearchImpl appSearchImpl = AppSearchImpl.create(
                 folder,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
@@ -414,8 +419,8 @@
         // Create another appsearchImpl on the same folder
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
-                /*visibilityChecker=*/null);
+                folder, new UnlimitedLimitConfig(), new DefaultIcingOptionsConfig(),
+                initStatsBuilder, ALWAYS_OPTIMIZE, /*visibilityChecker=*/null);
         InitializeStats iStats = initStatsBuilder.build();
 
         assertThat(iStats).isNotNull();
@@ -441,8 +446,8 @@
         final File folder = mTemporaryFolder.newFolder();
 
         AppSearchImpl appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
-                /*visibilityChecker=*/null);
+                folder, new UnlimitedLimitConfig(), new DefaultIcingOptionsConfig(),
+                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE, /*visibilityChecker=*/null);
 
         List<AppSearchSchema> schemas = ImmutableList.of(
                 new AppSearchSchema.Builder("Type1").build(),
@@ -480,8 +485,8 @@
         // Create another appsearchImpl on the same folder
         InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
         appSearchImpl = AppSearchImpl.create(
-                folder, new UnlimitedLimitConfig(), initStatsBuilder, ALWAYS_OPTIMIZE,
-                /*visibilityChecker=*/null);
+                folder, new UnlimitedLimitConfig(), new DefaultIcingOptionsConfig(),
+                initStatsBuilder, ALWAYS_OPTIMIZE, /*visibilityChecker=*/null);
         InitializeStats iStats = initStatsBuilder.build();
 
         // Some of other fields are already covered by AppSearchImplTest#testReset()
@@ -708,6 +713,160 @@
     }
 
     @Test
+    public void testLoggingStats_search_join() throws Exception {
+        AppSearchSchema actionSchema = new AppSearchSchema.Builder("ViewAction")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("entityId")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setJoinableValueType(AppSearchSchema.StringPropertyConfig
+                                .JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        AppSearchSchema entitySchema = new AppSearchSchema.Builder("entity")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("subject")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(
+                                AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .build();
+        List<AppSearchSchema> schemas = Arrays.asList(actionSchema, entitySchema);
+
+        // Insert schema
+        final String testPackageName = "testPackage";
+        final String testDatabase = "testDatabase";
+        InternalSetSchemaResponse internalSetSchemaResponse = mAppSearchImpl.setSchema(
+                testPackageName,
+                testDatabase,
+                schemas,
+                /*visibilityDocuments=*/ Collections.emptyList(),
+                /*forceOverride=*/ false,
+                /*version=*/ 0,
+                /* setSchemaStatsBuilder= */ null);
+
+        assertThat(internalSetSchemaResponse.isSuccess()).isTrue();
+        GenericDocument entity1 =
+                new GenericDocument.Builder<>("namespace", "id1", "entity")
+                        .setPropertyString("subject", "an entity")
+                        .build();
+        GenericDocument entity2 =
+                new GenericDocument.Builder<>("namespace", "id2", "entity")
+                        .setPropertyString("subject", "another entity")
+                        .build();
+
+        GenericDocument action1 =
+                new GenericDocument.Builder<>("namespace", "action1", "ViewAction")
+                        .setPropertyString("entityId",
+                                "testPackage$testDatabase/namespace#id1")
+                        .build();
+        GenericDocument action2 =
+                new GenericDocument.Builder<>("namespace", "action2", "ViewAction")
+                        .setPropertyString("entityId",
+                                "testPackage$testDatabase/namespace#id1")
+                        .build();
+        GenericDocument action3 =
+                new GenericDocument.Builder<>("namespace", "action3", "ViewAction")
+                        .setPropertyString("entityId",
+                                "testPackage$testDatabase/namespace#id1")
+                        .build();
+        GenericDocument action4 =
+                new GenericDocument.Builder<>("namespace", "action4", "ViewAction")
+                        .setPropertyString("entityId",
+                                "testPackage$testDatabase/namespace#id2")
+                        .build();
+
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                entity1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                entity2,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                action1,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                action2,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                action3,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+        mAppSearchImpl.putDocument(
+                testPackageName,
+                testDatabase,
+                action4,
+                /*sendChangeNotifications=*/ false,
+                mLogger);
+
+        SearchSpec nestedSearchSpec =
+                new SearchSpec.Builder()
+                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
+                        .setOrder(SearchSpec.ORDER_ASCENDING)
+                        .build();
+
+        JoinSpec js = new JoinSpec.Builder("entityId")
+                .setNestedSearch("", nestedSearchSpec)
+                .setAggregationScoringStrategy(JoinSpec.AGGREGATION_SCORING_RESULT_COUNT)
+                .build();
+
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_JOIN_AGGREGATE_SCORE)
+                .setJoinSpec(js)
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build();
+
+        String queryStr = "entity";
+        SearchResultPage searchResultPage = mAppSearchImpl.query(testPackageName, testDatabase,
+                queryStr, searchSpec, /*logger=*/ mLogger);
+
+        assertThat(searchResultPage.getResults()).hasSize(2);
+        assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(entity1);
+        assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(entity2);
+
+        SearchStats sStats = mLogger.mSearchStats;
+
+        assertThat(sStats).isNotNull();
+
+        assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
+        assertThat(sStats.getDatabase()).isEqualTo(testDatabase);
+        assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
+        assertThat(sStats.getVisibilityScope()).isEqualTo(SearchStats.VISIBILITY_SCOPE_LOCAL);
+        assertThat(sStats.getTermCount()).isEqualTo(1);
+        assertThat(sStats.getQueryLength()).isEqualTo(queryStr.length());
+        assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(1);
+        assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(2);
+        assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(2);
+        assertThat(sStats.isFirstPage()).isTrue();
+        assertThat(sStats.getRankingStrategy()).isEqualTo(
+                ScoringSpecProto.RankingStrategy.Code.JOIN_AGGREGATE_SCORE_VALUE);
+        assertThat(sStats.getScoredDocumentCount()).isEqualTo(2);
+        assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(0);
+        // Join-specific stats. If the process goes really fast, the total latency could be 0.
+        // Since the default of total latency is also 0, we just remove the assertion on
+        // JoinLatencyMillis.
+        assertThat(sStats.getJoinType()).isEqualTo(
+                AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID);
+        assertThat(sStats.getNumJoinedResultsCurrentPage()).isEqualTo(4);
+    }
+
+    @Test
     public void testLoggingStats_remove_success() throws Exception {
         // Insert schema
         final String testPackageName = "testPackage";
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
index dff83a2..6840a98 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/SearchResultsImplTest.java
@@ -52,6 +52,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mTemporaryFolder.newFolder(),
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
     }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverterTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverterTest.java
index 3f2cb70..3e5a91b 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverterTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverterTest.java
@@ -20,6 +20,7 @@
 
 import androidx.appsearch.app.AppSearchSchema;
 
+import com.google.android.icing.proto.JoinableConfig;
 import com.google.android.icing.proto.PropertyConfigProto;
 import com.google.android.icing.proto.SchemaTypeConfigProto;
 import com.google.android.icing.proto.StringIndexingConfig;
@@ -118,4 +119,44 @@
         assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedMusicRecordingProto))
                 .isEqualTo(musicRecordingSchema);
     }
+
+    @Test
+    public void testGetProto_JoinableConfig() {
+        AppSearchSchema albumSchema = new AppSearchSchema.Builder("Album")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("artist")
+                        .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setJoinableValueType(AppSearchSchema.StringPropertyConfig
+                                .JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        // @exportToFramework:startStrip()
+                        // TODO(b/274157614) start exporting this when it is unhidden in framework
+                        .setDeletionPropagation(true)
+                        // @exportToFramework:endStrip()
+                        .build()
+                ).build();
+
+        JoinableConfig joinableConfig = JoinableConfig.newBuilder()
+                .setValueType(JoinableConfig.ValueType.Code.QUALIFIED_ID)
+                .setPropagateDelete(true)
+                .build();
+
+        SchemaTypeConfigProto expectedAlbumProto = SchemaTypeConfigProto.newBuilder()
+                .setSchemaType("Album")
+                .setVersion(0)
+                .addProperties(
+                        PropertyConfigProto.newBuilder()
+                                .setPropertyName("artist")
+                                .setDataType(PropertyConfigProto.DataType.Code.STRING)
+                                .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL)
+                                .setStringIndexingConfig(StringIndexingConfig.newBuilder()
+                                        .setTermMatchType(TermMatchType.Code.UNKNOWN)
+                                        .setTokenizerType(
+                                                StringIndexingConfig.TokenizerType.Code.NONE))
+                                .setJoinableConfig(joinableConfig))
+                .build();
+
+        assertThat(SchemaToProtoConverter.toSchemaTypeConfigProto(albumSchema, /*version=*/0))
+                .isEqualTo(expectedAlbumProto);
+        assertThat(SchemaToProtoConverter.toAppSearchSchema(expectedAlbumProto))
+                .isEqualTo(albumSchema);
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
index 271bf2a..9a19a6a 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterTest.java
@@ -26,6 +26,8 @@
 import androidx.appsearch.app.JoinSpec;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.DefaultIcingOptionsConfig;
+import androidx.appsearch.localstorage.IcingOptionsConfig;
 import androidx.appsearch.localstorage.OptimizeStrategy;
 import androidx.appsearch.localstorage.UnlimitedLimitConfig;
 import androidx.appsearch.localstorage.util.PrefixUtil;
@@ -43,6 +45,8 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -58,6 +62,26 @@
     @Rule
     public final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
 
+    private final IcingOptionsConfig mDefaultIcingOptionsConfig = new DefaultIcingOptionsConfig();
+
+    private AppSearchImpl mAppSearchImpl;
+
+    @Before
+    public void setUp() throws Exception {
+        mAppSearchImpl = AppSearchImpl.create(
+                mTemporaryFolder.newFolder(),
+                new UnlimitedLimitConfig(),
+                mDefaultIcingOptionsConfig,
+                /*initStatsBuilder=*/ null,
+                ALWAYS_OPTIMIZE,
+                /*visibilityChecker=*/null);
+    }
+
+    @After
+    public void tearDown() {
+        mAppSearchImpl.close();
+    }
+
     @Test
     public void testToSearchSpecProto() throws Exception {
         SearchSpec searchSpec = new SearchSpec.Builder().build();
@@ -70,19 +94,20 @@
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
                 /*namespaceMap=*/ImmutableMap.of(
-                        prefix1, ImmutableSet.of(
-                                prefix1 + "namespace1",
-                                prefix1 + "namespace2"),
-                        prefix2, ImmutableSet.of(
-                                prefix2 + "namespace1",
-                                prefix2 + "namespace2")),
+                prefix1, ImmutableSet.of(
+                        prefix1 + "namespace1",
+                        prefix1 + "namespace2"),
+                prefix2, ImmutableSet.of(
+                        prefix2 + "namespace1",
+                        prefix2 + "namespace2")),
                 /*schemaMap=*/ImmutableMap.of(
-                        prefix1, ImmutableMap.of(
-                                prefix1 + "typeA", configProto,
-                                prefix1 + "typeB", configProto),
-                        prefix2, ImmutableMap.of(
-                                prefix2 + "typeA", configProto,
-                                prefix2 + "typeB", configProto)));
+                prefix1, ImmutableMap.of(
+                        prefix1 + "typeA", configProto,
+                        prefix1 + "typeB", configProto),
+                prefix2, ImmutableMap.of(
+                        prefix2 + "typeA", configProto,
+                        prefix2 + "typeB", configProto)),
+                mDefaultIcingOptionsConfig);
         // Convert SearchSpec to proto.
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
 
@@ -93,6 +118,7 @@
         assertThat(searchSpecProto.getNamespaceFiltersList()).containsExactly(
                 "package$database1/namespace1", "package$database1/namespace2",
                 "package$database2/namespace1", "package$database2/namespace2");
+        assertThat(searchSpecProto.getUseReadOnlySearch()).isTrue();
     }
 
     @Test
@@ -106,7 +132,6 @@
         JoinSpec joinSpec = new JoinSpec.Builder("childPropertyExpression")
                 .setNestedSearch("nestedQuery", nestedSearchSpec)
                 .setAggregationScoringStrategy(JoinSpec.AGGREGATION_SCORING_SUM_RANKING_SIGNAL)
-                .setMaxJoinedResultCount(10)
                 .build();
 
         searchSpec.setJoinSpec(joinSpec);
@@ -131,7 +156,8 @@
                         prefix1 + "typeB", configProto),
                 prefix2, ImmutableMap.of(
                         prefix2 + "typeA", configProto,
-                        prefix2 + "typeB", configProto)));
+                        prefix2 + "typeB", configProto)),
+                mDefaultIcingOptionsConfig);
 
         // Convert SearchSpec to proto.
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
@@ -149,11 +175,10 @@
 
         JoinSpecProto joinSpecProto = searchSpecProto.getJoinSpec();
         assertThat(joinSpecProto.hasNestedSpec()).isTrue();
-        assertThat(joinSpecProto.getParentPropertyExpression()).isEqualTo(JoinSpec.QUALIFIED_ID);
+        assertThat(joinSpecProto.getParentPropertyExpression()).isEqualTo("this.qualifiedId()");
         assertThat(joinSpecProto.getChildPropertyExpression()).isEqualTo("childPropertyExpression");
         assertThat(joinSpecProto.getAggregationScoringStrategy())
                 .isEqualTo(JoinSpecProto.AggregationScoringStrategy.Code.SUM);
-        assertThat(joinSpecProto.getMaxJoinedChildCount()).isEqualTo(10);
 
         JoinSpecProto.NestedSpecProto nestedSpecProto = joinSpecProto.getNestedSpec();
         assertThat(nestedSpecProto.getSearchSpec().getQuery()).isEqualTo("nestedQuery");
@@ -161,6 +186,87 @@
                 ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP);
     }
 
+    @Test
+    public void testToSearchSpec_withJoinSpec_childSearchesOtherSchema() throws Exception {
+        String prefix1 = PrefixUtil.createPrefix("package", "database1");
+        String prefix2 = PrefixUtil.createPrefix("package", "database2");
+
+        SearchSpec nestedSearchSpec =
+                new SearchSpec.Builder()
+                        .addFilterPackageNames("package")
+                        .addFilterSchemas("typeA")
+                        .build();
+        SearchSpec.Builder searchSpec =
+                new SearchSpec.Builder()
+                        .addFilterPackageNames("package")
+                        .addFilterSchemas("typeB");
+
+        // Create a JoinSpec object and set it in the converter
+        JoinSpec joinSpec =
+                new JoinSpec.Builder("childPropertyExpression")
+                        .setNestedSearch("nestedQuery", nestedSearchSpec)
+                        .build();
+
+        searchSpec.setJoinSpec(joinSpec);
+
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        SearchSpecToProtoConverter converter =
+                new SearchSpecToProtoConverter(
+                        /*queryExpression=*/ "query",
+                        searchSpec.build(),
+                        /*prefixes=*/ ImmutableSet.of(prefix1, prefix2),
+                        /*namespaceMap=*/ ImmutableMap.of(
+                        prefix1,
+                        ImmutableSet.of(
+                                prefix1 + "namespace1", prefix1 + "namespace2"),
+                        prefix2,
+                        ImmutableSet.of(
+                                prefix2 + "namespace1", prefix2 + "namespace2")),
+                        /*schemaMap=*/ ImmutableMap.of(
+                        prefix1,
+                        ImmutableMap.of(
+                                prefix1 + "typeA", configProto,
+                                prefix1 + "typeB", configProto),
+                        prefix2,
+                        ImmutableMap.of(
+                                prefix2 + "typeA", configProto,
+                                prefix2 + "typeB", configProto)),
+                        mDefaultIcingOptionsConfig);
+
+        VisibilityStore visibilityStore = new VisibilityStore(mAppSearchImpl);
+        converter.removeInaccessibleSchemaFilter(
+                new CallerAccess(/*callingPackageName=*/"package"),
+                visibilityStore,
+                AppSearchTestUtils.createMockVisibilityChecker(
+                        /*visiblePrefixedSchemas=*/ ImmutableSet.of(
+                                prefix1 + "typeA", prefix1 + "typeB", prefix2 + "typeA",
+                                prefix2 + "typeB")));
+
+        // Convert SearchSpec to proto.
+        SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
+
+        assertThat(searchSpecProto.getQuery()).isEqualTo("query");
+        assertThat(searchSpecProto.getSchemaTypeFiltersList())
+                .containsExactly(
+                        "package$database1/typeB",
+                        "package$database2/typeB");
+        assertThat(searchSpecProto.getNamespaceFiltersList())
+                .containsExactly(
+                        "package$database1/namespace1", "package$database1/namespace2",
+                        "package$database2/namespace1", "package$database2/namespace2");
+
+        // Assert that the joinSpecProto is set correctly in the searchSpecProto
+        assertThat(searchSpecProto.hasJoinSpec()).isTrue();
+
+        JoinSpecProto joinSpecProto = searchSpecProto.getJoinSpec();
+        assertThat(joinSpecProto.hasNestedSpec()).isTrue();
+
+        JoinSpecProto.NestedSpecProto nestedSpecProto = joinSpecProto.getNestedSpec();
+        assertThat(nestedSpecProto.getSearchSpec().getSchemaTypeFiltersList())
+                .containsExactly(
+                        "package$database1/typeA",
+                        "package$database2/typeA");
+    }
 
     @Test
     public void testToScoringSpecProto() {
@@ -177,7 +283,8 @@
                 searchSpec, /*prefixes=*/ImmutableSet.of(prefix),
                 /*namespaceMap=*/ImmutableMap.of(prefix, ImmutableSet.of(prefix + namespace)),
                 /*schemaMap=*/ImmutableMap.of(prefix, ImmutableMap.of(prefix + schemaType,
-                SchemaTypeConfigProto.getDefaultInstance()))).toScoringSpecProto();
+                SchemaTypeConfigProto.getDefaultInstance())),
+                mDefaultIcingOptionsConfig).toScoringSpecProto();
         TypePropertyWeights typePropertyWeights = TypePropertyWeights.newBuilder()
                 .setSchemaType(prefix + schemaType)
                 .addPropertyWeights(PropertyWeight.newBuilder()
@@ -205,7 +312,8 @@
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(),
                 /*namespaceMap=*/ImmutableMap.of(),
-                /*schemaMap=*/ImmutableMap.of()).toScoringSpecProto();
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig).toScoringSpecProto();
 
         assertThat(scoringSpecProto.getOrderBy().getNumber())
                 .isEqualTo(ScoringSpecProto.Order.Code.ASC_VALUE);
@@ -229,9 +337,11 @@
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(),
                 /*namespaceMap=*/ImmutableMap.of(),
-                /*schemaMap=*/ImmutableMap.of());
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
         ResultSpecProto resultSpecProto = convert.toResultSpecProto(
-                /*namespaceMap=*/ImmutableMap.of());
+                /*namespaceMap=*/ImmutableMap.of(),
+                /*schemaMap=*/ImmutableMap.of());
 
         assertThat(resultSpecProto.getNumPerPage()).isEqualTo(123);
         assertThat(resultSpecProto.getSnippetSpec().getNumToSnippet()).isEqualTo(234);
@@ -240,6 +350,46 @@
     }
 
     @Test
+    public void testToResultSpecProtoWithJoinSpec() throws Exception {
+        SearchSpec nestedSearchSpec = new SearchSpec.Builder()
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP).build();
+
+        // Create a JoinSpec object and set it in the converter
+        JoinSpec joinSpec = new JoinSpec.Builder("childPropertyExpression")
+                .setNestedSearch("nestedQuery", nestedSearchSpec)
+                .setAggregationScoringStrategy(JoinSpec.AGGREGATION_SCORING_SUM_RANKING_SIGNAL)
+                .setMaxJoinedResultCount(10)
+                .build();
+
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_JOIN_AGGREGATE_SCORE)
+                .setJoinSpec(joinSpec)
+                .setResultCountPerPage(123)
+                .setSnippetCount(234)
+                .setSnippetCountPerProperty(345)
+                .setMaxSnippetSize(456)
+                .build();
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"query",
+                searchSpec,
+                /*prefixes=*/ImmutableSet.of(),
+                /*namespaceMap=*/ImmutableMap.of(),
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
+
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(
+                /*namespaceMap=*/ImmutableMap.of(),
+                /*schemaMap=*/ImmutableMap.of());
+
+        assertThat(resultSpecProto.getNumPerPage()).isEqualTo(123);
+        assertThat(resultSpecProto.getSnippetSpec().getNumToSnippet()).isEqualTo(234);
+        assertThat(resultSpecProto.getSnippetSpec().getNumMatchesPerProperty()).isEqualTo(345);
+        assertThat(resultSpecProto.getSnippetSpec().getMaxWindowUtf32Length()).isEqualTo(456);
+        assertThat(resultSpecProto.getMaxJoinedChildrenPerParentToReturn()).isEqualTo(10);
+    }
+
+    @Test
     public void testToResultSpecProto_groupByPackage() {
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 5)
@@ -253,7 +403,8 @@
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
                 /*namespaceMap=*/ImmutableMap.of(),
-                /*schemaMap=*/ImmutableMap.of());
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
         ResultSpecProto resultSpecProto = converter.toResultSpecProto(
                 /*namespaceMap=*/ImmutableMap.of(
                         prefix1, ImmutableSet.of(
@@ -261,7 +412,8 @@
                                 prefix1 + "namespaceB"),
                         prefix2, ImmutableSet.of(
                                 prefix2 + "namespaceA",
-                                prefix2 + "namespaceB")));
+                                prefix2 + "namespaceB")),
+                /*schemaMap=*/ImmutableMap.of());
 
         assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(2);
         // First grouping should have same package name.
@@ -304,8 +456,11 @@
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
                 namespaceMap,
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(
+                namespaceMap,
                 /*schemaMap=*/ImmutableMap.of());
-        ResultSpecProto resultSpecProto = converter.toResultSpecProto(namespaceMap);
 
         assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(2);
         // First grouping should have same namespace.
@@ -325,11 +480,61 @@
                         PrefixUtil.removePrefix(grouping2.getEntryGroupings(1).getNamespace()));
     }
 
+    // @exportToFramework:startStrip()
+    // TODO(b/258715421) start exporting this when it is unhidden in framework
+    @Test
+    public void testToResultSpecProto_groupBySchema() throws Exception {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_SCHEMA, 5)
+                .build();
+
+        String prefix1 = PrefixUtil.createPrefix("package1", "database");
+        String prefix2 = PrefixUtil.createPrefix("package2", "database");
+
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        Map<String, Map<String, SchemaTypeConfigProto>> schemaMap = ImmutableMap.of(
+                prefix1, ImmutableMap.of(
+                    prefix1 + "typeA", configProto,
+                    prefix1 + "typeB", configProto),
+                prefix2, ImmutableMap.of(
+                    prefix2 + "typeA", configProto,
+                    prefix2 + "typeB", configProto));
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"query",
+                searchSpec,
+                /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
+                /*namespaceMap=*/ImmutableMap.of(),
+                schemaMap,
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(
+                /*namespaceMap=*/ImmutableMap.of(),
+                schemaMap);
+
+        assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(2);
+        // First grouping should have the same schema type.
+        ResultSpecProto.ResultGrouping grouping1 = resultSpecProto.getResultGroupings(0);
+        assertThat(grouping1.getEntryGroupingsList()).hasSize(2);
+        assertThat(
+                PrefixUtil.removePrefix(grouping1.getEntryGroupings(0).getSchema()))
+                .isEqualTo(
+                    PrefixUtil.removePrefix(grouping1.getEntryGroupings(1).getSchema()));
+
+        // Second grouping should have the same schema type.
+        ResultSpecProto.ResultGrouping grouping2 = resultSpecProto.getResultGroupings(1);
+        assertThat(grouping2.getEntryGroupingsList()).hasSize(2);
+        assertThat(
+                PrefixUtil.removePrefix(grouping2.getEntryGroupings(0).getSchema()))
+                .isEqualTo(
+                    PrefixUtil.removePrefix(grouping2.getEntryGroupings(1).getSchema()));
+    }
+    // @exportToFramework:endStrip()
+
     @Test
     public void testToResultSpecProto_groupByNamespaceAndPackage() throws Exception {
         SearchSpec searchSpec = new SearchSpec.Builder()
                 .setResultGrouping(GROUPING_TYPE_PER_PACKAGE
-                        | SearchSpec.GROUPING_TYPE_PER_NAMESPACE, 5)
+                    | SearchSpec.GROUPING_TYPE_PER_NAMESPACE, 5)
                 .build();
 
         String prefix1 = PrefixUtil.createPrefix("package1", "database");
@@ -346,8 +551,11 @@
                 /*queryExpression=*/"query",
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
-                namespaceMap, /*schemaMap=*/ImmutableMap.of());
-        ResultSpecProto resultSpecProto = converter.toResultSpecProto(namespaceMap);
+                namespaceMap, /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(
+                namespaceMap,
+                /*schemaMap=*/ImmutableMap.of());
 
         // All namespace should be separated.
         assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(4);
@@ -357,6 +565,247 @@
         assertThat(resultSpecProto.getResultGroupings(3).getEntryGroupingsList()).hasSize(1);
     }
 
+    // @exportToFramework:startStrip()
+    // TODO(b/258715421) start exporting this when it is unhidden in framework
+    @Test
+    public void testToResultSpecProto_groupBySchemaAndPackage() throws Exception {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setResultGrouping(GROUPING_TYPE_PER_PACKAGE
+                    | SearchSpec.GROUPING_TYPE_PER_SCHEMA, 5)
+                .build();
+
+        String prefix1 = PrefixUtil.createPrefix("package1", "database");
+        String prefix2 = PrefixUtil.createPrefix("package2", "database");
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        Map<String, Map<String, SchemaTypeConfigProto>> schemaMap = ImmutableMap.of(
+                prefix1, ImmutableMap.of(
+                    prefix1 + "typeA", configProto,
+                    prefix1 + "typeB", configProto),
+                prefix2, ImmutableMap.of(
+                    prefix2 + "typeA", configProto,
+                    prefix2 + "typeB", configProto));
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"query",
+                searchSpec,
+                /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
+                /*namespaceMap=*/ImmutableMap.of(),
+                schemaMap,
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(
+                /*namespaceMap=*/ImmutableMap.of(),
+                schemaMap);
+
+        // All schema should be separated.
+        assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(4);
+        assertThat(resultSpecProto.getResultGroupings(0).getEntryGroupingsList()).hasSize(1);
+        assertThat(resultSpecProto.getResultGroupings(1).getEntryGroupingsList()).hasSize(1);
+        assertThat(resultSpecProto.getResultGroupings(2).getEntryGroupingsList()).hasSize(1);
+        assertThat(resultSpecProto.getResultGroupings(3).getEntryGroupingsList()).hasSize(1);
+    }
+
+    @Test
+    public void testToResultSpecProto_groupByNamespaceAndSchema() throws Exception {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_SCHEMA, 5)
+                .build();
+
+        String prefix1 = PrefixUtil.createPrefix("package1", "database");
+        String prefix2 = PrefixUtil.createPrefix("package2", "database");
+        Map<String, Set<String>> namespaceMap = /*namespaceMap=*/ImmutableMap.of(
+                prefix1, ImmutableSet.of(
+                    prefix1 + "namespaceA",
+                    prefix1 + "namespaceB"),
+                prefix2, ImmutableSet.of(
+                    prefix2 + "namespaceA",
+                    prefix2 + "namespaceB"));
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        Map<String, Map<String, SchemaTypeConfigProto>> schemaMap = ImmutableMap.of(
+                prefix1, ImmutableMap.of(
+                    prefix1 + "typeA", configProto,
+                    prefix1 + "typeB", configProto),
+                prefix2, ImmutableMap.of(
+                    prefix2 + "typeA", configProto,
+                    prefix2 + "typeB", configProto));
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"query",
+                searchSpec,
+                /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
+                namespaceMap,
+                schemaMap,
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(namespaceMap, schemaMap);
+
+        assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(4);
+        ResultSpecProto.ResultGrouping grouping1 = resultSpecProto.getResultGroupings(0);
+        // Each grouping should have a size of 2.
+        assertThat(grouping1.getEntryGroupingsList()).hasSize(2);
+        // Each grouping should have the same namespace and schema type.
+        // Each entry should have the same package and database.
+        assertThat(grouping1.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceA");
+        assertThat(grouping1.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeA");
+        assertThat(grouping1.getEntryGroupings(1).getNamespace())
+                .isEqualTo("package2$database/namespaceA");
+        assertThat(grouping1.getEntryGroupings(1).getSchema())
+                .isEqualTo("package2$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping2 = resultSpecProto.getResultGroupings(1);
+        // Each grouping should have a size of 2.
+        assertThat(grouping2.getEntryGroupingsList()).hasSize(2);
+        // Each grouping should have the same namespace and schema type.
+        // Each entry should have the same package and database.
+        assertThat(grouping2.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceA");
+        assertThat(grouping2.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeB");
+        assertThat(grouping2.getEntryGroupings(1).getNamespace())
+                .isEqualTo("package2$database/namespaceA");
+        assertThat(grouping2.getEntryGroupings(1).getSchema())
+                .isEqualTo("package2$database/typeB");
+
+        ResultSpecProto.ResultGrouping grouping3 = resultSpecProto.getResultGroupings(2);
+        // Each grouping should have a size of 2.
+        assertThat(grouping3.getEntryGroupingsList()).hasSize(2);
+        // Each grouping should have the same namespace and schema type.
+        // Each entry should have the same package and database.
+        assertThat(grouping3.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceB");
+        assertThat(grouping3.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeA");
+        assertThat(grouping3.getEntryGroupings(1).getNamespace())
+                .isEqualTo("package2$database/namespaceB");
+        assertThat(grouping3.getEntryGroupings(1).getSchema())
+                .isEqualTo("package2$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping4 = resultSpecProto.getResultGroupings(3);
+        // Each grouping should have a size of 2.
+        assertThat(grouping4.getEntryGroupingsList()).hasSize(2);
+        // Each grouping should have the same namespace and schema type.
+        // Each entry should have the same package and database.
+        assertThat(grouping4.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceB");
+        assertThat(grouping4.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeB");
+        assertThat(grouping4.getEntryGroupings(1).getNamespace())
+                .isEqualTo("package2$database/namespaceB");
+        assertThat(grouping4.getEntryGroupings(1).getSchema())
+                .isEqualTo("package2$database/typeB");
+    }
+
+    @Test
+    public void testToResultSpecProto_groupByNamespaceAndSchemaAndPackage() throws Exception {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_PACKAGE
+                    | SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_SCHEMA, 5)
+                .build();
+        String prefix1 = PrefixUtil.createPrefix("package1", "database");
+        String prefix2 = PrefixUtil.createPrefix("package2", "database");
+        Map<String, Set<String>> namespaceMap = /*namespaceMap=*/ImmutableMap.of(
+                prefix1, ImmutableSet.of(
+                    prefix1 + "namespaceA",
+                    prefix1 + "namespaceB"),
+                prefix2, ImmutableSet.of(
+                    prefix2 + "namespaceA",
+                    prefix2 + "namespaceB"));
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        Map<String, Map<String, SchemaTypeConfigProto>> schemaMap = ImmutableMap.of(
+                prefix1, ImmutableMap.of(
+                    prefix1 + "typeA", configProto,
+                    prefix1 + "typeB", configProto),
+                prefix2, ImmutableMap.of(
+                    prefix2 + "typeA", configProto,
+                    prefix2 + "typeB", configProto));
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"query",
+                searchSpec,
+                /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
+                namespaceMap,
+                schemaMap,
+                mDefaultIcingOptionsConfig);
+        ResultSpecProto resultSpecProto = converter.toResultSpecProto(namespaceMap, schemaMap);
+
+        assertThat(resultSpecProto.getResultGroupingsCount()).isEqualTo(8);
+        ResultSpecProto.ResultGrouping grouping1 = resultSpecProto.getResultGroupings(0);
+        //assertThat(grouping1.getEntryGroupingsList()).containsExactly();
+        // Each grouping should have the size of 1.
+        assertThat(grouping1.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping1.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package2$database/namespaceA");
+        assertThat(grouping1.getEntryGroupings(0).getSchema())
+                .isEqualTo("package2$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping2 = resultSpecProto.getResultGroupings(1);
+        // Each grouping should have the size of 1.
+        assertThat(grouping2.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping2.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package2$database/namespaceA");
+        assertThat(grouping2.getEntryGroupings(0).getSchema())
+                .isEqualTo("package2$database/typeB");
+
+        ResultSpecProto.ResultGrouping grouping3 = resultSpecProto.getResultGroupings(2);
+        // Each grouping should have the size of 1.
+        assertThat(grouping3.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping3.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package2$database/namespaceB");
+        assertThat(grouping3.getEntryGroupings(0).getSchema())
+                .isEqualTo("package2$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping4 = resultSpecProto.getResultGroupings(3);
+        // Each grouping should have the size of 1.
+        assertThat(grouping4.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping4.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package2$database/namespaceB");
+        assertThat(grouping4.getEntryGroupings(0).getSchema())
+                .isEqualTo("package2$database/typeB");
+
+        ResultSpecProto.ResultGrouping grouping5 = resultSpecProto.getResultGroupings(4);
+        // Each grouping should have the size of 1.
+        assertThat(grouping5.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping5.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceA");
+        assertThat(grouping5.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping6 = resultSpecProto.getResultGroupings(5);
+        // Each grouping should have the size of 1.
+        assertThat(grouping6.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping6.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceA");
+        assertThat(grouping6.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeB");
+
+        ResultSpecProto.ResultGrouping grouping7 = resultSpecProto.getResultGroupings(6);
+        // Each grouping should have the size of 1.
+        assertThat(grouping7.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping7.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceB");
+        assertThat(grouping7.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeA");
+
+        ResultSpecProto.ResultGrouping grouping8 = resultSpecProto.getResultGroupings(7);
+        // Each grouping should have the size of 1.
+        assertThat(grouping8.getEntryGroupingsList()).hasSize(1);
+        // Each entry should have the same package.
+        assertThat(grouping8.getEntryGroupings(0).getNamespace())
+                .isEqualTo("package1$database/namespaceB");
+        assertThat(grouping8.getEntryGroupings(0).getSchema())
+                .isEqualTo("package1$database/typeB");
+    }
+    // @exportToFramework:endStrip()
+
     @Test
     public void testGetTargetNamespaceFilters_emptySearchingFilter() {
         SearchSpec searchSpec = new SearchSpec.Builder().build();
@@ -372,7 +821,8 @@
                 /*queryExpression=*/"",
                 searchSpec,
                 /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
-                namespaceMap, /*schemaMap=*/ImmutableMap.of());
+                namespaceMap, /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
 
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
 
@@ -397,7 +847,8 @@
                         "package$database1/namespace2"),
                 prefix2, ImmutableSet.of("package$database2/namespace3",
                         "package$database2/namespace4")),
-                /*schemaMap=*/ImmutableMap.of());
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
 
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // Only search prefix1 will return namespace 1 and 2.
@@ -419,7 +870,8 @@
                 /*namespaceMap=*/ImmutableMap.of(
                 prefix1, ImmutableSet.of("package$database1/namespace1",
                         "package$database1/namespace2")),
-                /*schemaMap=*/ImmutableMap.of());
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // If the searching namespace filter is not empty, the target namespace filter will be the
         // intersection of the searching namespace filters that users want to search over and
@@ -442,7 +894,8 @@
                 /*namespaceMap=*/ImmutableMap.of(
                 prefix1, ImmutableSet.of("package$database1/namespace1",
                         "package$database1/namespace2")),
-                /*schemaMap=*/ImmutableMap.of());
+                /*schemaMap=*/ImmutableMap.of(),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // If the searching namespace filter is not empty, the target namespace filter will be the
         // intersection of the searching namespace filters that users want to search over and
@@ -469,7 +922,8 @@
                         "package$database1/typeB", schemaTypeConfigProto),
                 prefix2, ImmutableMap.of(
                         "package$database2/typeC", schemaTypeConfigProto,
-                        "package$database2/typeD", schemaTypeConfigProto)));
+                        "package$database2/typeD", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // Empty searching filter will get all types for target filter
         assertThat(searchSpecProto.getSchemaTypeFiltersList()).containsExactly(
@@ -497,7 +951,8 @@
                         "package$database1/typeB", schemaTypeConfigProto),
                 prefix2, ImmutableMap.of(
                         "package$database2/typeC", schemaTypeConfigProto,
-                        "package$database2/typeD", schemaTypeConfigProto)));
+                        "package$database2/typeD", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // Only search prefix1 will return typeA and B.
         assertThat(searchSpecProto.getSchemaTypeFiltersList()).containsExactly(
@@ -521,7 +976,8 @@
                 /*schemaMap=*/ImmutableMap.of(
                 prefix1, ImmutableMap.of(
                         "package$database1/typeA", schemaTypeConfigProto,
-                        "package$database1/typeB", schemaTypeConfigProto)));
+                        "package$database1/typeB", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // If the searching schema filter is not empty, the target schema filter will be the
         // intersection of the schema filters that users want to search over and those candidates
@@ -547,7 +1003,8 @@
                 /*schemaMap=*/ImmutableMap.of(
                 prefix1, ImmutableMap.of(
                         "package$database1/typeA", schemaTypeConfigProto,
-                        "package$database1/typeB", schemaTypeConfigProto)));
+                        "package$database1/typeB", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
         SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
         // If there is no intersection of the schema filters that user want to search over and
         // those filters which are stored in AppSearch, return empty.
@@ -556,20 +1013,19 @@
 
     @Test
     public void testRemoveInaccessibleSchemaFilter() throws Exception {
-        AppSearchImpl appSearchImpl = AppSearchImpl.create(
-                mTemporaryFolder.newFolder(),
-                new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/null,
-                ALWAYS_OPTIMIZE,
-                /*visibilityChecker=*/null);
-        VisibilityStore visibilityStore = new VisibilityStore(appSearchImpl);
+        VisibilityStore visibilityStore = new VisibilityStore(mAppSearchImpl);
 
         final String prefix = PrefixUtil.createPrefix("package", "database");
         SchemaTypeConfigProto schemaTypeConfigProto =
                 SchemaTypeConfigProto.newBuilder().getDefaultInstanceForType();
+
+        SearchSpec nestedSearchSpec = new SearchSpec.Builder().build();
+        JoinSpec joinSpec = new JoinSpec.Builder("entity")
+                .setNestedSearch("", nestedSearchSpec).build();
+
         SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
                 /*queryExpression=*/"",
-                new SearchSpec.Builder().build(),
+                new SearchSpec.Builder().setJoinSpec(joinSpec).build(),
                 /*prefixes=*/ImmutableSet.of(prefix),
                 /*namespaceMap=*/ImmutableMap.of(
                 prefix, ImmutableSet.of("package$database/namespace1")),
@@ -577,7 +1033,8 @@
                 prefix, ImmutableMap.of(
                         "package$database/schema1", schemaTypeConfigProto,
                         "package$database/schema2", schemaTypeConfigProto,
-                        "package$database/schema3", schemaTypeConfigProto)));
+                        "package$database/schema3", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
 
         converter.removeInaccessibleSchemaFilter(
                 new CallerAccess(/*callingPackageName=*/"otherPackageName"),
@@ -590,12 +1047,21 @@
         // schema 2 is filtered out since it is not searchable for user.
         assertThat(searchSpecProto.getSchemaTypeFiltersList()).containsExactly(
                 prefix + "schema1", prefix + "schema3");
+
+        SearchSpecProto nestedSearchProto =
+                searchSpecProto.getJoinSpec().getNestedSpec().getSearchSpec();
+        assertThat(nestedSearchProto.getSchemaTypeFiltersList()).containsExactly(
+                prefix + "schema1", prefix + "schema3");
     }
 
     @Test
     public void testIsNothingToSearch() {
         String prefix = PrefixUtil.createPrefix("package", "database");
+        SearchSpec nestedSearchSpec = new SearchSpec.Builder().build();
+        JoinSpec joinSpec = new JoinSpec.Builder("entity")
+                .setNestedSearch("nested", nestedSearchSpec).build();
         SearchSpec searchSpec = new SearchSpec.Builder()
+                .setJoinSpec(joinSpec)
                 .addFilterSchemas("schema").addFilterNamespaces("namespace").build();
 
         // build maps
@@ -614,7 +1080,8 @@
                         /*queryExpression=*/"",
                         searchSpec, /*prefixes=*/ImmutableSet.of(prefix),
                         /*namespaceMap=*/namespaceMap,
-                        /*schemaMap=*/ImmutableMap.of());
+                        /*schemaMap=*/ImmutableMap.of(),
+                        mDefaultIcingOptionsConfig);
         assertThat(emptySchemaConverter.hasNothingToSearch()).isTrue();
 
         SearchSpecToProtoConverter emptyNamespaceConverter =
@@ -622,14 +1089,16 @@
                         /*queryExpression=*/"",
                         searchSpec, /*prefixes=*/ImmutableSet.of(prefix),
                         /*namespaceMap=*/ImmutableMap.of(),
-                        schemaMap);
+                        schemaMap,
+                        mDefaultIcingOptionsConfig);
         assertThat(emptyNamespaceConverter.hasNothingToSearch()).isTrue();
 
         SearchSpecToProtoConverter nonEmptyConverter =
                 new SearchSpecToProtoConverter(
                         /*queryExpression=*/"",
                         searchSpec, /*prefixes=*/ImmutableSet.of(prefix),
-                        namespaceMap, schemaMap);
+                        namespaceMap, schemaMap,
+                        mDefaultIcingOptionsConfig);
         assertThat(nonEmptyConverter.hasNothingToSearch()).isFalse();
 
         // remove all target schema filter, and the query becomes nothing to search.
@@ -638,6 +1107,49 @@
                 /*visibilityStore=*/null,
                 /*visibilityChecker=*/null);
         assertThat(nonEmptyConverter.hasNothingToSearch()).isTrue();
+        // As the JoinSpec has nothing to search, it should not be part of the SearchSpec
+        assertThat(nonEmptyConverter.toSearchSpecProto().hasJoinSpec()).isFalse();
+    }
+
+    @Test
+    public void testRemoveInaccessibleSchemaFilterWithEmptyNestedFilter() throws Exception {
+        VisibilityStore visibilityStore = new VisibilityStore(mAppSearchImpl);
+
+        final String prefix = PrefixUtil.createPrefix("package", "database");
+        SchemaTypeConfigProto schemaTypeConfigProto =
+                SchemaTypeConfigProto.newBuilder().getDefaultInstanceForType();
+
+        SearchSpec nestedSearchSpec = new SearchSpec.Builder()
+                .addFilterSchemas(ImmutableSet.of(prefix + "schema1", prefix + "schema2"))
+                .build();
+        JoinSpec joinSpec = new JoinSpec.Builder("entity")
+                .setNestedSearch("nested", nestedSearchSpec).build();
+
+        SearchSpecToProtoConverter converter = new SearchSpecToProtoConverter(
+                /*queryExpression=*/"",
+                new SearchSpec.Builder().setJoinSpec(joinSpec).build(),
+                /*prefixes=*/ImmutableSet.of(prefix),
+                /*namespaceMap=*/ImmutableMap.of(
+                prefix, ImmutableSet.of("package$database/namespace1")),
+                /*schemaMap=*/ImmutableMap.of(
+                prefix, ImmutableMap.of(
+                        "package$database/schema1", schemaTypeConfigProto,
+                        "package$database/schema2", schemaTypeConfigProto,
+                        "package$database/schema3", schemaTypeConfigProto)),
+                mDefaultIcingOptionsConfig);
+
+        converter.removeInaccessibleSchemaFilter(
+                new CallerAccess(/*callingPackageName=*/"otherPackageName"),
+                visibilityStore,
+                AppSearchTestUtils.createMockVisibilityChecker(
+                        /*visiblePrefixedSchemas=*/ ImmutableSet.of(prefix + "schema3")));
+
+        SearchSpecProto searchSpecProto = converter.toSearchSpecProto();
+        assertThat(searchSpecProto.getSchemaTypeFiltersList()).containsExactly(prefix + "schema3");
+
+        // Schema 1 and 2 are filtered out of the nested spec. As the JoinSpec has nothing to
+        // search, it should not be part of the SearchSpec.
+        assertThat(searchSpecProto.hasJoinSpec()).isFalse();
     }
 
     @Test
@@ -671,7 +1183,8 @@
                         /*queryExpression=*/"",
                         searchSpec, /*prefixes=*/ImmutableSet.of(prefix1, prefix2),
                         namespaceMap,
-                        schemaTypeMap);
+                        schemaTypeMap,
+                        mDefaultIcingOptionsConfig);
 
         TypePropertyWeights expectedTypePropertyWeight1 =
                 TypePropertyWeights.newBuilder().setSchemaType(prefix1 + schemaTypeA)
@@ -721,7 +1234,8 @@
                         ImmutableSet.of(prefix1 + "namespace1")),
                         /*schemaMap=*/ImmutableMap.of(
                         prefix1,
-                        ImmutableMap.of(prefix1 + "typeA", schemaTypeConfigProto)));
+                        ImmutableMap.of(prefix1 + "typeA", schemaTypeConfigProto)),
+                        mDefaultIcingOptionsConfig);
 
         ScoringSpecProto convertedScoringSpecProto = converter.toScoringSpecProto();
 
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverterTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverterTest.java
index 0a848fa..f918784 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverterTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverterTest.java
@@ -42,7 +42,6 @@
                         .addFilterNamespaces("namespace1", "namespace2")
                         .addFilterDocumentIds("namespace1", ImmutableList.of("doc1", "doc2"))
                         .addFilterSchemas("typeA", "typeB")
-                        .addFilterProperties("typeA", ImmutableList.of("property1", "property2"))
                         .build();
 
         String prefix1 = PrefixUtil.createPrefix("package", "database");
@@ -68,15 +67,41 @@
                 "package$database/typeA", "package$database/typeB");
         assertThat(proto.getNamespaceFiltersList()).containsExactly(
                 "package$database/namespace1", "package$database/namespace2");
-        assertThat(proto.getTypePropertyFiltersList()).containsExactly(
-                TypePropertyMask.newBuilder()
-                        .setSchemaType("package$database/typeA")
-                        .addPaths("property1").addPaths("property2")
-                        .build());
         assertThat(proto.getDocumentUriFiltersList()).containsExactly(
                 NamespaceDocumentUriGroup.newBuilder()
                         .setNamespace("package$database/namespace1")
                         .addDocumentUris("doc1").addDocumentUris("doc2")
                         .build());
     }
+
+    // @exportToFramework:startStrip()
+    // TODO(b/230553264) remove this when it is deprecated and replaced by
+    //  advanced query property filters or it is exportable.
+    @Test
+    public void testToProto_propertyFilters() throws Exception {
+        SearchSuggestionSpec searchSuggestionSpec =
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/123)
+                        .addFilterProperties("typeA", ImmutableList.of("property1", "property2"))
+                        .build();
+
+        String prefix1 = PrefixUtil.createPrefix("package", "database");
+        SchemaTypeConfigProto configProto = SchemaTypeConfigProto.getDefaultInstance();
+        SearchSuggestionSpecToProtoConverter converter = new SearchSuggestionSpecToProtoConverter(
+                /*queryExpression=*/"prefix",
+                searchSuggestionSpec,
+                /*prefixes=*/ImmutableSet.of(prefix1),
+                /*namespaceMap=*/ImmutableMap.of(),
+                /*schemaMap=*/ImmutableMap.of(
+                prefix1, ImmutableMap.of(
+                        prefix1 + "typeA", configProto,
+                        prefix1 + "typeB", configProto)));
+
+        SuggestionSpecProto proto = converter.toSearchSuggestionSpecProto();
+        assertThat(proto.getTypePropertyFiltersList()).containsExactly(
+                TypePropertyMask.newBuilder()
+                        .setSchemaType("package$database/typeA")
+                        .addPaths("property1").addPaths("property2")
+                        .build());
+    }
+    // @exportToFramework:endStrip()
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
index fc8d058..167ed1c 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
@@ -32,6 +32,7 @@
 import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.DefaultIcingOptionsConfig;
 import androidx.appsearch.localstorage.OptimizeStrategy;
 import androidx.appsearch.localstorage.UnlimitedLimitConfig;
 import androidx.appsearch.localstorage.util.PrefixUtil;
@@ -127,7 +128,7 @@
         // Persist to disk and re-open the AppSearchImpl
         appSearchImplInV0.close();
         AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                new DefaultIcingOptionsConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
         VisibilityDocument actualDocument1 = new VisibilityDocument(
@@ -159,6 +160,7 @@
                         .build();
         assertThat(actualDocument1).isEqualTo(expectedDocument1);
         assertThat(actualDocument2).isEqualTo(expectedDocument2);
+        appSearchImpl.close();
     }
 
     /** Build AppSearchImpl with deprecated visibility schemas version 0.     */
@@ -192,7 +194,7 @@
                 .build();
         // Set deprecated visibility schema version 0 into AppSearchImpl.
         AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                new DefaultIcingOptionsConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
         InternalSetSchemaResponse internalSetSchemaResponse = appSearchImpl.setSchema(
                 VisibilityStore.VISIBILITY_PACKAGE_NAME,
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
index 37d8fb6..0ca32c0 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
@@ -27,6 +27,7 @@
 import androidx.appsearch.app.SetSchemaRequest;
 import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.DefaultIcingOptionsConfig;
 import androidx.appsearch.localstorage.OptimizeStrategy;
 import androidx.appsearch.localstorage.UnlimitedLimitConfig;
 import androidx.appsearch.localstorage.util.PrefixUtil;
@@ -71,7 +72,7 @@
 
         // Create AppSearchImpl with visibility document version 1;
         AppSearchImpl appSearchImplInV1 = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                new DefaultIcingOptionsConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
         InternalSetSchemaResponse internalSetSchemaResponse = appSearchImplInV1.setSchema(
                 VisibilityStore.VISIBILITY_PACKAGE_NAME,
@@ -119,7 +120,7 @@
         // Persist to disk and re-open the AppSearchImpl
         appSearchImplInV1.close();
         AppSearchImpl appSearchImpl = AppSearchImpl.create(mFile, new UnlimitedLimitConfig(),
-                /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
+                new DefaultIcingOptionsConfig(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
 
         VisibilityDocument actualDocument = new VisibilityDocument(
@@ -140,5 +141,6 @@
                         ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR),
                         ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA),
                         ImmutableSet.of(SetSchemaRequest.READ_ASSISTANT_APP_SEARCH_DATA)));
+        appSearchImpl.close();
     }
 }
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
index 0a5364f..99a1ffe 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
@@ -26,6 +26,7 @@
 import androidx.appsearch.app.VisibilityDocument;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.localstorage.AppSearchImpl;
+import androidx.appsearch.localstorage.DefaultIcingOptionsConfig;
 import androidx.appsearch.localstorage.OptimizeStrategy;
 import androidx.appsearch.localstorage.UnlimitedLimitConfig;
 import androidx.appsearch.localstorage.util.PrefixUtil;
@@ -60,6 +61,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 mAppSearchDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 /*initStatsBuilder=*/ null,
                 ALWAYS_OPTIMIZE,
                 /*visibilityChecker=*/null);
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
index 2eba5ee..644fc10 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AlwaysSupportedFeatures.java
@@ -24,7 +24,7 @@
  * An implementation of {@link Features}. This implementation always returns true. This is
  * sufficient for the use in the local backend because all features are always available on the
  * local backend.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class AlwaysSupportedFeatures implements Features {
@@ -48,6 +48,8 @@
                 // fall through
             case Features.LIST_FILTER_QUERY_LANGUAGE:
                 // fall through
+            case Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA:
+                // fall through
             case Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH:
                 // fall through
             case Features.SEARCH_SPEC_PROPERTY_WEIGHTS:
@@ -55,6 +57,12 @@
             case Features.TOKENIZER_TYPE_RFC822:
                 // fall through
             case Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION:
+                // fall through
+            case Features.SEARCH_SUGGESTION:
+                // fall through
+            case Features.SCHEMA_SET_DELETION_PROPAGATION:
+                // fall through
+            case Features.SET_SCHEMA_CIRCULAR_REFERENCES:
                 return true;
             default:
                 return false;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
index f445af7..24c76ca 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
@@ -161,7 +161,7 @@
  *
  * <p>This class is thread safe.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @WorkerThread
@@ -182,6 +182,7 @@
     private final ReadWriteLock mReadWriteLock = new ReentrantReadWriteLock();
     private final OptimizeStrategy mOptimizeStrategy;
     private final LimitConfig mLimitConfig;
+    private final IcingOptionsConfig mIcingOptionsConfig;
 
     @GuardedBy("mReadWriteLock")
     @VisibleForTesting
@@ -268,12 +269,13 @@
     public static AppSearchImpl create(
             @NonNull File icingDir,
             @NonNull LimitConfig limitConfig,
+            @NonNull IcingOptionsConfig icingOptionsConfig,
             @Nullable InitializeStats.Builder initStatsBuilder,
             @NonNull OptimizeStrategy optimizeStrategy,
             @Nullable VisibilityChecker visibilityChecker)
             throws AppSearchException {
-        return new AppSearchImpl(icingDir, limitConfig, initStatsBuilder, optimizeStrategy,
-                visibilityChecker);
+        return new AppSearchImpl(icingDir, limitConfig, icingOptionsConfig, initStatsBuilder,
+                optimizeStrategy, visibilityChecker);
     }
 
     /**
@@ -282,12 +284,14 @@
     private AppSearchImpl(
             @NonNull File icingDir,
             @NonNull LimitConfig limitConfig,
+            @NonNull IcingOptionsConfig icingOptionsConfig,
             @Nullable InitializeStats.Builder initStatsBuilder,
             @NonNull OptimizeStrategy optimizeStrategy,
             @Nullable VisibilityChecker visibilityChecker)
             throws AppSearchException {
         Preconditions.checkNotNull(icingDir);
         mLimitConfig = Preconditions.checkNotNull(limitConfig);
+        mIcingOptionsConfig = Preconditions.checkNotNull(icingOptionsConfig);
         mOptimizeStrategy = Preconditions.checkNotNull(optimizeStrategy);
         mVisibilityCheckerLocked = visibilityChecker;
 
@@ -296,7 +300,19 @@
             // We synchronize here because we don't want to call IcingSearchEngine.initialize() more
             // than once. It's unnecessary and can be a costly operation.
             IcingSearchEngineOptions options = IcingSearchEngineOptions.newBuilder()
-                    .setBaseDir(icingDir.getAbsolutePath()).build();
+                    .setBaseDir(icingDir.getAbsolutePath())
+                    .setMaxTokenLength(icingOptionsConfig.getMaxTokenLength())
+                    .setIndexMergeSize(icingOptionsConfig.getIndexMergeSize())
+                    .setDocumentStoreNamespaceIdFingerprint(
+                            icingOptionsConfig.getDocumentStoreNamespaceIdFingerprint())
+                    .setOptimizeRebuildIndexThreshold(
+                            icingOptionsConfig.getOptimizeRebuildIndexThreshold())
+                    .setCompressionLevel(icingOptionsConfig.getCompressionLevel())
+                    .setAllowCircularSchemaDefinitions(
+                            icingOptionsConfig.getAllowCircularSchemaDefinitions())
+                    .setPreMappingFbv(icingOptionsConfig.getUsePreMappingWithFileBackedVector())
+                    .setUsePersistentHashMap(icingOptionsConfig.getUsePersistentHashMap())
+                    .build();
             LogUtil.piiTrace(TAG, "Constructing IcingSearchEngine, request", options);
             mIcingSearchEngineLocked = new IcingSearchEngine(options);
             LogUtil.piiTrace(
@@ -1327,7 +1343,8 @@
             String prefix = createPrefix(packageName, databaseName);
             SearchSpecToProtoConverter searchSpecToProtoConverter =
                     new SearchSpecToProtoConverter(queryExpression, searchSpec,
-                            Collections.singleton(prefix), mNamespaceMapLocked, mSchemaMapLocked);
+                            Collections.singleton(prefix), mNamespaceMapLocked, mSchemaMapLocked,
+                            mIcingOptionsConfig);
             if (searchSpecToProtoConverter.hasNothingToSearch()) {
                 // there is nothing to search over given their search filters, so we can return an
                 // empty SearchResult and skip sending request to Icing.
@@ -1409,7 +1426,7 @@
             }
             SearchSpecToProtoConverter searchSpecToProtoConverter =
                     new SearchSpecToProtoConverter(queryExpression, searchSpec, prefixFilters,
-                            mNamespaceMapLocked, mSchemaMapLocked);
+                            mNamespaceMapLocked, mSchemaMapLocked, mIcingOptionsConfig);
             // Remove those inaccessible schemas.
             searchSpecToProtoConverter.removeInaccessibleSchemaFilter(
                     callerAccess, mVisibilityStoreLocked, mVisibilityCheckerLocked);
@@ -1450,7 +1467,7 @@
         long rewriteSearchSpecLatencyStartMillis = SystemClock.elapsedRealtime();
         SearchSpecProto finalSearchSpec = searchSpecToProtoConverter.toSearchSpecProto();
         ResultSpecProto finalResultSpec = searchSpecToProtoConverter.toResultSpecProto(
-                mNamespaceMapLocked);
+                mNamespaceMapLocked, mSchemaMapLocked);
         ScoringSpecProto scoringSpec = searchSpecToProtoConverter.toScoringSpecProto();
         if (sStatsBuilder != null) {
             sStatsBuilder.setRewriteSearchSpecLatencyMillis((int)
@@ -1492,6 +1509,10 @@
                 TAG, "search, response", searchResultProto.getResultsCount(), searchResultProto);
         if (sStatsBuilder != null) {
             sStatsBuilder.setStatusCode(statusProtoToResultCode(searchResultProto.getStatus()));
+            if (searchSpec.hasJoinSpec()) {
+                sStatsBuilder.setJoinType(AppSearchSchema.StringPropertyConfig
+                        .JOINABLE_VALUE_TYPE_QUALIFIED_ID);
+            }
             AppSearchLoggerHelper.copyNativeStats(searchResultProto.getQueryStats(), sStatsBuilder);
         }
         checkSuccess(searchResultProto.getStatus());
@@ -1629,6 +1650,8 @@
 
             if (sStatsBuilder != null) {
                 sStatsBuilder.setStatusCode(statusProtoToResultCode(searchResultProto.getStatus()));
+                // Join query stats are handled by SearchResultsImpl, which has access to the
+                // original SearchSpec.
                 AppSearchLoggerHelper.copyNativeStats(searchResultProto.getQueryStats(),
                         sStatsBuilder);
             }
@@ -1868,7 +1891,8 @@
 
             SearchSpecToProtoConverter searchSpecToProtoConverter =
                     new SearchSpecToProtoConverter(queryExpression, searchSpec,
-                            Collections.singleton(prefix), mNamespaceMapLocked, mSchemaMapLocked);
+                            Collections.singleton(prefix), mNamespaceMapLocked, mSchemaMapLocked,
+                            mIcingOptionsConfig);
             if (searchSpecToProtoConverter.hasNothingToSearch()) {
                 // there is nothing to search over given their search filters, so we can return
                 // early and skip sending request to Icing.
@@ -2218,6 +2242,9 @@
         mReadWriteLock.writeLock().lock();
         try {
             throwIfClosedLocked();
+            if (LogUtil.DEBUG) {
+                Log.d(TAG, "Clear data for package: " + packageName);
+            }
             // TODO(b/193494000): We are calling getPackageToDatabases here and in several other
             //  places within AppSearchImpl. This method is not efficient and does a lot of string
             //  manipulation. We should find a way to cache the package to database map so it can
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLogger.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLogger.java
index 724f05a..3e9e739 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLogger.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLogger.java
@@ -35,7 +35,7 @@
  *
  * <p>All implementations of this interface must be thread safe.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public interface AppSearchLogger {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLoggerHelper.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLoggerHelper.java
index 4772afe..6fb135a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLoggerHelper.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchLoggerHelper.java
@@ -39,7 +39,7 @@
  *
  * <p>E.g. we need to have helper functions to copy numbers from IcingLib to stats classes.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class AppSearchLoggerHelper {
@@ -130,7 +130,10 @@
                 .setJavaToNativeJniLatencyMillis(
                         fromNativeStats.getJavaToNativeJniLatencyMs())
                 .setNativeToJavaJniLatencyMillis(
-                        fromNativeStats.getNativeToJavaJniLatencyMs());
+                        fromNativeStats.getNativeToJavaJniLatencyMs())
+                .setNativeNumJoinedResultsCurrentPage(
+                        fromNativeStats.getNumJoinedResultsReturnedCurrentPage())
+                .setNativeJoinLatencyMillis(fromNativeStats.getJoinLatencyMs());
     }
 
     /**
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java
new file mode 100644
index 0000000..9de05a6
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/DefaultIcingOptionsConfig.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+// @exportToFramework:copyToPath(testing/testutils/src/android/app/appsearch/testutil/external/DefaultIcingOptionsConfig.java)
+package androidx.appsearch.localstorage;
+
+import androidx.annotation.RestrictTo;
+
+/**
+ * Icing options for AppSearch local-storage. Note, these values are not necessarily the defaults
+ * set in {@link com.google.android.icing.proto.IcingSearchEngineOptions} proto.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class DefaultIcingOptionsConfig implements IcingOptionsConfig {
+    @Override
+    public int getMaxTokenLength() {
+        return DEFAULT_MAX_TOKEN_LENGTH;
+    }
+
+    @Override
+    public int getIndexMergeSize() {
+        return DEFAULT_INDEX_MERGE_SIZE;
+    }
+
+    @Override
+    public boolean getDocumentStoreNamespaceIdFingerprint() {
+        return true;
+    }
+
+    @Override
+    public float getOptimizeRebuildIndexThreshold() {
+        return 0.9f;
+    }
+
+    @Override
+    public int getCompressionLevel() {
+        return DEFAULT_COMPRESSION_LEVEL;
+    }
+
+    @Override
+    public boolean getAllowCircularSchemaDefinitions() {
+        return true;
+    }
+
+    @Override
+    public boolean getUseReadOnlySearch() {
+        return true;
+    }
+
+    @Override
+    public boolean getUsePreMappingWithFileBackedVector() {
+        return false;
+    }
+
+    @Override
+    public boolean getUsePersistentHashMap() {
+        return true;
+    }
+
+    @Override
+    public int getMaxPageBytesLimit() {
+        return DEFAULT_MAX_PAGE_BYTES_LIMIT;
+    }
+
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
new file mode 100644
index 0000000..56b097d
--- /dev/null
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/IcingOptionsConfig.java
@@ -0,0 +1,153 @@
+/*
+ * 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.appsearch.localstorage;
+
+import android.app.appsearch.SearchSpec;
+
+import androidx.annotation.RestrictTo;
+
+import com.google.android.icing.proto.IcingSearchEngineOptions;
+
+/**
+ * An interface exposing the optional config flags in {@link IcingSearchEngineOptions} used to
+ * instantiate {@link com.google.android.icing.IcingSearchEngine}, as well as other additional
+ * config flags for IcingSearchEngine.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public interface IcingOptionsConfig {
+    // Defaults from IcingSearchEngineOptions proto
+    int DEFAULT_MAX_TOKEN_LENGTH = 30;
+
+    int DEFAULT_INDEX_MERGE_SIZE = 1048576; // 1 MiB
+
+    boolean DEFAULT_DOCUMENT_STORE_NAMESPACE_ID_FINGERPRINT = false;
+
+    float DEFAULT_OPTIMIZE_REBUILD_INDEX_THRESHOLD = 0.0f;
+
+    /**
+     * The default compression level in IcingSearchEngineOptions proto matches the
+     * previously-hardcoded document compression level in Icing (which is 3).
+     */
+    int DEFAULT_COMPRESSION_LEVEL = 3;
+
+    boolean DEFAULT_USE_PREMAPPING_WITH_FILE_BACKED_VECTOR = false;
+
+    boolean DEFAULT_USE_PERSISTENT_HASH_MAP = false;
+
+    int DEFAULT_MAX_PAGE_BYTES_LIMIT = Integer.MAX_VALUE;
+
+    /**
+     * The maximum allowable token length. All tokens in excess of this size will be truncated to
+     * max_token_length before being indexed.
+     *
+     * <p>Clients may use this option to prevent unnecessary indexing of long tokens.
+     * Depending on the use case, indexing all of
+     * 'Supercalifragilisticexpialidocious' may be unnecessary - a user is
+     * unlikely to type that entire query. So only indexing the first n bytes may
+     * still provide the desired behavior without wasting resources.
+     */
+    int getMaxTokenLength();
+
+    /**
+     * The size (measured in bytes) at which Icing's internal indices should be
+     * merged. Icing buffers changes together before merging them into a more
+     * compact format. When the buffer exceeds index_merge_size during a Put
+     * operation, the buffer is merged into the larger, more compact index.
+     *
+     * <p>This more compact index is more efficient to search over as the index
+     * grows larger and has smaller system health impact.
+     *
+     * <p>Setting a low index_merge_size increases the frequency of merges -
+     * increasing indexing-time latency and flash wear. Setting a high
+     * index_merge_size leads to larger resource usage and higher query latency.
+     */
+    int getIndexMergeSize();
+
+    /**
+     * Whether to use namespace id or namespace name to build up fingerprint for
+     * document_key_mapper_ and corpus_mapper_ in document store.
+     */
+    boolean getDocumentStoreNamespaceIdFingerprint();
+
+    /**
+     * The threshold of the percentage of invalid documents at which to rebuild index
+     * during optimize.
+     *
+     * <p>We rebuild index if and only if |invalid_documents| / |all_documents| >= threshold.
+     *
+     * <p>Rebuilding the index could be faster than optimizing the index if we have
+     * removed most of the documents. Based on benchmarks, 85%~95% seems to be a good threshold
+     * for most cases.
+     */
+    float getOptimizeRebuildIndexThreshold();
+
+    /**
+     * The level of gzip compression for documents in the Icing document store.
+     *
+     * <p>NO_COMPRESSION = 0, BEST_SPEED = 1, BEST_COMPRESSION = 9
+     */
+    int getCompressionLevel();
+
+    /**
+     * Whether to allow circular references between schema types for the schema definition.
+     *
+     * <p>Even when set to true, circular references are still not allowed in the following cases:
+     *   1. All edges of a cycle have index_nested_properties=true
+     *   2. One of the types in the cycle has a joinable property, or depends on a type with a
+     *   joinable property.
+     */
+    boolean getAllowCircularSchemaDefinitions();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.SearchSpecProto}.
+     *
+     * <p>Whether to use the read-only implementation of IcingSearchEngine::Search.
+     *
+     * <p>The read-only version enables multiple queries to be performed concurrently
+     * as it only acquires the read lock at IcingSearchEngine's level. Finer-grained locks are
+     * implemented around code paths that write changes to Icing during Search.
+     */
+    boolean getUseReadOnlySearch();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.IcingSearchEngineOptions}.
+     *
+     * <p>Whether or not to pre-map the potential memory region used by the PersistentHashMap.
+     * This will avoid the need to re-map the mmapping used by PersistentHashMap whenever the
+     * underlying storage grows.
+     */
+    boolean getUsePreMappingWithFileBackedVector();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.IcingSearchEngineOptions}.
+     *
+     * <p>Whether or not to use the PersistentHashMap in the QualifiedIdTypeJoinableIndex. If false,
+     * we will use the old IcingDynamicTrie to store key value pairs.
+     */
+    boolean getUsePersistentHashMap();
+
+    /**
+     * Flag for {@link com.google.android.icing.proto.ResultSpecProto}.
+     *
+     * <p>The maximum byte size to allow in a single page. This limit is only loosely binding.
+     * AppSearch will add results to the page until either 1) AppSearch has retrieved
+     * {@link SearchSpec#getResultCountPerPage()} results or 2) total size of the page exceeds this
+     * value. Therefore, AppSearch will always retrieve at least a single result, even if that
+     * result exceeds this limit.
+     */
+    int getMaxPageBytesLimit();
+}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/JetpackOptimizeStrategy.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/JetpackOptimizeStrategy.java
index 6c0ee68..d64f233 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/JetpackOptimizeStrategy.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/JetpackOptimizeStrategy.java
@@ -26,10 +26,10 @@
  * An implementation of {@link androidx.appsearch.localstorage.OptimizeStrategy} will
  * determine when to trigger {@link androidx.appsearch.localstorage.AppSearchImpl#optimize()} in
  * Jetpack environment.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public class JetpackOptimizeStrategy implements OptimizeStrategy{
+public class JetpackOptimizeStrategy implements OptimizeStrategy {
 
     @VisibleForTesting
     static final int DOC_COUNT_OPTIMIZE_THRESHOLD = 1000;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LimitConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LimitConfig.java
index b53e12a..ed74481 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LimitConfig.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LimitConfig.java
@@ -20,7 +20,7 @@
 
 /**
  * Defines limits placed on users of AppSearch and enforced by {@link AppSearchImpl}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public interface LimitConfig {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
index b862ce3..86c825a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/LocalStorage.java
@@ -147,7 +147,7 @@
              * <p>If no logger is provided, nothing would be returned/logged. There is no default
              * logger implementation in AppSearch.
              *
-             * @hide
+             * @exportToFramework:hide
              */
             @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
             @NonNull
@@ -227,7 +227,7 @@
              * <p>If no logger is provided, nothing would be returned/logged. There is no default
              * logger implementation in AppSearch.
              *
-             * @hide
+             * @exportToFramework:hide
              */
             @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
             @NonNull
@@ -340,6 +340,7 @@
         mAppSearchImpl = AppSearchImpl.create(
                 icingDir,
                 new UnlimitedLimitConfig(),
+                new DefaultIcingOptionsConfig(),
                 initStatsBuilder,
                 new JetpackOptimizeStrategy(),
                 /*visibilityChecker=*/null);
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
index c25be25..bf6306b 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/ObserverManager.java
@@ -49,7 +49,7 @@
  *
  * <p>This class is thread-safe.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class ObserverManager {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/OptimizeStrategy.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/OptimizeStrategy.java
index 962dc6b..6b1ab7e 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/OptimizeStrategy.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/OptimizeStrategy.java
@@ -24,7 +24,7 @@
 /**
  * An interface class for implementing a strategy to determine when to trigger
  * {@link AppSearchImpl#optimize()}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public interface OptimizeStrategy {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
index 8da40bb..11b4813 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/SearchResultsImpl.java
@@ -18,6 +18,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.SearchResult;
 import androidx.appsearch.app.SearchResultPage;
 import androidx.appsearch.app.SearchResults;
@@ -114,6 +115,11 @@
                 searchResultPage = mAppSearchImpl.getNextPage(mPackageName, mNextPageToken,
                         sStatsBuilder);
                 if (mLogger != null && sStatsBuilder != null) {
+                    if (mSearchSpec.getJoinSpec() != null
+                            && !mSearchSpec.getJoinSpec().getChildPropertyExpression().isEmpty()) {
+                        sStatsBuilder.setJoinType(AppSearchSchema.StringPropertyConfig
+                                .JOINABLE_VALUE_TYPE_QUALIFIED_ID);
+                    }
                     mLogger.logStats(sStatsBuilder.build());
                 }
             }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/UnlimitedLimitConfig.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/UnlimitedLimitConfig.java
index b4f37fa..a402969 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/UnlimitedLimitConfig.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/UnlimitedLimitConfig.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+// @exportToFramework:copyToPath(testing/testutils/src/android/app/appsearch/testutil/external/UnlimitedLimitConfig.java)
 package androidx.appsearch.localstorage;
 
 import androidx.annotation.RestrictTo;
@@ -22,7 +22,6 @@
  * In Jetpack, AppSearch doesn't enforce artificial limits on number of documents or size of
  * documents, since the app is the only user of the Icing instance. Icing still enforces a docid
  * limit of 1M docs.
- * @hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class UnlimitedLimitConfig implements LimitConfig {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
index c6731d1..e6a7506 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/GenericDocumentToProtoConverter.java
@@ -35,7 +35,7 @@
 /**
  * Translates a {@link GenericDocument} into a {@link DocumentProto}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class GenericDocumentToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/ResultCodeToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/ResultCodeToProtoConverter.java
index e04d756..2106917 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/ResultCodeToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/ResultCodeToProtoConverter.java
@@ -26,7 +26,7 @@
 
 /**
  * Translates an {@link StatusProto.Code} into a {@link AppSearchResult.ResultCode}
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class ResultCodeToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverter.java
index b22d33f..0e64163 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SchemaToProtoConverter.java
@@ -36,7 +36,7 @@
 
 /**
  * Translates an {@link AppSearchSchema} into a {@link SchemaTypeConfigProto}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SchemaToProtoConverter {
@@ -99,6 +99,7 @@
                         .setValueType(
                                 convertJoinableValueTypeToProto(
                                         stringProperty.getJoinableValueType()))
+                        .setPropagateDelete(stringProperty.getDeletionPropagation())
                         .build();
                 builder.setJoinableConfig(joinableConfig);
             }
@@ -188,6 +189,7 @@
                         .setJoinableValueType(
                                 convertJoinableValueTypeFromProto(
                                         proto.getJoinableConfig().getValueType()))
+                        .setDeletionPropagation(proto.getJoinableConfig().getPropagateDelete())
                         .setTokenizerType(
                                 proto.getStringIndexingConfig().getTokenizerType().getNumber());
 
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
index 7a2d909..b26954b 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchResultToProtoConverter.java
@@ -43,7 +43,7 @@
 /**
  * Translates a {@link SearchResultProto} into {@link SearchResult}s.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class SearchResultToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
index 0e80ebe..a8ba0d3 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverter.java
@@ -18,6 +18,7 @@
 
 import static androidx.appsearch.localstorage.util.PrefixUtil.createPrefix;
 import static androidx.appsearch.localstorage.util.PrefixUtil.getPackageName;
+import static androidx.appsearch.localstorage.util.PrefixUtil.getPrefix;
 import static androidx.appsearch.localstorage.util.PrefixUtil.removePrefix;
 
 import android.util.Log;
@@ -26,8 +27,10 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.appsearch.app.JoinSpec;
+import androidx.appsearch.app.SearchResult;
 import androidx.appsearch.app.SearchSpec;
 import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.localstorage.IcingOptionsConfig;
 import androidx.appsearch.localstorage.visibilitystore.CallerAccess;
 import androidx.appsearch.localstorage.visibilitystore.VisibilityChecker;
 import androidx.appsearch.localstorage.visibilitystore.VisibilityStore;
@@ -55,7 +58,7 @@
 /**
  * Translates a {@link SearchSpec} into icing search protos.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SearchSpecToProtoConverter {
@@ -79,6 +82,7 @@
      * filters which are stored in AppSearch. This is a field so that we can generate nested protos.
      */
     private final Map<String, Set<String>> mNamespaceMap;
+
     /**
      *The cached Map of {@code <Prefix, Map<PrefixedSchemaType, schemaProto>>} stores all
      * prefixed schema filters which are stored inAppSearch. This is a field so that we can
@@ -87,6 +91,18 @@
     private final Map<String, Map<String, SchemaTypeConfigProto>> mSchemaMap;
 
     /**
+     * Optional config flags in {@link SearchSpecProto}.
+     */
+    private final IcingOptionsConfig mIcingOptionsConfig;
+
+    /**
+     * The nested converter, which contains SearchSpec, ResultSpec, and ScoringSpec information
+     * about the nested query. This will remain null if there is no nested {@link JoinSpec}.
+     */
+    @Nullable
+    private SearchSpecToProtoConverter mNestedConverter = null;
+
+    /**
      * Creates a {@link SearchSpecToProtoConverter} for given {@link SearchSpec}.
      *
      * @param queryExpression                Query String to search.
@@ -102,12 +118,14 @@
             @NonNull SearchSpec searchSpec,
             @NonNull Set<String> prefixes,
             @NonNull Map<String, Set<String>> namespaceMap,
-            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap) {
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap,
+            @NonNull IcingOptionsConfig icingOptionsConfig) {
         mQueryExpression = Preconditions.checkNotNull(queryExpression);
         mSearchSpec = Preconditions.checkNotNull(searchSpec);
         mPrefixes = Preconditions.checkNotNull(prefixes);
         mNamespaceMap = Preconditions.checkNotNull(namespaceMap);
         mSchemaMap = Preconditions.checkNotNull(schemaMap);
+        mIcingOptionsConfig = Preconditions.checkNotNull(icingOptionsConfig);
         mTargetPrefixedNamespaceFilters =
                 SearchSpecToProtoConverterUtil.generateTargetNamespaceFilters(
                         prefixes, namespaceMap, searchSpec.getFilterNamespaces());
@@ -120,11 +138,28 @@
         } else {
             mTargetPrefixedSchemaFilters = new ArraySet<>();
         }
+
+        JoinSpec joinSpec = searchSpec.getJoinSpec();
+        if (joinSpec == null) {
+            return;
+        }
+
+        mNestedConverter = new SearchSpecToProtoConverter(
+                joinSpec.getNestedQuery(),
+                joinSpec.getNestedSearchSpec(),
+                mPrefixes,
+                namespaceMap,
+                schemaMap,
+                mIcingOptionsConfig);
     }
 
     /**
      * @return whether this search's target filters are empty. If any target filter is empty, we
      * should skip send request to Icing.
+     *
+     * <p> The nestedConverter is not checked as {@link SearchResult}s from the nested query have
+     * to be joined to a {@link SearchResult} from the parent query. If the parent query has
+     * nothing to search, then so does the child query.
      */
     public boolean hasNothingToSearch() {
         return mTargetPrefixedNamespaceFilters.isEmpty() || mTargetPrefixedSchemaFilters.isEmpty();
@@ -146,23 +181,68 @@
             @NonNull CallerAccess callerAccess,
             @Nullable VisibilityStore visibilityStore,
             @Nullable VisibilityChecker visibilityChecker) {
+        removeInaccessibleSchemaFilterCached(callerAccess, visibilityStore,
+                /*inaccessibleSchemaPrefixes=*/new ArraySet<>(),
+                /*accessibleSchemaPrefixes=*/new ArraySet<>(), visibilityChecker);
+    }
+
+    /**
+     * For each target schema, we will check visibility store is that accessible to the caller. And
+     * remove this schemas if it is not allowed for caller to query. This private version accepts
+     * two additional parameters to minimize the amount of calls to
+     * {@link VisibilityUtil#isSchemaSearchableByCaller}.
+     *
+     * @param callerAccess      Visibility access info of the calling app
+     * @param visibilityStore   The {@link VisibilityStore} that store all visibility
+     *                          information.
+     * @param visibilityChecker Optional visibility checker to check whether the caller
+     *                          could access target schemas. Pass {@code null} will
+     *                          reject access for all documents which doesn't belong
+     *                          to the calling package.
+     * @param inaccessibleSchemaPrefixes A set of schemas that are known to be inaccessible. This
+     *                                  is helpful for reducing duplicate calls to
+     *                                  {@link VisibilityUtil}.
+     * @param accessibleSchemaPrefixes A set of schemas that are known to be accessible. This is
+     *                                 helpful for reducing duplicate calls to
+     *                                 {@link VisibilityUtil}.
+     */
+    private void removeInaccessibleSchemaFilterCached(
+            @NonNull CallerAccess callerAccess,
+            @Nullable VisibilityStore visibilityStore,
+            @NonNull Set<String> inaccessibleSchemaPrefixes,
+            @NonNull Set<String> accessibleSchemaPrefixes,
+            @Nullable VisibilityChecker visibilityChecker) {
         Iterator<String> targetPrefixedSchemaFilterIterator =
                 mTargetPrefixedSchemaFilters.iterator();
         while (targetPrefixedSchemaFilterIterator.hasNext()) {
             String targetPrefixedSchemaFilter = targetPrefixedSchemaFilterIterator.next();
             String packageName = getPackageName(targetPrefixedSchemaFilter);
 
-            if (!VisibilityUtil.isSchemaSearchableByCaller(
+            if (accessibleSchemaPrefixes.contains(targetPrefixedSchemaFilter)) {
+                continue;
+            } else if (inaccessibleSchemaPrefixes.contains(targetPrefixedSchemaFilter)) {
+                targetPrefixedSchemaFilterIterator.remove();
+            } else if (!VisibilityUtil.isSchemaSearchableByCaller(
                     callerAccess,
                     packageName,
                     targetPrefixedSchemaFilter,
                     visibilityStore,
                     visibilityChecker)) {
                 targetPrefixedSchemaFilterIterator.remove();
+                inaccessibleSchemaPrefixes.add(targetPrefixedSchemaFilter);
+            } else {
+                accessibleSchemaPrefixes.add(targetPrefixedSchemaFilter);
             }
         }
+
+        if (mNestedConverter != null) {
+            mNestedConverter.removeInaccessibleSchemaFilterCached(
+                    callerAccess, visibilityStore, inaccessibleSchemaPrefixes,
+                    accessibleSchemaPrefixes, visibilityChecker);
+        }
     }
 
+
     /** Extracts {@link SearchSpecProto} information from a {@link SearchSpec}. */
     @NonNull
     public SearchSpecProto toSearchSpecProto() {
@@ -172,7 +252,8 @@
         SearchSpecProto.Builder protoBuilder = SearchSpecProto.newBuilder()
                 .setQuery(mQueryExpression)
                 .addAllNamespaceFilters(mTargetPrefixedNamespaceFilters)
-                .addAllSchemaTypeFilters(mTargetPrefixedSchemaFilters);
+                .addAllSchemaTypeFilters(mTargetPrefixedSchemaFilters)
+                .setUseReadOnlySearch(mIcingOptionsConfig.getUseReadOnlySearch());
 
         @SearchSpec.TermMatch int termMatchCode = mSearchSpec.getTermMatch();
         TermMatchType.Code termMatchCodeProto = TermMatchType.Code.forNumber(termMatchCode);
@@ -181,25 +262,25 @@
         }
         protoBuilder.setTermMatchType(termMatchCodeProto);
 
-        JoinSpec joinSpec = mSearchSpec.getJoinSpec();
-        if (joinSpec != null) {
-            SearchSpecToProtoConverter nestedConverter = new SearchSpecToProtoConverter(
-                    joinSpec.getNestedQuery(), joinSpec.getNestedSearchSpec(), mPrefixes,
-                    mNamespaceMap, mSchemaMap);
+        if (mNestedConverter != null && !mNestedConverter.hasNothingToSearch()) {
+            JoinSpecProto.NestedSpecProto nestedSpec =
+                    JoinSpecProto.NestedSpecProto.newBuilder()
+                            .setResultSpec(mNestedConverter.toResultSpecProto(
+                                    mNamespaceMap, mSchemaMap))
+                            .setScoringSpec(mNestedConverter.toScoringSpecProto())
+                            .setSearchSpec(mNestedConverter.toSearchSpecProto())
+                            .build();
 
-            JoinSpecProto.NestedSpecProto nestedSpec = JoinSpecProto.NestedSpecProto.newBuilder()
-                    .setResultSpec(nestedConverter.toResultSpecProto(mNamespaceMap))
-                    .setScoringSpec(nestedConverter.toScoringSpecProto())
-                    .setSearchSpec(nestedConverter.toSearchSpecProto())
-                    .build();
-
-            JoinSpecProto.Builder joinSpecProtoBuilder = JoinSpecProto.newBuilder()
-                    .setNestedSpec(nestedSpec)
-                    .setParentPropertyExpression(JoinSpec.QUALIFIED_ID)
-                    .setChildPropertyExpression(joinSpec.getChildPropertyExpression())
-                    .setAggregationScoringStrategy(
-                            toAggregationScoringStrategy(joinSpec.getAggregationScoringStrategy()))
-                    .setMaxJoinedChildCount(joinSpec.getMaxJoinedResultCount());
+            // This cannot be null, otherwise mNestedConverter would be null as well.
+            JoinSpec joinSpec = mSearchSpec.getJoinSpec();
+            JoinSpecProto.Builder joinSpecProtoBuilder =
+                    JoinSpecProto.newBuilder()
+                            .setNestedSpec(nestedSpec)
+                            .setParentPropertyExpression(JoinSpec.QUALIFIED_ID)
+                            .setChildPropertyExpression(joinSpec.getChildPropertyExpression())
+                            .setAggregationScoringStrategy(
+                                    toAggregationScoringStrategy(
+                                            joinSpec.getAggregationScoringStrategy()));
 
             protoBuilder.setJoinSpec(joinSpecProtoBuilder);
         }
@@ -252,17 +333,27 @@
      *
      * @param namespaceMap    The cached Map of {@code <Prefix, Set<PrefixedNamespace>>} stores
      *                        all existing prefixed namespace.
+     * @param schemaMap       The cached Map of {@code <Prefix, Map<PrefixedSchemaType,
+     *                        schemaProto>>} stores all prefixed schema filters which are stored
+     *                        inAppSearch.
      */
     @NonNull
     public ResultSpecProto toResultSpecProto(
-            @NonNull Map<String, Set<String>> namespaceMap) {
+            @NonNull Map<String, Set<String>> namespaceMap,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap) {
         ResultSpecProto.Builder resultSpecBuilder = ResultSpecProto.newBuilder()
                 .setNumPerPage(mSearchSpec.getResultCountPerPage())
                 .setSnippetSpec(
                         ResultSpecProto.SnippetSpecProto.newBuilder()
                                 .setNumToSnippet(mSearchSpec.getSnippetCount())
                                 .setNumMatchesPerProperty(mSearchSpec.getSnippetCountPerProperty())
-                                .setMaxWindowUtf32Length(mSearchSpec.getMaxSnippetSize()));
+                                .setMaxWindowUtf32Length(mSearchSpec.getMaxSnippetSize()))
+                .setNumTotalBytesPerPageThreshold(mIcingOptionsConfig.getMaxPageBytesLimit());
+        JoinSpec joinSpec = mSearchSpec.getJoinSpec();
+        if (joinSpec != null) {
+            resultSpecBuilder.setMaxJoinedChildrenPerParentToReturn(
+                    joinSpec.getMaxJoinedResultCount());
+        }
 
         // Rewrites the typePropertyMasks that exist in {@code prefixes}.
         int groupingType = mSearchSpec.getResultGroupingTypeFlags();
@@ -279,12 +370,36 @@
                         namespaceMap, resultSpecBuilder);
                 resultGroupingType = ResultSpecProto.ResultGroupingType.NAMESPACE;
                 break;
+            case SearchSpec.GROUPING_TYPE_PER_SCHEMA:
+                addPerSchemaResultGrouping(mPrefixes, mSearchSpec.getResultGroupingLimit(),
+                        schemaMap, resultSpecBuilder);
+                resultGroupingType = ResultSpecProto.ResultGroupingType.SCHEMA_TYPE;
+                break;
             case SearchSpec.GROUPING_TYPE_PER_PACKAGE | SearchSpec.GROUPING_TYPE_PER_NAMESPACE:
                 addPerPackagePerNamespaceResultGroupings(mPrefixes,
                         mSearchSpec.getResultGroupingLimit(),
                         namespaceMap, resultSpecBuilder);
                 resultGroupingType = ResultSpecProto.ResultGroupingType.NAMESPACE;
                 break;
+            case SearchSpec.GROUPING_TYPE_PER_PACKAGE | SearchSpec.GROUPING_TYPE_PER_SCHEMA:
+                addPerPackagePerSchemaResultGroupings(mPrefixes,
+                        mSearchSpec.getResultGroupingLimit(),
+                        schemaMap, resultSpecBuilder);
+                resultGroupingType = ResultSpecProto.ResultGroupingType.SCHEMA_TYPE;
+                break;
+            case SearchSpec.GROUPING_TYPE_PER_NAMESPACE | SearchSpec.GROUPING_TYPE_PER_SCHEMA:
+                addPerNamespaceAndSchemaResultGrouping(mPrefixes,
+                        mSearchSpec.getResultGroupingLimit(),
+                        namespaceMap, schemaMap, resultSpecBuilder);
+                resultGroupingType = ResultSpecProto.ResultGroupingType.NAMESPACE_AND_SCHEMA_TYPE;
+                break;
+            case SearchSpec.GROUPING_TYPE_PER_PACKAGE | SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                | SearchSpec.GROUPING_TYPE_PER_SCHEMA:
+                addPerPackagePerNamespacePerSchemaResultGrouping(mPrefixes,
+                        mSearchSpec.getResultGroupingLimit(),
+                        namespaceMap, schemaMap, resultSpecBuilder);
+                resultGroupingType = ResultSpecProto.ResultGroupingType.NAMESPACE_AND_SCHEMA_TYPE;
+                break;
             default:
                 break;
         }
@@ -363,21 +478,54 @@
     }
 
     /**
-     * Adds result groupings for each namespace in each package being queried for.
+     * Returns a Map of namespace to prefixedNamespaces. This is NOT necessarily the
+     * same as the list of namespaces. If a namespace exists under different packages and/or
+     * different databases, they should still be grouped together.
      *
-     * @param prefixes          Prefixes that we should prepend to all our filters
-     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param prefixes          Prefixes that we should prepend to all our filters.
      * @param namespaceMap      The namespace map contains all prefixed existing namespaces.
-     * @param resultSpecBuilder ResultSpecs as specified by client
      */
-    private static void addPerPackagePerNamespaceResultGroupings(
+    private static Map<String, List<String>> getNamespaceToPrefixedNamespaces(
             @NonNull Set<String> prefixes,
-            int maxNumResults,
-            @NonNull Map<String, Set<String>> namespaceMap,
-            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
-        // Create a map for package+namespace to prefixedNamespaces. This is NOT necessarily the
-        // same as the list of namespaces. If one package has multiple databases, each with the same
-        // namespace, then those should be grouped together.
+            @NonNull Map<String, Set<String>> namespaceMap) {
+        Map<String, List<String>> namespaceToPrefixedNamespaces = new ArrayMap<>();
+        for (String prefix : prefixes) {
+            Set<String> prefixedNamespaces = namespaceMap.get(prefix);
+            if (prefixedNamespaces == null) {
+                continue;
+            }
+            for (String prefixedNamespace : prefixedNamespaces) {
+                String namespace;
+                try {
+                    namespace = removePrefix(prefixedNamespace);
+                } catch (AppSearchException e) {
+                    // This should never happen. Skip this namespace if it does.
+                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
+                    continue;
+                }
+                List<String> groupedPrefixedNamespaces =
+                        namespaceToPrefixedNamespaces.get(namespace);
+                if (groupedPrefixedNamespaces == null) {
+                    groupedPrefixedNamespaces = new ArrayList<>();
+                    namespaceToPrefixedNamespaces.put(namespace, groupedPrefixedNamespaces);
+                }
+                groupedPrefixedNamespaces.add(prefixedNamespace);
+            }
+        }
+        return namespaceToPrefixedNamespaces;
+    }
+
+    /**
+     * Returns a map for package+namespace to prefixedNamespaces. This is NOT necessarily the
+     * same as the list of namespaces. If one package has multiple databases, each with the same
+     * namespace, then those should be grouped together.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters.
+     * @param namespaceMap      The namespace map contains all prefixed existing namespaces.
+     */
+    private static Map<String, List<String>> getPackageAndNamespaceToPrefixedNamespaces(
+            @NonNull Set<String> prefixes,
+            @NonNull Map<String, Set<String>> namespaceMap) {
         Map<String, List<String>> packageAndNamespaceToNamespaces = new ArrayMap<>();
         for (String prefix : prefixes) {
             Set<String> prefixedNamespaces = namespaceMap.get(prefix);
@@ -408,14 +556,113 @@
                 namespaceList.add(prefixedNamespace);
             }
         }
+        return packageAndNamespaceToNamespaces;
+    }
+
+    /**
+     * Returns a map of schema to prefixedSchemas. This is NOT necessarily the
+     * same as the list of schemas. If a schema exists under different packages and/or
+     * different databases, they should still be grouped together.
+     *
+     * @param prefixes      Prefixes that we should prepend to all our filters.
+     * @param schemaMap     The schema map contains all prefixed existing schema types.
+     */
+    private static Map<String, List<String>> getSchemaToPrefixedSchemas(
+            @NonNull Set<String> prefixes,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap) {
+        Map<String, List<String>> schemaToPrefixedSchemas = new ArrayMap<>();
+        for (String prefix : prefixes) {
+            Map<String, SchemaTypeConfigProto> prefixedSchemas = schemaMap.get(prefix);
+            if (prefixedSchemas == null) {
+                continue;
+            }
+            for (String prefixedSchema : prefixedSchemas.keySet()) {
+                String schema;
+                try {
+                    schema = removePrefix(prefixedSchema);
+                } catch (AppSearchException e) {
+                    // This should never happen. Skip this schema if it does.
+                    Log.e(TAG, "Prefixed schema " + prefixedSchema + " is malformed.");
+                    continue;
+                }
+                List<String> groupedPrefixedSchemas =
+                        schemaToPrefixedSchemas.get(schema);
+                if (groupedPrefixedSchemas == null) {
+                    groupedPrefixedSchemas = new ArrayList<>();
+                    schemaToPrefixedSchemas.put(schema, groupedPrefixedSchemas);
+                }
+                groupedPrefixedSchemas.add(prefixedSchema);
+            }
+        }
+        return schemaToPrefixedSchemas;
+    }
+
+    /**
+     * Returns a map for package+schema to prefixedSchemas. This is NOT necessarily the
+     * same as the list of schemas. If one package has multiple databases, each with the same
+     * schema, then those should be grouped together.
+     *
+     * @param prefixes      Prefixes that we should prepend to all our filters.
+     * @param schemaMap     The schema map contains all prefixed existing schema types.
+     */
+    private static Map<String, List<String>> getPackageAndSchemaToPrefixedSchemas(
+            @NonNull Set<String> prefixes,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap) {
+        Map<String, List<String>> packageAndSchemaToSchemas = new ArrayMap<>();
+        for (String prefix : prefixes) {
+            Map<String, SchemaTypeConfigProto> prefixedSchemas = schemaMap.get(prefix);
+            if (prefixedSchemas == null) {
+                continue;
+            }
+            String packageName = getPackageName(prefix);
+            // Create a new prefix without the database name. This will allow us to group schemas
+            // that have the same name and package but a different database name together.
+            String emptyDatabasePrefix = createPrefix(packageName, /*database*/"");
+            for (String prefixedSchema : prefixedSchemas.keySet()) {
+                String schema;
+                try {
+                    schema = removePrefix(prefixedSchema);
+                } catch (AppSearchException e) {
+                    // This should never happen. Skip this schema if it does.
+                    Log.e(TAG, "Prefixed schema " + prefixedSchema + " is malformed.");
+                    continue;
+                }
+                String emptyDatabasePrefixedSchema = emptyDatabasePrefix + schema;
+                List<String> schemaList =
+                        packageAndSchemaToSchemas.get(emptyDatabasePrefixedSchema);
+                if (schemaList == null) {
+                    schemaList = new ArrayList<>();
+                    packageAndSchemaToSchemas.put(emptyDatabasePrefixedSchema, schemaList);
+                }
+                schemaList.add(prefixedSchema);
+            }
+        }
+        return packageAndSchemaToSchemas;
+    }
+
+    /**
+     * Adds result groupings for each namespace in each package being queried for.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters
+     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param namespaceMap      The namespace map contains all prefixed existing namespaces.
+     * @param resultSpecBuilder ResultSpecs as specified by client
+     */
+    private static void addPerPackagePerNamespaceResultGroupings(
+            @NonNull Set<String> prefixes,
+            int maxNumResults,
+            @NonNull Map<String, Set<String>> namespaceMap,
+            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
+        Map<String, List<String>> packageAndNamespaceToNamespaces =
+                getPackageAndNamespaceToPrefixedNamespaces(prefixes, namespaceMap);
 
         for (List<String> prefixedNamespaces : packageAndNamespaceToNamespaces.values()) {
             List<ResultSpecProto.ResultGrouping.Entry> entries =
                     new ArrayList<>(prefixedNamespaces.size());
-            for (String namespace : prefixedNamespaces) {
+            for (int i = 0; i < prefixedNamespaces.size(); i++) {
                 entries.add(
                         ResultSpecProto.ResultGrouping.Entry.newBuilder()
-                                .setNamespace(namespace).build());
+                            .setNamespace(prefixedNamespaces.get(i)).build());
             }
             resultSpecBuilder.addResultGroupings(
                     ResultSpecProto.ResultGrouping.newBuilder()
@@ -424,6 +671,84 @@
     }
 
     /**
+     * Adds result groupings for each schema type in each package being queried for.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters.
+     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param schemaMap         The schema map contains all prefixed existing schema types.
+     * @param resultSpecBuilder ResultSpecs as a specified by client.
+     */
+    private static void addPerPackagePerSchemaResultGroupings(
+            @NonNull Set<String> prefixes,
+            int maxNumResults,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap,
+            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
+        Map<String, List<String>> packageAndSchemaToSchemas =
+                getPackageAndSchemaToPrefixedSchemas(prefixes, schemaMap);
+
+        for (List<String> prefixedSchemas : packageAndSchemaToSchemas.values()) {
+            List<ResultSpecProto.ResultGrouping.Entry> entries =
+                    new ArrayList<>(prefixedSchemas.size());
+            for (int i = 0; i < prefixedSchemas.size(); i++) {
+                entries.add(
+                        ResultSpecProto.ResultGrouping.Entry.newBuilder()
+                            .setSchema(prefixedSchemas.get(i)).build());
+            }
+            resultSpecBuilder.addResultGroupings(
+                    ResultSpecProto.ResultGrouping.newBuilder()
+                            .addAllEntryGroupings(entries).setMaxResults(maxNumResults));
+        }
+    }
+
+    /**
+     * Adds result groupings for each namespace and schema type being queried for.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters.
+     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param namespaceMap      The namespace map contains all prefixed existing namespaces.
+     * @param schemaMap         The schema map contains all prefixed existing schema types.
+     * @param resultSpecBuilder ResultSpec as specified by client.
+     */
+    private static void addPerPackagePerNamespacePerSchemaResultGrouping(
+            @NonNull Set<String> prefixes,
+            int maxNumResults,
+            @NonNull Map<String, Set<String>> namespaceMap,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap,
+            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
+        Map<String, List<String>> packageAndNamespaceToNamespaces =
+                getPackageAndNamespaceToPrefixedNamespaces(prefixes, namespaceMap);
+        Map<String, List<String>> packageAndSchemaToSchemas =
+                getPackageAndSchemaToPrefixedSchemas(prefixes, schemaMap);
+
+        for (List<String> prefixedNamespaces : packageAndNamespaceToNamespaces.values()) {
+            for (List<String> prefixedSchemas : packageAndSchemaToSchemas.values()) {
+                List<ResultSpecProto.ResultGrouping.Entry> entries =
+                        new ArrayList<>(prefixedNamespaces.size() * prefixedSchemas.size());
+                // Iterate through all namespaces.
+                for (int i = 0; i < prefixedNamespaces.size(); i++) {
+                    String namespacePackage = getPackageName(prefixedNamespaces.get(i));
+                    // Iterate through all schemas.
+                    for (int j = 0; j < prefixedSchemas.size(); j++) {
+                        String schemaPackage = getPackageName(prefixedSchemas.get(j));
+                        if (namespacePackage.equals(schemaPackage)) {
+                            entries.add(
+                                    ResultSpecProto.ResultGrouping.Entry.newBuilder()
+                                        .setNamespace(prefixedNamespaces.get(i))
+                                        .setSchema(prefixedSchemas.get(j))
+                                        .build());
+                        }
+                    }
+                }
+                if (entries.size() > 0) {
+                    resultSpecBuilder.addResultGroupings(
+                            ResultSpecProto.ResultGrouping.newBuilder()
+                                .addAllEntryGroupings(entries).setMaxResults(maxNumResults));
+                }
+            }
+        }
+    }
+
+    /**
      * Adds result groupings for each package being queried for.
      *
      * @param prefixes          Prefixes that we should prepend to all our filters
@@ -479,42 +804,16 @@
             int maxNumResults,
             @NonNull Map<String, Set<String>> namespaceMap,
             @NonNull ResultSpecProto.Builder resultSpecBuilder) {
-        // Create a map of namespace to prefixedNamespaces. This is NOT necessarily the
-        // same as the list of namespaces. If a namespace exists under different packages and/or
-        // different databases, they should still be grouped together.
-        Map<String, List<String>> namespaceToPrefixedNamespaces = new ArrayMap<>();
-        for (String prefix : prefixes) {
-            Set<String> prefixedNamespaces = namespaceMap.get(prefix);
-            if (prefixedNamespaces == null) {
-                continue;
-            }
-            for (String prefixedNamespace : prefixedNamespaces) {
-                String namespace;
-                try {
-                    namespace = removePrefix(prefixedNamespace);
-                } catch (AppSearchException e) {
-                    // This should never happen. Skip this namespace if it does.
-                    Log.e(TAG, "Prefixed namespace " + prefixedNamespace + " is malformed.");
-                    continue;
-                }
-                List<String> groupedPrefixedNamespaces =
-                        namespaceToPrefixedNamespaces.get(namespace);
-                if (groupedPrefixedNamespaces == null) {
-                    groupedPrefixedNamespaces = new ArrayList<>();
-                    namespaceToPrefixedNamespaces.put(namespace,
-                            groupedPrefixedNamespaces);
-                }
-                groupedPrefixedNamespaces.add(prefixedNamespace);
-            }
-        }
+        Map<String, List<String>> namespaceToPrefixedNamespaces =
+                getNamespaceToPrefixedNamespaces(prefixes, namespaceMap);
 
         for (List<String> prefixedNamespaces : namespaceToPrefixedNamespaces.values()) {
             List<ResultSpecProto.ResultGrouping.Entry> entries =
                     new ArrayList<>(prefixedNamespaces.size());
-            for (String namespace : prefixedNamespaces) {
+            for (int i = 0; i < prefixedNamespaces.size(); i++) {
                 entries.add(
                         ResultSpecProto.ResultGrouping.Entry.newBuilder()
-                                .setNamespace(namespace).build());
+                            .setNamespace(prefixedNamespaces.get(i)).build());
             }
             resultSpecBuilder.addResultGroupings(
                     ResultSpecProto.ResultGrouping.newBuilder()
@@ -523,6 +822,90 @@
     }
 
     /**
+     * Adds result groupings for each schema type being queried for.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters.
+     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param schemaMap         The schema map contains all prefixed existing schema types.
+     * @param resultSpecBuilder ResultSpec as specified by client.
+     */
+    private static void addPerSchemaResultGrouping(
+            @NonNull Set<String> prefixes,
+            int maxNumResults,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap,
+            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
+        Map<String, List<String>> schemaToPrefixedSchemas =
+                getSchemaToPrefixedSchemas(prefixes, schemaMap);
+
+        for (List<String> prefixedSchemas : schemaToPrefixedSchemas.values()) {
+            List<ResultSpecProto.ResultGrouping.Entry> entries =
+                    new ArrayList<>(prefixedSchemas.size());
+            for (int i = 0; i < prefixedSchemas.size(); i++) {
+                entries.add(
+                        ResultSpecProto.ResultGrouping.Entry.newBuilder()
+                            .setSchema(prefixedSchemas.get(i)).build());
+            }
+            resultSpecBuilder.addResultGroupings(
+                    ResultSpecProto.ResultGrouping.newBuilder()
+                            .addAllEntryGroupings(entries).setMaxResults(maxNumResults));
+        }
+    }
+
+    /**
+     * Adds result groupings for each namespace and schema type being queried for.
+     *
+     * @param prefixes          Prefixes that we should prepend to all our filters.
+     * @param maxNumResults     The maximum number of results for each grouping to support.
+     * @param namespaceMap      The namespace map contains all prefixed existing namespaces.
+     * @param schemaMap         The schema map contains all prefixed existing schema types.
+     * @param resultSpecBuilder ResultSpec as specified by client.
+     */
+    private static void addPerNamespaceAndSchemaResultGrouping(
+            @NonNull Set<String> prefixes,
+            int maxNumResults,
+            @NonNull Map<String, Set<String>> namespaceMap,
+            @NonNull Map<String, Map<String, SchemaTypeConfigProto>> schemaMap,
+            @NonNull ResultSpecProto.Builder resultSpecBuilder) {
+        Map<String, List<String>> namespaceToPrefixedNamespaces =
+                getNamespaceToPrefixedNamespaces(prefixes, namespaceMap);
+        Map<String, List<String>> schemaToPrefixedSchemas =
+                getSchemaToPrefixedSchemas(prefixes, schemaMap);
+
+        for (List<String> prefixedNamespaces : namespaceToPrefixedNamespaces.values()) {
+            for (List<String> prefixedSchemas : schemaToPrefixedSchemas.values()) {
+                List<ResultSpecProto.ResultGrouping.Entry> entries =
+                        new ArrayList<>(prefixedNamespaces.size() * prefixedSchemas.size());
+                // Iterate through all namespaces.
+                for (int i = 0; i < prefixedNamespaces.size(); i++) {
+                    // Iterate through all schemas.
+                    for (int j = 0; j < prefixedSchemas.size(); j++) {
+                        try {
+                            if (getPrefix(prefixedNamespaces.get(i))
+                                    .equals(getPrefix(prefixedSchemas.get(j)))) {
+                                entries.add(
+                                                ResultSpecProto.ResultGrouping.Entry.newBuilder()
+                                                .setNamespace(prefixedNamespaces.get(i))
+                                                .setSchema(prefixedSchemas.get(j))
+                                                .build());
+                            }
+                        } catch (AppSearchException e) {
+                            // This should never happen. Skip this schema if it does.
+                            Log.e(TAG, "Prefixed string " + prefixedNamespaces.get(i) + " or "
+                                    + prefixedSchemas.get(j) + " is malformed.");
+                            continue;
+                        }
+                    }
+                }
+                if (entries.size() > 0) {
+                    resultSpecBuilder.addResultGroupings(
+                            ResultSpecProto.ResultGrouping.newBuilder()
+                                .addAllEntryGroupings(entries).setMaxResults(maxNumResults));
+                }
+            }
+        }
+    }
+
+    /**
      * Adds {@link TypePropertyWeights} to {@link ScoringSpecProto}.
      *
      * <p>{@link TypePropertyWeights} are added to the {@link ScoringSpecProto} with database and
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterUtil.java
index 1a90bb8..9015102 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterUtil.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSpecToProtoConverterUtil.java
@@ -29,7 +29,7 @@
 /**
  * Utilities for working with {@link SearchSpecToProtoConverter} and
  * {@link SearchSuggestionSpecToProtoConverter}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class SearchSpecToProtoConverterUtil {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverter.java
index 077bdd2..52f57bd 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SearchSuggestionSpecToProtoConverter.java
@@ -35,7 +35,7 @@
 /**
  * Translates a {@link SearchSuggestionSpec} into icing search protos.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SearchSuggestionSpecToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SetSchemaResponseToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SetSchemaResponseToProtoConverter.java
index 62d788c..797f138 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SetSchemaResponseToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/SetSchemaResponseToProtoConverter.java
@@ -26,7 +26,7 @@
 /**
  * Translates a {@link SetSchemaResultProto} into {@link SetSchemaResponse}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class SetSchemaResponseToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/TypePropertyPathToProtoConverter.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/TypePropertyPathToProtoConverter.java
index 1e81145..cac0c5c 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/TypePropertyPathToProtoConverter.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/converter/TypePropertyPathToProtoConverter.java
@@ -29,7 +29,7 @@
 /**
  * Translates a <code>Map<String, List<String>></code> into <code>List<TypePropertyMask></code>.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class TypePropertyPathToProtoConverter {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
index cb29317..02d2971 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/CallStats.java
@@ -20,11 +20,16 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
+import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Set;
 
 /**
  * A class for setting basic information to log for all function calls.
@@ -36,7 +41,7 @@
  * However, {@link CallStats} can still be used along with the detailed stats class for easy
  * aggregation/analysis with other function calls.
  *
- * @hide
+ * <!--@exportToFramework:hide-->
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class CallStats {
@@ -58,6 +63,20 @@
             CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH,
             CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID,
             CALL_TYPE_SCHEMA_MIGRATION,
+            CALL_TYPE_GLOBAL_GET_SCHEMA,
+            CALL_TYPE_GET_SCHEMA,
+            CALL_TYPE_GET_NAMESPACES,
+            CALL_TYPE_GET_NEXT_PAGE,
+            CALL_TYPE_INVALIDATE_NEXT_PAGE_TOKEN,
+            CALL_TYPE_WRITE_SEARCH_RESULTS_TO_FILE,
+            CALL_TYPE_PUT_DOCUMENTS_FROM_FILE,
+            CALL_TYPE_SEARCH_SUGGESTION,
+            CALL_TYPE_REPORT_SYSTEM_USAGE,
+            CALL_TYPE_REPORT_USAGE,
+            CALL_TYPE_GET_STORAGE_INFO,
+            CALL_TYPE_REGISTER_OBSERVER_CALLBACK,
+            CALL_TYPE_UNREGISTER_OBSERVER_CALLBACK,
+            CALL_TYPE_GLOBAL_GET_NEXT_PAGE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CallType {
@@ -80,6 +99,51 @@
     public static final int CALL_TYPE_REMOVE_DOCUMENT_BY_SEARCH = 14;
     public static final int CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID = 15;
     public static final int CALL_TYPE_SCHEMA_MIGRATION = 16;
+    public static final int CALL_TYPE_GLOBAL_GET_SCHEMA = 17;
+    public static final int CALL_TYPE_GET_SCHEMA = 18;
+    public static final int CALL_TYPE_GET_NAMESPACES = 19;
+    public static final int CALL_TYPE_GET_NEXT_PAGE = 20;
+    public static final int CALL_TYPE_INVALIDATE_NEXT_PAGE_TOKEN = 21;
+    public static final int CALL_TYPE_WRITE_SEARCH_RESULTS_TO_FILE = 22;
+    public static final int CALL_TYPE_PUT_DOCUMENTS_FROM_FILE = 23;
+    public static final int CALL_TYPE_SEARCH_SUGGESTION = 24;
+    public static final int CALL_TYPE_REPORT_SYSTEM_USAGE = 25;
+    public static final int CALL_TYPE_REPORT_USAGE = 26;
+    public static final int CALL_TYPE_GET_STORAGE_INFO = 27;
+    public static final int CALL_TYPE_REGISTER_OBSERVER_CALLBACK = 28;
+    public static final int CALL_TYPE_UNREGISTER_OBSERVER_CALLBACK = 29;
+    public static final int CALL_TYPE_GLOBAL_GET_NEXT_PAGE = 30;
+
+    // These strings are for the subset of call types that correspond to an AppSearchManager API
+    private static final String CALL_TYPE_STRING_INITIALIZE = "initialize";
+    private static final String CALL_TYPE_STRING_SET_SCHEMA = "localSetSchema";
+    private static final String CALL_TYPE_STRING_PUT_DOCUMENTS = "localPutDocuments";
+    private static final String CALL_TYPE_STRING_GET_DOCUMENTS = "localGetDocuments";
+    private static final String CALL_TYPE_STRING_REMOVE_DOCUMENTS_BY_ID = "localRemoveByDocumentId";
+    private static final String CALL_TYPE_STRING_SEARCH = "localSearch";
+    private static final String CALL_TYPE_STRING_FLUSH = "flush";
+    private static final String CALL_TYPE_STRING_GLOBAL_SEARCH = "globalSearch";
+    private static final String CALL_TYPE_STRING_REMOVE_DOCUMENTS_BY_SEARCH = "localRemoveBySearch";
+    private static final String CALL_TYPE_STRING_GLOBAL_GET_DOCUMENT_BY_ID = "globalGetDocuments";
+    private static final String CALL_TYPE_STRING_GLOBAL_GET_SCHEMA = "globalGetSchema";
+    private static final String CALL_TYPE_STRING_GET_SCHEMA = "localGetSchema";
+    private static final String CALL_TYPE_STRING_GET_NAMESPACES = "localGetNamespaces";
+    private static final String CALL_TYPE_STRING_GET_NEXT_PAGE = "localGetNextPage";
+    private static final String CALL_TYPE_STRING_INVALIDATE_NEXT_PAGE_TOKEN =
+            "invalidateNextPageToken";
+    private static final String CALL_TYPE_STRING_WRITE_SEARCH_RESULTS_TO_FILE =
+            "localWriteSearchResultsToFile";
+    private static final String CALL_TYPE_STRING_PUT_DOCUMENTS_FROM_FILE =
+            "localPutDocumentsFromFile";
+    private static final String CALL_TYPE_STRING_SEARCH_SUGGESTION = "localSearchSuggestion";
+    private static final String CALL_TYPE_STRING_REPORT_SYSTEM_USAGE = "globalReportUsage";
+    private static final String CALL_TYPE_STRING_REPORT_USAGE = "localReportUsage";
+    private static final String CALL_TYPE_STRING_GET_STORAGE_INFO = "localGetStorageInfo";
+    private static final String CALL_TYPE_STRING_REGISTER_OBSERVER_CALLBACK =
+            "globalRegisterObserverCallback";
+    private static final String CALL_TYPE_STRING_UNREGISTER_OBSERVER_CALLBACK =
+            "globalUnregisterObserverCallback";
+    private static final String CALL_TYPE_STRING_GLOBAL_GET_NEXT_PAGE = "globalGetNextPage";
 
     @Nullable
     private final String mPackageName;
@@ -149,8 +213,9 @@
      * Returns number of operations succeeded.
      *
      * <p>For example, for
-     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of individual
-     * successful put operations. In this case, how many documents are successfully indexed.
+     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of
+     * individual successful put operations. In this case, how many documents are successfully
+     * indexed.
      *
      * <p>For non-batch calls such as
      * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
@@ -166,8 +231,8 @@
      * Returns number of operations failed.
      *
      * <p>For example, for
-     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of individual
-     * failed put operations. In this case, how many documents are failed to be indexed.
+     * {@link androidx.appsearch.app.AppSearchSession#putAsync}, it is the total number of
+     * individual failed put operations. In this case, how many documents are failed to be indexed.
      *
      * <p>For non-batch calls such as
      * {@link androidx.appsearch.app.AppSearchSession#setSchemaAsync}, the sum of
@@ -195,20 +260,23 @@
         int mNumOperationsFailed;
 
         /** Sets the PackageName used by the session. */
+        @CanIgnoreReturnValue
         @NonNull
-        public Builder setPackageName(@NonNull String packageName) {
-            mPackageName = Preconditions.checkNotNull(packageName);
+        public Builder setPackageName(@Nullable String packageName) {
+            mPackageName = packageName;
             return this;
         }
 
         /** Sets the database used by the session. */
+        @CanIgnoreReturnValue
         @NonNull
-        public Builder setDatabase(@NonNull String database) {
-            mDatabase = Preconditions.checkNotNull(database);
+        public Builder setDatabase(@Nullable String database) {
+            mDatabase = database;
             return this;
         }
 
         /** Sets the status code. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -216,6 +284,7 @@
         }
 
         /** Sets total latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -223,6 +292,7 @@
         }
 
         /** Sets type of the call. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setCallType(@CallType int callType) {
             mCallType = callType;
@@ -230,6 +300,7 @@
         }
 
         /** Sets estimated binder latency, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setEstimatedBinderLatencyMillis(int estimatedBinderLatencyMillis) {
             mEstimatedBinderLatencyMillis = estimatedBinderLatencyMillis;
@@ -250,6 +321,7 @@
          * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
          * operation.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNumOperationsSucceeded(int numOperationsSucceeded) {
             mNumOperationsSucceeded = numOperationsSucceeded;
@@ -269,6 +341,7 @@
          * {@link CallStats#getNumOperationsFailed()} is always 1 since there is only one
          * operation.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNumOperationsFailed(int numOperationsFailed) {
             mNumOperationsFailed = numOperationsFailed;
@@ -281,4 +354,97 @@
             return new CallStats(/* builder= */ this);
         }
     }
+
+    /**
+     * Returns the {@link CallStats.CallType} represented by the given AppSearchManager API name. If
+     * an unknown name is provided, {@link CallStats.CallType#CALL_TYPE_UNKNOWN} is returned.
+     */
+    @CallType
+    public static int getApiCallTypeFromName(@NonNull String name) {
+        switch (name) {
+            case CALL_TYPE_STRING_INITIALIZE:
+                return CALL_TYPE_INITIALIZE;
+            case CALL_TYPE_STRING_SET_SCHEMA:
+                return CALL_TYPE_SET_SCHEMA;
+            case CALL_TYPE_STRING_PUT_DOCUMENTS:
+                return CALL_TYPE_PUT_DOCUMENTS;
+            case CALL_TYPE_STRING_GET_DOCUMENTS:
+                return CALL_TYPE_GET_DOCUMENTS;
+            case CALL_TYPE_STRING_REMOVE_DOCUMENTS_BY_ID:
+                return CALL_TYPE_REMOVE_DOCUMENTS_BY_ID;
+            case CALL_TYPE_STRING_SEARCH:
+                return CALL_TYPE_SEARCH;
+            case CALL_TYPE_STRING_FLUSH:
+                return CALL_TYPE_FLUSH;
+            case CALL_TYPE_STRING_GLOBAL_SEARCH:
+                return CALL_TYPE_GLOBAL_SEARCH;
+            case CALL_TYPE_STRING_REMOVE_DOCUMENTS_BY_SEARCH:
+                return CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH;
+            case CALL_TYPE_STRING_GLOBAL_GET_DOCUMENT_BY_ID:
+                return CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID;
+            case CALL_TYPE_STRING_GLOBAL_GET_SCHEMA:
+                return CALL_TYPE_GLOBAL_GET_SCHEMA;
+            case CALL_TYPE_STRING_GET_SCHEMA:
+                return CALL_TYPE_GET_SCHEMA;
+            case CALL_TYPE_STRING_GET_NAMESPACES:
+                return CALL_TYPE_GET_NAMESPACES;
+            case CALL_TYPE_STRING_GET_NEXT_PAGE:
+                return CALL_TYPE_GET_NEXT_PAGE;
+            case CALL_TYPE_STRING_INVALIDATE_NEXT_PAGE_TOKEN:
+                return CALL_TYPE_INVALIDATE_NEXT_PAGE_TOKEN;
+            case CALL_TYPE_STRING_WRITE_SEARCH_RESULTS_TO_FILE:
+                return CALL_TYPE_WRITE_SEARCH_RESULTS_TO_FILE;
+            case CALL_TYPE_STRING_PUT_DOCUMENTS_FROM_FILE:
+                return CALL_TYPE_PUT_DOCUMENTS_FROM_FILE;
+            case CALL_TYPE_STRING_SEARCH_SUGGESTION:
+                return CALL_TYPE_SEARCH_SUGGESTION;
+            case CALL_TYPE_STRING_REPORT_SYSTEM_USAGE:
+                return CALL_TYPE_REPORT_SYSTEM_USAGE;
+            case CALL_TYPE_STRING_REPORT_USAGE:
+                return CALL_TYPE_REPORT_USAGE;
+            case CALL_TYPE_STRING_GET_STORAGE_INFO:
+                return CALL_TYPE_GET_STORAGE_INFO;
+            case CALL_TYPE_STRING_REGISTER_OBSERVER_CALLBACK:
+                return CALL_TYPE_REGISTER_OBSERVER_CALLBACK;
+            case CALL_TYPE_STRING_UNREGISTER_OBSERVER_CALLBACK:
+                return CALL_TYPE_UNREGISTER_OBSERVER_CALLBACK;
+            case CALL_TYPE_STRING_GLOBAL_GET_NEXT_PAGE:
+                return CALL_TYPE_GLOBAL_GET_NEXT_PAGE;
+            default:
+                return CALL_TYPE_UNKNOWN;
+        }
+    }
+
+    /**
+     * Returns the set of all {@link CallStats.CallType} that map to an AppSearchManager API.
+     */
+    @VisibleForTesting
+    @NonNull
+    public static Set<Integer> getAllApiCallTypes() {
+        return new ArraySet<>(Arrays.asList(
+                CALL_TYPE_INITIALIZE,
+                CALL_TYPE_SET_SCHEMA,
+                CALL_TYPE_PUT_DOCUMENTS,
+                CALL_TYPE_GET_DOCUMENTS,
+                CALL_TYPE_REMOVE_DOCUMENTS_BY_ID,
+                CALL_TYPE_SEARCH,
+                CALL_TYPE_FLUSH,
+                CALL_TYPE_GLOBAL_SEARCH,
+                CALL_TYPE_REMOVE_DOCUMENTS_BY_SEARCH,
+                CALL_TYPE_GLOBAL_GET_DOCUMENT_BY_ID,
+                CALL_TYPE_GLOBAL_GET_SCHEMA,
+                CALL_TYPE_GET_SCHEMA,
+                CALL_TYPE_GET_NAMESPACES,
+                CALL_TYPE_GET_NEXT_PAGE,
+                CALL_TYPE_INVALIDATE_NEXT_PAGE_TOKEN,
+                CALL_TYPE_WRITE_SEARCH_RESULTS_TO_FILE,
+                CALL_TYPE_PUT_DOCUMENTS_FROM_FILE,
+                CALL_TYPE_SEARCH_SUGGESTION,
+                CALL_TYPE_REPORT_SYSTEM_USAGE,
+                CALL_TYPE_REPORT_USAGE,
+                CALL_TYPE_GET_STORAGE_INFO,
+                CALL_TYPE_REGISTER_OBSERVER_CALLBACK,
+                CALL_TYPE_UNREGISTER_OBSERVER_CALLBACK,
+                CALL_TYPE_GLOBAL_GET_NEXT_PAGE));
+    }
 }
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/InitializeStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/InitializeStats.java
index f88d257..4a16ff3 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/InitializeStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/InitializeStats.java
@@ -19,6 +19,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.core.util.Preconditions;
 
@@ -28,7 +29,7 @@
 /**
  * Class holds detailed stats for initialization
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class InitializeStats {
@@ -288,6 +289,7 @@
         int mResetStatusCode;
 
         /** Sets the status of the initialization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -295,6 +297,7 @@
         }
 
         /** Sets the total latency of the initialization in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -307,6 +310,7 @@
          * <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent
          * view of what data should exist.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setHasDeSync(boolean hasDeSync) {
             mHasDeSync = hasDeSync;
@@ -314,6 +318,7 @@
         }
 
         /** Sets time used to read and process the schema and namespaces. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setPrepareSchemaAndNamespacesLatencyMillis(
                 int prepareSchemaAndNamespacesLatencyMillis) {
@@ -322,6 +327,7 @@
         }
 
         /** Sets time used to read and process the visibility file. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setPrepareVisibilityStoreLatencyMillis(
                 int prepareVisibilityStoreLatencyMillis) {
@@ -330,6 +336,7 @@
         }
 
         /** Sets overall time used for the native function call. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
             mNativeLatencyMillis = nativeLatencyMillis;
@@ -344,6 +351,7 @@
          * <li> {@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
          * <li> {@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentStoreRecoveryCause(
                 @RecoveryCause int documentStoreRecoveryCause) {
@@ -358,6 +366,7 @@
          *      <li> {@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
          *      <li> {@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIndexRestorationCause(
                 @RecoveryCause int indexRestorationCause) {
@@ -370,6 +379,7 @@
          *  <p> Possible causes:
          *      <li> {@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSchemaStoreRecoveryCause(
                 @RecoveryCause int schemaStoreRecoveryCause) {
@@ -378,6 +388,7 @@
         }
 
         /** Sets time used to recover the document store. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentStoreRecoveryLatencyMillis(
                 int documentStoreRecoveryLatencyMillis) {
@@ -386,6 +397,7 @@
         }
 
         /** Sets time used to restore the index. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIndexRestorationLatencyMillis(
                 int indexRestorationLatencyMillis) {
@@ -394,6 +406,7 @@
         }
 
         /** Sets time used to recover the schema store. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSchemaStoreRecoveryLatencyMillis(
                 int schemaStoreRecoveryLatencyMillis) {
@@ -405,6 +418,7 @@
          * Sets Native Document Store Data status.
          * status is defined in external/icing/proto/icing/proto/logging.proto
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentStoreDataStatus(
                 @DocumentStoreDataStatus int documentStoreDataStatus) {
@@ -416,6 +430,7 @@
          * Sets number of documents currently in document store. Those may include alive, deleted,
          * and expired documents.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentCount(int numDocuments) {
             mNativeNumDocuments = numDocuments;
@@ -423,6 +438,7 @@
         }
 
         /** Sets number of schema types currently in the schema store. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSchemaTypeCount(int numSchemaTypes) {
             mNativeNumSchemaTypes = numSchemaTypes;
@@ -430,6 +446,7 @@
         }
 
         /** Sets whether we had to reset the index, losing all data, as part of initialization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setHasReset(boolean hasReset) {
             mHasReset = hasReset;
@@ -437,6 +454,7 @@
         }
 
         /** Sets the status of the reset, if one was performed according to {@link #setHasReset}. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setResetStatusCode(@AppSearchResult.ResultCode int resetStatusCode) {
             mResetStatusCode = resetStatusCode;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/OptimizeStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/OptimizeStats.java
index b7dcae0..87731b3 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/OptimizeStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/OptimizeStats.java
@@ -18,13 +18,14 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.core.util.Preconditions;
 
 /**
  * Class holds detailed stats for Optimize.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class OptimizeStats {
@@ -156,6 +157,7 @@
         long mNativeTimeSinceLastOptimizeMillis;
 
         /** Sets the status code. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -163,6 +165,7 @@
         }
 
         /** Sets total latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -170,6 +173,7 @@
         }
 
         /** Sets native latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
             mNativeLatencyMillis = nativeLatencyMillis;
@@ -177,6 +181,7 @@
         }
 
         /** Sets time used to optimize the document store. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentStoreOptimizeLatencyMillis(
                 int documentStoreOptimizeLatencyMillis) {
@@ -185,6 +190,7 @@
         }
 
         /** Sets time used to restore the index. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis) {
             mNativeIndexRestorationLatencyMillis = indexRestorationLatencyMillis;
@@ -192,6 +198,7 @@
         }
 
         /** Sets number of documents before the optimization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setOriginalDocumentCount(int originalDocumentCount) {
             mNativeOriginalDocumentCount = originalDocumentCount;
@@ -199,6 +206,7 @@
         }
 
         /** Sets number of documents deleted during the optimization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDeletedDocumentCount(int deletedDocumentCount) {
             mNativeDeletedDocumentCount = deletedDocumentCount;
@@ -206,6 +214,7 @@
         }
 
         /** Sets number of documents expired during the optimization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setExpiredDocumentCount(int expiredDocumentCount) {
             mNativeExpiredDocumentCount = expiredDocumentCount;
@@ -213,6 +222,7 @@
         }
 
         /** Sets Storage size in bytes before optimization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStorageSizeBeforeBytes(long storageSizeBeforeBytes) {
             mNativeStorageSizeBeforeBytes = storageSizeBeforeBytes;
@@ -220,6 +230,7 @@
         }
 
         /** Sets storage size in bytes after optimization. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStorageSizeAfterBytes(long storageSizeAfterBytes) {
             mNativeStorageSizeAfterBytes = storageSizeAfterBytes;
@@ -229,6 +240,7 @@
         /**
          * Sets the amount the time since the last optimize ran calculated using wall clock time.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTimeSinceLastOptimizeMillis(long timeSinceLastOptimizeMillis) {
             mNativeTimeSinceLastOptimizeMillis = timeSinceLastOptimizeMillis;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
index e9a25fd..65c5923 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/PutDocumentStats.java
@@ -18,6 +18,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.core.util.Preconditions;
 
@@ -25,7 +26,7 @@
  * A class for holding detailed stats to log for each individual document put by a
  * {@link androidx.appsearch.app.AppSearchSession#putAsync} call.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class PutDocumentStats {
@@ -169,6 +170,7 @@
         }
 
         /** Sets the status code. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -176,6 +178,7 @@
         }
 
         /** Sets total latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -183,6 +186,7 @@
         }
 
         /** Sets how much time we spend for generating document proto, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setGenerateDocumentProtoLatencyMillis(
                 int generateDocumentProtoLatencyMillis) {
@@ -194,6 +198,7 @@
          * Sets how much time we spend for rewriting types and namespaces in document, in
          * milliseconds.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRewriteDocumentTypesLatencyMillis(int rewriteDocumentTypesLatencyMillis) {
             mRewriteDocumentTypesLatencyMillis = rewriteDocumentTypesLatencyMillis;
@@ -201,6 +206,7 @@
         }
 
         /** Sets the native latency, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
             mNativeLatencyMillis = nativeLatencyMillis;
@@ -208,6 +214,7 @@
         }
 
         /** Sets how much time we spend on document store, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeDocumentStoreLatencyMillis(int nativeDocumentStoreLatencyMillis) {
             mNativeDocumentStoreLatencyMillis = nativeDocumentStoreLatencyMillis;
@@ -215,6 +222,7 @@
         }
 
         /** Sets the native index latency, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeIndexLatencyMillis(int nativeIndexLatencyMillis) {
             mNativeIndexLatencyMillis = nativeIndexLatencyMillis;
@@ -222,6 +230,7 @@
         }
 
         /** Sets how much time we spend on merging indices, in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeIndexMergeLatencyMillis(int nativeIndexMergeLatencyMillis) {
             mNativeIndexMergeLatencyMillis = nativeIndexMergeLatencyMillis;
@@ -229,6 +238,7 @@
         }
 
         /** Sets document size, in bytes. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeDocumentSizeBytes(int nativeDocumentSizeBytes) {
             mNativeDocumentSizeBytes = nativeDocumentSizeBytes;
@@ -236,6 +246,7 @@
         }
 
         /** Sets number of tokens indexed in native. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeNumTokensIndexed(int nativeNumTokensIndexed) {
             mNativeNumTokensIndexed = nativeNumTokensIndexed;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
index 7eb4820..73a8c96 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/RemoveStats.java
@@ -19,6 +19,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.RemoveByDocumentIdRequest;
 import androidx.appsearch.app.SearchSpec;
@@ -32,7 +33,7 @@
  * {@link androidx.appsearch.app.AppSearchSession#removeAsync(RemoveByDocumentIdRequest)} and
  * {@link androidx.appsearch.app.AppSearchSession#removeAsync(String, SearchSpec)}
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class RemoveStats {
@@ -148,6 +149,7 @@
         }
 
         /** Sets the status code. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -155,6 +157,7 @@
         }
 
         /** Sets total latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -162,6 +165,7 @@
         }
 
         /** Sets native latency in millis. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
             mNativeLatencyMillis = nativeLatencyMillis;
@@ -169,6 +173,7 @@
         }
 
         /** Sets delete type for this call. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDeleteType(@DeleteType int nativeDeleteType) {
             mNativeDeleteType = nativeDeleteType;
@@ -176,6 +181,7 @@
         }
 
         /** Sets how many documents get deleted for this call. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDeletedDocumentCount(int nativeNumDocumentsDeleted) {
             mNativeNumDocumentsDeleted = nativeNumDocumentsDeleted;
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SearchStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SearchStats.java
index bc46326..a87ae04 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SearchStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SearchStats.java
@@ -19,7 +19,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
+import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.JoinableValueType;
 import androidx.appsearch.app.SearchSpec;
 import androidx.core.util.Preconditions;
 
@@ -30,7 +32,7 @@
  * Class holds detailed stats for
  * {@link androidx.appsearch.app.AppSearchSession#search(String, SearchSpec)}
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SearchStats {
@@ -129,7 +131,12 @@
     private final int mJavaToNativeJniLatencyMillis;
     /** Time used to send data across the JNI boundary from native to java side. */
     private final int mNativeToJavaJniLatencyMillis;
-
+    /** The type of join performed. Zero if no join is performed */
+    @JoinableValueType private final int mJoinType;
+    /** The total number of joined documents in the current page. */
+    private final int mNativeNumJoinedResultsCurrentPage;
+    /** Time taken to join documents together. */
+    private final int mNativeJoinLatencyMillis;
 
     SearchStats(@NonNull Builder builder) {
         Preconditions.checkNotNull(builder);
@@ -160,6 +167,9 @@
         mNativeLockAcquisitionLatencyMillis = builder.mNativeLockAcquisitionLatencyMillis;
         mJavaToNativeJniLatencyMillis = builder.mJavaToNativeJniLatencyMillis;
         mNativeToJavaJniLatencyMillis = builder.mNativeToJavaJniLatencyMillis;
+        mJoinType = builder.mJoinType;
+        mNativeNumJoinedResultsCurrentPage = builder.mNativeNumJoinedResultsCurrentPage;
+        mNativeJoinLatencyMillis = builder.mNativeJoinLatencyMillis;
     }
 
     /** Returns the package name of the session. */
@@ -317,6 +327,21 @@
         return mNativeToJavaJniLatencyMillis;
     }
 
+    /** Returns the type of join performed. Blank if no join is performed */
+    public @JoinableValueType int getJoinType() {
+        return mJoinType;
+    }
+
+    /** Returns the total number of joined documents in the current page. */
+    public int getNumJoinedResultsCurrentPage() {
+        return mNativeNumJoinedResultsCurrentPage;
+    }
+
+    /** Returns the time taken to join documents together. */
+    public int getJoinLatencyMillis() {
+        return mNativeJoinLatencyMillis;
+    }
+
     /** Builder for {@link SearchStats} */
     public static class Builder {
         @NonNull
@@ -349,7 +374,9 @@
         int mNativeLockAcquisitionLatencyMillis;
         int mJavaToNativeJniLatencyMillis;
         int mNativeToJavaJniLatencyMillis;
-
+        @JoinableValueType int mJoinType;
+        int mNativeNumJoinedResultsCurrentPage;
+        int mNativeJoinLatencyMillis;
 
         /**
          * Constructor
@@ -363,13 +390,15 @@
         }
 
         /** Sets the database used by the session. */
+        @CanIgnoreReturnValue
         @NonNull
-        public Builder setDatabase(@NonNull String database) {
-            mDatabase = Preconditions.checkNotNull(database);
+        public Builder setDatabase(@Nullable String database) {
+            mDatabase = database;
             return this;
         }
 
         /** Sets the status of the search. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -377,6 +406,7 @@
         }
 
         /** Sets total latency for the search. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -384,6 +414,7 @@
         }
 
         /** Sets time used to rewrite the search spec. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRewriteSearchSpecLatencyMillis(int rewriteSearchSpecLatencyMillis) {
             mRewriteSearchSpecLatencyMillis = rewriteSearchSpecLatencyMillis;
@@ -391,6 +422,7 @@
         }
 
         /** Sets time used to rewrite the search results. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRewriteSearchResultLatencyMillis(int rewriteSearchResultLatencyMillis) {
             mRewriteSearchResultLatencyMillis = rewriteSearchResultLatencyMillis;
@@ -398,6 +430,7 @@
         }
 
         /** Sets time passed while waiting to acquire the lock during Java function calls. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setJavaLockAcquisitionLatencyMillis(int javaLockAcquisitionLatencyMillis) {
             mJavaLockAcquisitionLatencyMillis = javaLockAcquisitionLatencyMillis;
@@ -408,6 +441,7 @@
          * Sets time spent on ACL checking, which is the time spent filtering namespaces based on
          * package permissions and Android permission access.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setAclCheckLatencyMillis(int aclCheckLatencyMillis) {
             mAclCheckLatencyMillis = aclCheckLatencyMillis;
@@ -415,6 +449,7 @@
         }
 
         /** Sets overall time used for the native function calls. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
             mNativeLatencyMillis = nativeLatencyMillis;
@@ -422,6 +457,7 @@
         }
 
         /** Sets number of terms in the search string. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTermCount(int termCount) {
             mNativeNumTerms = termCount;
@@ -429,6 +465,7 @@
         }
 
         /** Sets length of the search string. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setQueryLength(int queryLength) {
             mNativeQueryLength = queryLength;
@@ -436,6 +473,7 @@
         }
 
         /** Sets number of namespaces filtered. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setFilteredNamespaceCount(int filteredNamespaceCount) {
             mNativeNumNamespacesFiltered = filteredNamespaceCount;
@@ -443,6 +481,7 @@
         }
 
         /** Sets number of schema types filtered. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setFilteredSchemaTypeCount(int filteredSchemaTypeCount) {
             mNativeNumSchemaTypesFiltered = filteredSchemaTypeCount;
@@ -450,6 +489,7 @@
         }
 
         /** Sets the requested number of results in one page. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRequestedPageSize(int requestedPageSize) {
             mNativeRequestedPageSize = requestedPageSize;
@@ -457,6 +497,7 @@
         }
 
         /** Sets the actual number of results returned in the current page. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setCurrentPageReturnedResultCount(
                 int currentPageReturnedResultCount) {
@@ -469,6 +510,7 @@
          * not, Icing will fetch the results from cache so that some steps
          * may be skipped.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIsFirstPage(boolean nativeIsFirstPage) {
             mNativeIsFirstPage = nativeIsFirstPage;
@@ -479,6 +521,7 @@
          * Sets time used to parse the query, including 2 parts: tokenizing and
          * transforming tokens into an iterator tree.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setParseQueryLatencyMillis(int parseQueryLatencyMillis) {
             mNativeParseQueryLatencyMillis = parseQueryLatencyMillis;
@@ -486,6 +529,7 @@
         }
 
         /** Sets strategy of scoring and ranking. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRankingStrategy(
                 @SearchSpec.RankingStrategy int rankingStrategy) {
@@ -494,6 +538,7 @@
         }
 
         /** Sets number of documents scored. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setScoredDocumentCount(int scoredDocumentCount) {
             mNativeNumDocumentsScored = scoredDocumentCount;
@@ -501,6 +546,7 @@
         }
 
         /** Sets time used to score the raw results. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setScoringLatencyMillis(int scoringLatencyMillis) {
             mNativeScoringLatencyMillis = scoringLatencyMillis;
@@ -508,6 +554,7 @@
         }
 
         /** Sets time used to rank the scored results. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRankingLatencyMillis(int rankingLatencyMillis) {
             mNativeRankingLatencyMillis = rankingLatencyMillis;
@@ -515,6 +562,7 @@
         }
 
         /** Sets time used to fetch the document protos. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocumentRetrievingLatencyMillis(
                 int documentRetrievingLatencyMillis) {
@@ -523,6 +571,7 @@
         }
 
         /** Sets how many snippets are calculated. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setResultWithSnippetsCount(int resultWithSnippetsCount) {
             mNativeNumResultsWithSnippets = resultWithSnippetsCount;
@@ -530,6 +579,7 @@
         }
 
         /** Sets time passed while waiting to acquire the lock during native function calls. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeLockAcquisitionLatencyMillis(
                 int nativeLockAcquisitionLatencyMillis) {
@@ -538,6 +588,7 @@
         }
 
         /** Sets time used to send data across the JNI boundary from java to native side. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setJavaToNativeJniLatencyMillis(int javaToNativeJniLatencyMillis) {
             mJavaToNativeJniLatencyMillis = javaToNativeJniLatencyMillis;
@@ -545,12 +596,34 @@
         }
 
         /** Sets time used to send data across the JNI boundary from native to java side. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNativeToJavaJniLatencyMillis(int nativeToJavaJniLatencyMillis) {
             mNativeToJavaJniLatencyMillis = nativeToJavaJniLatencyMillis;
             return this;
         }
 
+        /** Sets whether or not this is a join query */
+        @NonNull
+        public Builder setJoinType(@JoinableValueType int joinType) {
+            mJoinType = joinType;
+            return this;
+        }
+
+        /** Set the total number of joined documents in a page. */
+        @NonNull
+        public Builder setNativeNumJoinedResultsCurrentPage(int nativeNumJoinedResultsCurrentPage) {
+            mNativeNumJoinedResultsCurrentPage = nativeNumJoinedResultsCurrentPage;
+            return this;
+        }
+
+        /** Sets time it takes to join documents together in icing. */
+        @NonNull
+        public Builder setNativeJoinLatencyMillis(int nativeJoinLatencyMillis) {
+            mNativeJoinLatencyMillis = nativeJoinLatencyMillis;
+            return this;
+        }
+
         /**
          * Constructs a new {@link SearchStats} from the contents of this
          * {@link SearchStats.Builder}.
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SetSchemaStats.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SetSchemaStats.java
index c052eb8..0bb8629 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SetSchemaStats.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/stats/SetSchemaStats.java
@@ -21,6 +21,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.stats.SchemaMigrationStats;
 import androidx.core.util.Preconditions;
@@ -29,7 +30,7 @@
  * Class holds detailed stats for
  * {@link androidx.appsearch.app.AppSearchSession#setSchema(SetSchemaRequest)}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SetSchemaStats {
@@ -224,7 +225,8 @@
     }
 
     /** Gets the type indicate how this set schema call relative to schema migration cases */
-    public @SchemaMigrationStats.SchemaMigrationCallType int getSchemaMigrationCallType() {
+    @SchemaMigrationStats.SchemaMigrationCallType
+    public int getSchemaMigrationCallType() {
         return mSchemaMigrationCallType;
     }
 
@@ -266,6 +268,7 @@
         }
 
         /** Sets the status of the SetSchema action. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mStatusCode = statusCode;
@@ -273,6 +276,7 @@
         }
 
         /** Sets total latency for the SetSchema action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mTotalLatencyMillis = totalLatencyMillis;
@@ -280,6 +284,7 @@
         }
 
         /** Sets number of new types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNewTypeCount(int newTypeCount) {
             mNewTypeCount = newTypeCount;
@@ -287,6 +292,7 @@
         }
 
         /** Sets number of deleted types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDeletedTypeCount(int deletedTypeCount) {
             mDeletedTypeCount = deletedTypeCount;
@@ -294,6 +300,7 @@
         }
 
         /** Sets number of compatible type changes. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setCompatibleTypeChangeCount(int compatibleTypeChangeCount) {
             mCompatibleTypeChangeCount = compatibleTypeChangeCount;
@@ -301,6 +308,7 @@
         }
 
         /** Sets number of index-incompatible type changes. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIndexIncompatibleTypeChangeCount(int indexIncompatibleTypeChangeCount) {
             mIndexIncompatibleTypeChangeCount = indexIncompatibleTypeChangeCount;
@@ -308,6 +316,7 @@
         }
 
         /** Sets number of backwards-incompatible type changes. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setBackwardsIncompatibleTypeChangeCount(
                 int backwardsIncompatibleTypeChangeCount) {
@@ -316,6 +325,7 @@
         }
 
         /** Sets total latency for the SetSchema in native action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVerifyIncomingCallLatencyMillis(int verifyIncomingCallLatencyMillis) {
             mVerifyIncomingCallLatencyMillis = verifyIncomingCallLatencyMillis;
@@ -323,6 +333,7 @@
         }
 
         /** Sets total latency for the SetSchema in native action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis) {
             mExecutorAcquisitionLatencyMillis = executorAcquisitionLatencyMillis;
@@ -330,6 +341,7 @@
         }
 
         /** Sets latency for the rebuild schema object from bundle action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRebuildFromBundleLatencyMillis(int rebuildFromBundleLatencyMillis) {
             mRebuildFromBundleLatencyMillis = rebuildFromBundleLatencyMillis;
@@ -339,6 +351,7 @@
         /**
          * Sets latency for waiting to acquire the lock during Java function calls in milliseconds.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setJavaLockAcquisitionLatencyMillis(int javaLockAcquisitionLatencyMillis) {
             mJavaLockAcquisitionLatencyMillis = javaLockAcquisitionLatencyMillis;
@@ -346,6 +359,7 @@
         }
 
         /** Sets latency for the rewrite the schema proto action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRewriteSchemaLatencyMillis(int rewriteSchemaLatencyMillis) {
             mRewriteSchemaLatencyMillis = rewriteSchemaLatencyMillis;
@@ -353,6 +367,7 @@
         }
 
         /** Sets total latency for a single set schema in native action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalNativeLatencyMillis(int totalNativeLatencyMillis) {
             mTotalNativeLatencyMillis = totalNativeLatencyMillis;
@@ -360,6 +375,7 @@
         }
 
         /** Sets latency for the apply visibility settings action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVisibilitySettingLatencyMillis(int visibilitySettingLatencyMillis) {
             mVisibilitySettingLatencyMillis = visibilitySettingLatencyMillis;
@@ -367,6 +383,7 @@
         }
 
         /** Sets latency for converting to SetSchemaResponseInternal object in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setConvertToResponseLatencyMillis(int convertToResponseLatencyMillis) {
             mConvertToResponseLatencyMillis = convertToResponseLatencyMillis;
@@ -374,6 +391,7 @@
         }
 
         /** Sets latency for the dispatch change notification action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDispatchChangeNotificationsLatencyMillis(
                 int dispatchChangeNotificationsLatencyMillis) {
@@ -382,6 +400,7 @@
         }
 
         /** Sets latency for the optimization action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setOptimizeLatencyMillis(int optimizeLatencyMillis) {
             mOptimizeLatencyMillis = optimizeLatencyMillis;
@@ -389,6 +408,7 @@
         }
 
         /** Sets whether this package is observed and we should prepare change notifications. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIsPackageObserved(boolean isPackageObserved) {
             mIsPackageObserved = isPackageObserved;
@@ -396,6 +416,7 @@
         }
 
         /** Sets latency for the old schema action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setGetOldSchemaLatencyMillis(int getOldSchemaLatencyMillis) {
             mGetOldSchemaLatencyMillis = getOldSchemaLatencyMillis;
@@ -403,6 +424,7 @@
         }
 
         /** Sets latency for the registered observer action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setGetObserverLatencyMillis(int getObserverLatencyMillis) {
             mGetObserverLatencyMillis = getObserverLatencyMillis;
@@ -410,6 +432,7 @@
         }
 
         /** Sets latency for the preparing change notification action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setPreparingChangeNotificationLatencyMillis(
                 int preparingChangeNotificationLatencyMillis) {
@@ -418,6 +441,7 @@
         }
 
         /** Sets the type indicate how this set schema call relative to schema migration cases */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSchemaMigrationCallType(
                 @SchemaMigrationStats.SchemaMigrationCallType int schemaMigrationCallType) {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/FutureUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/FutureUtil.java
index f22ceb0..adbef5e9 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/FutureUtil.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/FutureUtil.java
@@ -28,7 +28,7 @@
 
 /**
  * Utilities for working with {@link com.google.common.util.concurrent.ListenableFuture}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class FutureUtil {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
index 5e4b053..89183f1 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/util/PrefixUtil.java
@@ -32,7 +32,7 @@
 /**
  * Provides utility functions for working with package + database prefixes.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class PrefixUtil {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java
index 1a47109..a22863a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/CallerAccess.java
@@ -23,7 +23,7 @@
 
 /**
  * Contains attributes of an API caller relevant to its access via visibility store.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class CallerAccess {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java
index 7801562..9db52a5 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityChecker.java
@@ -21,7 +21,7 @@
 /**
  * An interface for classes that validate document visibility data.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public interface VisibilityChecker {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
index e3be791..a45cf75 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityDocumentV1.java
@@ -28,7 +28,7 @@
 
 /**
  * Holds the visibility settings in version 1 that apply to a schema type.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 class VisibilityDocumentV1 extends GenericDocument {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
index 957f1be..b44cc3e 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
@@ -55,7 +55,7 @@
  * <p>These visibility settings won't be used in AppSearch Jetpack, we only store them for clients
  * to look up.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityStore {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
index bf1b987..4fb4de9 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0.java
@@ -41,7 +41,7 @@
  * The helper class to store Visibility Document information of version 0 and handle the upgrade to
  * version 1.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityStoreMigrationHelperFromV0 {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java
index cd3e2c5..5a082fc 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1.java
@@ -37,7 +37,7 @@
  * The helper class to store Visibility Document information of version 1 and handle the upgrade to
  * latest version
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityStoreMigrationHelperFromV1 {
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java
index ea04968..69d6a9a 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityUtil.java
@@ -23,7 +23,7 @@
 
 /**
  * Utilities for working with {@link VisibilityChecker} and {@link VisibilityStore}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityUtil {
diff --git a/appsearch/appsearch-platform-storage/build.gradle b/appsearch/appsearch-platform-storage/build.gradle
index 83ec8c6..285ae41 100644
--- a/appsearch/appsearch-platform-storage/build.gradle
+++ b/appsearch/appsearch-platform-storage/build.gradle
@@ -27,7 +27,7 @@
     implementation project(":appsearch:appsearch")
     implementation('androidx.collection:collection:1.2.0')
     implementation("androidx.concurrent:concurrent-futures:1.0.0")
-    implementation("androidx.core:core:1.8.0")
+    implementation(project(":core:core"))
 
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.testRules)
diff --git a/appsearch/appsearch-platform-storage/lint-baseline.xml b/appsearch/appsearch-platform-storage/lint-baseline.xml
index d82c712..dd1d2ee 100644
--- a/appsearch/appsearch-platform-storage/lint-baseline.xml
+++ b/appsearch/appsearch-platform-storage/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR"
+        message="Must be one of: AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR, AppSearchResult.RESULT_DENIED, but could be AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR"
         errorLine1="                            platformResult.getResultCode(), platformResult.getErrorMessage()));"
         errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -12,263 +12,11 @@
 
     <issue
         id="WrongConstant"
-        message="Must be one of: AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR"
+        message="Must be one of: AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR, AppSearchResult.RESULT_DENIED, but could be AppSearchResult.RESULT_OK, AppSearchResult.RESULT_UNKNOWN_ERROR, AppSearchResult.RESULT_INTERNAL_ERROR, AppSearchResult.RESULT_INVALID_ARGUMENT, AppSearchResult.RESULT_IO_ERROR, AppSearchResult.RESULT_OUT_OF_SPACE, AppSearchResult.RESULT_NOT_FOUND, AppSearchResult.RESULT_INVALID_SCHEMA, AppSearchResult.RESULT_SECURITY_ERROR"
         errorLine1="                                            namespaceResult.getResultCode(),"
         errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java"/>
     </issue>
 
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class AppSearchResultToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class BatchResultCallbackAdapter&lt;K, PlatformValue, JetpackValue>"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/util/BatchResultCallbackAdapter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class GenericDocumentToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class GetSchemaResponseToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class GlobalSearchSessionImpl implements GlobalSearchSession {"
-        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class ObserverSpecToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class RequestToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/RequestToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class ResponseToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/ResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SchemaToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SchemaToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SearchContextToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchContextToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SearchResultToPlatformConverter {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class SearchResultsImpl implements SearchResults {"
-        errorLine2="      ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class SearchSessionImpl implements AppSearchSession {"
-        errorLine2="      ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SearchSpecToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchSpecToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SetSchemaRequestToPlatformConverter {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.GetSchemaResponseToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                    platformResponse.getSchemaTypesNotDisplayedBySystem()) {"
-        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.GetSchemaResponseToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                    platformResponse.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {"
-        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.GetSchemaResponseToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                platformResponse.getSchemaTypesVisibleToPackages();"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.GlobalSearchSessionImpl is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="        mPlatformSession.getByDocumentId(packageName, databaseName,"
-        errorLine2="                         ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.GlobalSearchSessionImpl is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="        mPlatformSession.getSchema("
-        errorLine2="                         ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.GlobalSearchSessionImpl is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                mPlatformSession.registerObserverCallback("
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.GlobalSearchSessionImpl is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                mPlatformSession.unregisterObserverCallback(targetPackageName, frameworkCallback);"
-        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.SearchResultToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                            platformMatchInfo.getSubmatchRange().getStart(),"
-        errorLine2="                                              ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.SearchResultToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                            platformMatchInfo.getSubmatchRange().getEnd()));"
-        errorLine2="                                              ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="ClassVerificationFailure"
-        message="This call references a method added in API level 33; however, the containing class androidx.appsearch.platformstorage.converter.SetSchemaRequestToPlatformConverter is reachable from earlier API levels and will fail run-time class verification."
-        errorLine1="                    platformBuilder.addRequiredPermissionsForSchemaTypeVisibility("
-        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="PrereleaseSdkCoreDependency"
-        message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
-        errorLine1="                return BuildCompat.isAtLeastT();"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java"/>
-    </issue>
-
-    <issue
-        id="PrereleaseSdkCoreDependency"
-        message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
-        errorLine1="        if (BuildCompat.isAtLeastT()) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
-    </issue>
-
-    <issue
-        id="PrereleaseSdkCoreDependency"
-        message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
-        errorLine1="        if (BuildCompat.isAtLeastT()) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java"/>
-    </issue>
-
 </issues>
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
index 2f9336e..48c4a66 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java
@@ -15,6 +15,9 @@
  */
 package androidx.appsearch.platformstorage;
 
+import android.annotation.SuppressLint;
+import android.os.Build;
+
 import androidx.annotation.NonNull;
 import androidx.appsearch.app.Features;
 import androidx.core.os.BuildCompat;
@@ -26,7 +29,8 @@
 final class FeaturesImpl implements Features {
 
     @Override
-    // TODO(b/201316758): Remove once BuildCompat.isAtLeastT is removed
+    // TODO(b/265311462): Remove these two lines once BuildCompat.isAtLeastU() is removed
+    @SuppressLint("NewApi")
     @BuildCompat.PrereleaseSdkCheck
     public boolean isFeatureSupported(@NonNull String feature) {
         switch (feature) {
@@ -40,37 +44,35 @@
             case Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK:
                 // fall through
             case Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH:
-                // fall through
-                return BuildCompat.isAtLeastT();
+                return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
 
             // Android U Features
-            case Features.SEARCH_SPEC_PROPERTY_WEIGHTS:
-                // TODO(b/203700301) : Update to reflect support in Android U+ once this feature is
-                // synced over into service-appsearch.
-                // fall through
-            case Features.TOKENIZER_TYPE_RFC822:
-                // TODO(b/259294369) : Update to reflect support in Android U+ once this feature is
-                // synced over into service-appsearch.
-                // fall through
-            case Features.NUMERIC_SEARCH:
-                // TODO(b/259744228) : Update to reflect support in Android U+ once this feature is
-                // synced over into service-appsearch.
-                // fall through
-            case SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION:
-                // TODO(b/261474063) : Update to reflect support in Android U+ once advanced
-                //  ranking becomes available.
-                // fall through
             case Features.JOIN_SPEC_AND_QUALIFIED_ID:
-                // TODO(b/256022027) : Update to reflect support in Android U+ once this feature is
-                // synced over into service-appsearch.
-                // fall through
-            case Features.VERBATIM_SEARCH:
-                // TODO(b/204333391) : Update to reflect support in Android U+ once this feature is
-                // synced over into service-appsearch.
                 // fall through
             case Features.LIST_FILTER_QUERY_LANGUAGE:
-                // TODO(b/208654892) : Update to reflect support in Android U+ once this feature is
+                // fall through
+            case Features.NUMERIC_SEARCH:
+                // fall through
+            case Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION:
+                // fall through
+            case Features.SEARCH_SPEC_PROPERTY_WEIGHTS:
+                // fall through
+            case Features.SEARCH_SUGGESTION:
+                // fall through
+            case Features.TOKENIZER_TYPE_RFC822:
+                // fall through
+            case Features.VERBATIM_SEARCH:
+                // fall through
+            case Features.SET_SCHEMA_CIRCULAR_REFERENCES:
+                return BuildCompat.isAtLeastU();
+
+            // Beyond Android U features
+            case Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA:
+                // TODO(b/258715421) : Update to reflect support in Android U+ once this feature is
                 // synced over into service-appsearch.
+                // fall through
+            case Features.SCHEMA_SET_DELETION_PROPAGATION:
+                // TODO(b/268521214) : Update when feature is ready in service-appsearch.
                 return false;
             default:
                 return false;
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
index 1ee50ec..9cba5df 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/GlobalSearchSessionImpl.java
@@ -16,8 +16,11 @@
 package androidx.appsearch.platformstorage;
 
 import android.annotation.SuppressLint;
+import android.app.appsearch.AppSearchResult;
+import android.app.appsearch.BatchResultCallback;
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
@@ -52,12 +55,13 @@
 
 import java.util.Map;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
- * An implementation of {@link androidx.appsearch.app.GlobalSearchSession} which proxies to a
+ * An implementation of {@link GlobalSearchSession} which proxies to a
  * platform {@link android.app.appsearch.GlobalSearchSession}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -80,7 +84,6 @@
         mFeatures = Preconditions.checkNotNull(features);
     }
 
-    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     @Override
     public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
@@ -95,14 +98,16 @@
         Preconditions.checkNotNull(request);
         ResolvableFuture<AppSearchBatchResult<String, GenericDocument>> future =
                 ResolvableFuture.create();
-        mPlatformSession.getByDocumentId(packageName, databaseName,
-                RequestToPlatformConverter.toPlatformGetByDocumentIdRequest(request),
-                mExecutor,
+        ApiHelperForT.getByDocumentId(mPlatformSession, packageName, databaseName,
+                RequestToPlatformConverter.toPlatformGetByDocumentIdRequest(request), mExecutor,
                 new BatchResultCallbackAdapter<>(
                         future, GenericDocumentToPlatformConverter::toJetpackGenericDocument));
         return future;
     }
 
+    // TODO(b/265311462): Remove these two lines once BuildCompat.isAtLeastU() is removed
+    @SuppressLint("NewApi")
+    @BuildCompat.PrereleaseSdkCheck
     @Override
     @NonNull
     public SearchResults search(
@@ -131,6 +136,8 @@
         return future;
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
     @BuildCompat.PrereleaseSdkCheck
     @NonNull
     @Override
@@ -144,10 +151,7 @@
                             + " is not supported on this AppSearch implementation.");
         }
         ResolvableFuture<GetSchemaResponse> future = ResolvableFuture.create();
-        mPlatformSession.getSchema(
-                packageName,
-                databaseName,
-                mExecutor,
+        ApiHelperForT.getSchema(mPlatformSession, packageName, databaseName, mExecutor,
                 result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
                         result,
                         future,
@@ -161,9 +165,7 @@
         return mFeatures;
     }
 
-    // TODO(b/193494000): Remove these two lines once BuildCompat.isAtLeastT() is removed.
-    @SuppressLint("NewApi")
-    @BuildCompat.PrereleaseSdkCheck
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     @Override
     public void registerObserverCallback(
             @NonNull String targetPackageName,
@@ -213,10 +215,8 @@
             // Regardless of whether this stub was fresh or not, we have to register it again
             // because the user might be supplying a different spec.
             try {
-                mPlatformSession.registerObserverCallback(
-                        targetPackageName,
-                        ObserverSpecToPlatformConverter.toPlatformObserverSpec(spec),
-                        executor,
+                ApiHelperForT.registerObserverCallback(mPlatformSession, targetPackageName,
+                        ObserverSpecToPlatformConverter.toPlatformObserverSpec(spec), executor,
                         frameworkCallback);
             } catch (android.app.appsearch.exceptions.AppSearchException e) {
                 throw new AppSearchException((int) e.getResultCode(), e.getMessage(), e.getCause());
@@ -229,8 +229,6 @@
         }
     }
 
-    @SuppressLint("NewApi")
-    @BuildCompat.PrereleaseSdkCheck
     @Override
     public void unregisterObserverCallback(
             @NonNull String targetPackageName, @NonNull ObserverCallback observer)
@@ -253,7 +251,8 @@
             }
 
             try {
-                mPlatformSession.unregisterObserverCallback(targetPackageName, frameworkCallback);
+                ApiHelperForT.unregisterObserverCallback(mPlatformSession, targetPackageName,
+                        frameworkCallback);
             } catch (android.app.appsearch.exceptions.AppSearchException e) {
                 throw new AppSearchException((int) e.getResultCode(), e.getMessage(), e.getCause());
             }
@@ -267,4 +266,43 @@
     public void close() {
         mPlatformSession.close();
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private static class ApiHelperForT {
+        private ApiHelperForT() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void getByDocumentId(android.app.appsearch.GlobalSearchSession platformSession,
+                String packageName, String databaseName,
+                android.app.appsearch.GetByDocumentIdRequest request, Executor executor,
+                BatchResultCallback<String, android.app.appsearch.GenericDocument> callback) {
+            platformSession.getByDocumentId(packageName, databaseName, request, executor, callback);
+        }
+
+        @DoNotInline
+        static void getSchema(android.app.appsearch.GlobalSearchSession platformSessions,
+                String packageName, String databaseName, Executor executor,
+                Consumer<AppSearchResult<android.app.appsearch.GetSchemaResponse>> callback) {
+            platformSessions.getSchema(packageName, databaseName, executor, callback);
+        }
+
+        @DoNotInline
+        static void registerObserverCallback(
+                android.app.appsearch.GlobalSearchSession platformSession, String targetPackageName,
+                android.app.appsearch.observer.ObserverSpec spec, Executor executor,
+                android.app.appsearch.observer.ObserverCallback observer)
+                throws android.app.appsearch.exceptions.AppSearchException {
+            platformSession.registerObserverCallback(targetPackageName, spec, executor, observer);
+        }
+
+        @DoNotInline
+        static void unregisterObserverCallback(
+                android.app.appsearch.GlobalSearchSession platformSession, String targetPackageName,
+                android.app.appsearch.observer.ObserverCallback observer)
+                throws android.app.appsearch.exceptions.AppSearchException {
+            platformSession.unregisterObserverCallback(targetPackageName, observer);
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
index 6fde6d6..e18ae78 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchResultsImpl.java
@@ -40,7 +40,7 @@
 /**
  * Platform implementation of {@link SearchResults} which proxies to the platform's
  * {@link android.app.appsearch.SearchResults}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -58,13 +58,14 @@
         mExecutor = Preconditions.checkNotNull(executor);
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
     @SuppressLint("WrongConstant")
     @Override
     @NonNull
     @BuildCompat.PrereleaseSdkCheck
     public ListenableFuture<List<SearchResult>> getNextPageAsync() {
-        // TODO(b/256022027): add isAtLeastU check after Android U.
-        if (mSearchSpec.getJoinSpec() != null) {
+        if (!BuildCompat.isAtLeastU() && mSearchSpec.getJoinSpec() != null) {
             throw new UnsupportedOperationException("Searching with a SearchSpec containing a "
                     + "JoinSpec is not supported on this AppSearch implementation.");
         }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
index 4e4f3db..e7baf60 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/SearchSessionImpl.java
@@ -15,8 +15,11 @@
  */
 package androidx.appsearch.platformstorage;
 
+import android.annotation.SuppressLint;
+import android.app.appsearch.AppSearchResult;
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
@@ -43,6 +46,8 @@
 import androidx.appsearch.platformstorage.converter.RequestToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.ResponseToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.SearchSpecToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.SearchSuggestionResultToPlatformConverter;
+import androidx.appsearch.platformstorage.converter.SearchSuggestionSpecToPlatformConverter;
 import androidx.appsearch.platformstorage.converter.SetSchemaRequestToPlatformConverter;
 import androidx.appsearch.platformstorage.util.BatchResultCallbackAdapter;
 import androidx.concurrent.futures.ResolvableFuture;
@@ -54,11 +59,12 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * An implementation of {@link AppSearchSession} which proxies to a platform
  * {@link android.app.appsearch.AppSearchSession}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -76,9 +82,11 @@
         mFeatures = Preconditions.checkNotNull(features);
     }
 
+    // TODO(b/265311462): Remove these two lines once BuildCompat.isAtLeastU() is removed
+    @SuppressLint("NewApi")
+    @BuildCompat.PrereleaseSdkCheck
     @Override
     @NonNull
-    @BuildCompat.PrereleaseSdkCheck
     public ListenableFuture<SetSchemaResponse> setSchemaAsync(@NonNull SetSchemaRequest request) {
         Preconditions.checkNotNull(request);
         ResolvableFuture<SetSchemaResponse> future = ResolvableFuture.create();
@@ -93,9 +101,11 @@
         return future;
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @Override
     @NonNull
-    @BuildCompat.PrereleaseSdkCheck
     public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
         ResolvableFuture<GetSchemaResponse> future = ResolvableFuture.create();
         mPlatformSession.getSchema(
@@ -146,6 +156,9 @@
         return future;
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @Override
     @NonNull
     public SearchResults search(
@@ -160,13 +173,34 @@
         return new SearchResultsImpl(platformSearchResults, searchSpec, mExecutor);
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     @Override
     public ListenableFuture<List<SearchSuggestionResult>> searchSuggestionAsync(
-            @NonNull String suggestionQueryExpression, @NonNull SearchSuggestionSpec searchSpec) {
-        // TODO(b/227356108) Implement this after we export to framework.
-        throw new UnsupportedOperationException(
-                "Search Suggestion is not supported on this AppSearch implementation.");
+            @NonNull String suggestionQueryExpression,
+            @NonNull SearchSuggestionSpec searchSuggestionSpec) {
+        Preconditions.checkNotNull(suggestionQueryExpression);
+        Preconditions.checkNotNull(searchSuggestionSpec);
+        if (BuildCompat.isAtLeastU()) {
+            ResolvableFuture<List<SearchSuggestionResult>> future = ResolvableFuture.create();
+            ApiHelperForU.searchSuggestion(
+                    mPlatformSession,
+                    suggestionQueryExpression,
+                    SearchSuggestionSpecToPlatformConverter
+                            .toPlatformSearchSuggestionSpec(searchSuggestionSpec),
+                    mExecutor,
+                    result -> AppSearchResultToPlatformConverter.platformAppSearchResultToFuture(
+                            result,
+                            future,
+                            SearchSuggestionResultToPlatformConverter
+                                    ::toJetpackSearchSuggestionResults));
+            return future;
+        } else {
+            throw new UnsupportedOperationException(
+                    "Search Suggestion is not supported on this AppSearch implementation.");
+        }
     }
 
     @Override
@@ -195,9 +229,11 @@
         return future;
     }
 
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @Override
     @NonNull
-    @BuildCompat.PrereleaseSdkCheck
     public ListenableFuture<Void> removeAsync(
             @NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
         Preconditions.checkNotNull(queryExpression);
@@ -295,4 +331,23 @@
     public void close() {
         mPlatformSession.close();
     }
+
+    @RequiresApi(34)
+    static class ApiHelperForU {
+        private ApiHelperForU() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void searchSuggestion(
+                @NonNull android.app.appsearch.AppSearchSession appSearchSession,
+                @NonNull String suggestionQueryExpression,
+                @NonNull android.app.appsearch.SearchSuggestionSpec searchSuggestionSpec,
+                @NonNull Executor executor,
+                @NonNull Consumer<AppSearchResult<
+                        List<android.app.appsearch.SearchSuggestionResult>>> callback) {
+            appSearchSession.searchSuggestion(suggestionQueryExpression, searchSuggestionSpec,
+                    executor, callback);
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
index a7d6401..70bb21f 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/AppSearchResultToPlatformConverter.java
@@ -34,7 +34,7 @@
 /**
  * Translates {@link androidx.appsearch.app.AppSearchResult} and
  * {@link androidx.appsearch.app.AppSearchBatchResult} to platform versions.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
index 004fcc4..f87ab48 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GenericDocumentToPlatformConverter.java
@@ -27,7 +27,7 @@
 /**
  * Translates between Platform and Jetpack versions of {@link GenericDocument}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java
index 05575ce..17d0d25 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
@@ -32,7 +33,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of {@link GetSchemaResponse}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -43,8 +44,10 @@
      * Translates a platform {@link android.app.appsearch.GetSchemaResponse} into a jetpack
      * {@link GetSchemaResponse}.
      */
-    @NonNull
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
     @BuildCompat.PrereleaseSdkCheck
+    @NonNull
     public static GetSchemaResponse toJetpackGetSchemaResponse(
             @NonNull android.app.appsearch.GetSchemaResponse platformResponse) {
         Preconditions.checkNotNull(platformResponse);
@@ -60,17 +63,18 @@
             jetpackBuilder.addSchema(SchemaToPlatformConverter.toJetpackSchema(platformSchema));
         }
         jetpackBuilder.setVersion(platformResponse.getVersion());
-        if (BuildCompat.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             // Convert schemas not displayed by system
             for (String schemaTypeNotDisplayedBySystem :
-                    platformResponse.getSchemaTypesNotDisplayedBySystem()) {
+                    ApiHelperForT.getSchemaTypesNotDisplayedBySystem(platformResponse)) {
                 jetpackBuilder.addSchemaTypeNotDisplayedBySystem(schemaTypeNotDisplayedBySystem);
             }
             // Convert schemas visible to packages
             convertSchemasVisibleToPackages(platformResponse, jetpackBuilder);
             // Convert schemas visible to permissions
             for (Map.Entry<String, Set<Set<Integer>>> entry :
-                    platformResponse.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {
+                    ApiHelperForT.getRequiredPermissionsForSchemaTypeVisibility(platformResponse)
+                            .entrySet()) {
                 jetpackBuilder.setRequiredPermissionsForSchemaTypeVisibility(entry.getKey(),
                         entry.getValue());
             }
@@ -90,7 +94,7 @@
         //  incorrectly returns {@code null} in some prerelease versions of Android T. Remove
         //  this workaround after the issue is fixed in T.
         Map<String, Set<android.app.appsearch.PackageIdentifier>> schemaTypesVisibleToPackages =
-                platformResponse.getSchemaTypesVisibleToPackages();
+                ApiHelperForT.getSchemaTypesVisibleToPackage(platformResponse);
         if (schemaTypesVisibleToPackages != null) {
             for (Map.Entry<String, Set<android.app.appsearch.PackageIdentifier>> entry
                     : schemaTypesVisibleToPackages.entrySet()) {
@@ -107,4 +111,30 @@
             }
         }
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private static class ApiHelperForT {
+        private ApiHelperForT() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static Set<String> getSchemaTypesNotDisplayedBySystem(
+                android.app.appsearch.GetSchemaResponse platformResponse) {
+            return platformResponse.getSchemaTypesNotDisplayedBySystem();
+        }
+
+        @DoNotInline
+        static Map<String, Set<android.app.appsearch.PackageIdentifier>>
+                getSchemaTypesVisibleToPackage(
+                    android.app.appsearch.GetSchemaResponse platformResponse) {
+            return platformResponse.getSchemaTypesVisibleToPackages();
+        }
+
+        @DoNotInline
+        static Map<String, Set<Set<Integer>>> getRequiredPermissionsForSchemaTypeVisibility(
+                android.app.appsearch.GetSchemaResponse platformResponse) {
+            return platformResponse.getRequiredPermissionsForSchemaTypeVisibility();
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/JoinSpecToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/JoinSpecToPlatformConverter.java
new file mode 100644
index 0000000..9696cec
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/JoinSpecToPlatformConverter.java
@@ -0,0 +1,56 @@
+/*
+ * 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.appsearch.platformstorage.converter;
+
+import android.annotation.SuppressLint;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.JoinSpec;
+import androidx.core.os.BuildCompat;
+import androidx.core.util.Preconditions;
+
+/**
+ * Translates between Platform and Jetpack versions of {@link JoinSpec}.
+ */
+// TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once
+//  SearchSpecToPlatformConverter.toPlatformSearchSpec() removes it. Also, replace literal '34' with
+//  Build.VERSION_CODES.UPSIDE_DOWN_CAKE once the SDK_INT is finalized.
+@BuildCompat.PrereleaseSdkCheck
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@RequiresApi(34)
+public class JoinSpecToPlatformConverter {
+    private JoinSpecToPlatformConverter() {}
+
+    /**
+     * Translates a Jetpack {@link JoinSpec} into a platform {@link android.app.appsearch.JoinSpec}.
+     */
+    @SuppressLint("WrongConstant")
+    @NonNull
+    public static android.app.appsearch.JoinSpec toPlatformJoinSpec(@NonNull JoinSpec jetpackSpec) {
+        Preconditions.checkNotNull(jetpackSpec);
+        return new android.app.appsearch.JoinSpec.Builder(jetpackSpec.getChildPropertyExpression())
+                .setNestedSearch(
+                        jetpackSpec.getNestedQuery(),
+                        SearchSpecToPlatformConverter.toPlatformSearchSpec(
+                                jetpackSpec.getNestedSearchSpec()))
+                .setMaxJoinedResultCount(jetpackSpec.getMaxJoinedResultCount())
+                .setAggregationScoringStrategy(jetpackSpec.getAggregationScoringStrategy())
+                .build();
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java
index 41ca827..0f74189 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ObserverSpecToPlatformConverter.java
@@ -28,7 +28,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of {@link ObserverSpec}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.TIRAMISU)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/RequestToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/RequestToPlatformConverter.java
index d2c35bd..f4b2d43 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/RequestToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/RequestToPlatformConverter.java
@@ -34,7 +34,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of requests.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ResponseToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ResponseToPlatformConverter.java
index e6f1218..c8612c1 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ResponseToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/ResponseToPlatformConverter.java
@@ -26,7 +26,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of responses.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SchemaToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SchemaToPlatformConverter.java
index eba43cf..edc2141 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SchemaToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SchemaToPlatformConverter.java
@@ -19,18 +19,20 @@
 import android.annotation.SuppressLint;
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.appsearch.app.AppSearchSchema;
+import androidx.core.os.BuildCompat;
 import androidx.core.util.Preconditions;
 
 import java.util.List;
 
 /**
- * Translates a jetpack {@link androidx.appsearch.app.AppSearchSchema} into a platform
+ * Translates a jetpack {@link AppSearchSchema} into a platform
  * {@link android.app.appsearch.AppSearchSchema}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -38,9 +40,12 @@
     private SchemaToPlatformConverter() {}
 
     /**
-     * Translates a jetpack {@link androidx.appsearch.app.AppSearchSchema} into a platform
+     * Translates a jetpack {@link AppSearchSchema} into a platform
      * {@link android.app.appsearch.AppSearchSchema}.
      */
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once
+    //  toPlatformProperty() doesn't have it either.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     public static android.app.appsearch.AppSearchSchema toPlatformSchema(
             @NonNull AppSearchSchema jetpackSchema) {
@@ -58,8 +63,11 @@
 
     /**
      * Translates a platform {@link android.app.appsearch.AppSearchSchema} to a jetpack
-     * {@link androidx.appsearch.app.AppSearchSchema}.
+     * {@link AppSearchSchema}.
      */
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     public static AppSearchSchema toJetpackSchema(
             @NonNull android.app.appsearch.AppSearchSchema platformSchema) {
@@ -78,6 +86,9 @@
     // Most stringProperty.get calls cause WrongConstant lint errors because the methods are not
     // defined as returning the same constants as the corresponding setter expects, but they do
     @SuppressLint("WrongConstant")
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     private static android.app.appsearch.AppSearchSchema.PropertyConfig toPlatformProperty(
             @NonNull AppSearchSchema.PropertyConfig jetpackProperty) {
@@ -85,34 +96,47 @@
         if (jetpackProperty instanceof AppSearchSchema.StringPropertyConfig) {
             AppSearchSchema.StringPropertyConfig stringProperty =
                     (AppSearchSchema.StringPropertyConfig) jetpackProperty;
-            // TODO(b/256022027): add isAtLeastU check to allow JOINABLE_VALUE_TYPE_QUALIFIED_ID
-            //   after Android U, and set joinable value type to PropertyConfig.
-            if (stringProperty.getJoinableValueType()
-                    == AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID) {
-                throw new UnsupportedOperationException(
-                        "StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID is not supported on "
-                                + "this AppSearch implementation.");
-            }
-            return new android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder(
+            android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder platformBuilder =
+                    new android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder(
                     stringProperty.getName())
                     .setCardinality(stringProperty.getCardinality())
                     .setIndexingType(stringProperty.getIndexingType())
-                    .setTokenizerType(stringProperty.getTokenizerType())
-                    .build();
+                    .setTokenizerType(stringProperty.getTokenizerType());
+            if (stringProperty.getDeletionPropagation()) {
+                // TODO(b/268521214): Update once deletion propagation is available.
+                throw new UnsupportedOperationException("Setting deletion propagation is not "
+                        + "supported on this AppSearch implementation.");
+            }
+
+            if (stringProperty.getJoinableValueType()
+                    == AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID) {
+                if (!BuildCompat.isAtLeastU()) {
+                    throw new UnsupportedOperationException(
+                        "StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID is not supported"
+                                + " on this AppSearch implementation.");
+                }
+                ApiHelperForU.setJoinableValueType(platformBuilder,
+                        stringProperty.getJoinableValueType());
+            }
+            return platformBuilder.build();
         } else if (jetpackProperty instanceof AppSearchSchema.LongPropertyConfig) {
             AppSearchSchema.LongPropertyConfig longProperty =
                     (AppSearchSchema.LongPropertyConfig) jetpackProperty;
-            // TODO(b/259744228): add isAtLeastU check to allow INDEXING_TYPE_RANGE after Android U.
+            android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder longPropertyBuilder =
+                    new android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder(
+                    jetpackProperty.getName())
+                    .setCardinality(jetpackProperty.getCardinality());
             if (longProperty.getIndexingType()
                     == AppSearchSchema.LongPropertyConfig.INDEXING_TYPE_RANGE) {
-                throw new UnsupportedOperationException(
-                    "LongProperty.INDEXING_TYPE_RANGE is not supported on this AppSearch "
-                            + "implementation.");
+                if (!BuildCompat.isAtLeastU()) {
+                    throw new UnsupportedOperationException(
+                        "LongProperty.INDEXING_TYPE_RANGE is not supported on this AppSearch "
+                                + "implementation.");
+                }
+                ApiHelperForU.setIndexingType(
+                        longPropertyBuilder, longProperty.getIndexingType());
             }
-            return new android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder(
-                    jetpackProperty.getName())
-                    .setCardinality(jetpackProperty.getCardinality())
-                    .build();
+            return longPropertyBuilder.build();
         } else if (jetpackProperty instanceof AppSearchSchema.DoublePropertyConfig) {
             return new android.app.appsearch.AppSearchSchema.DoublePropertyConfig.Builder(
                     jetpackProperty.getName())
@@ -145,6 +169,9 @@
     // Most stringProperty.get calls cause WrongConstant lint errors because the methods are not
     // defined as returning the same constants as the corresponding setter expects, but they do
     @SuppressLint("WrongConstant")
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     private static AppSearchSchema.PropertyConfig toJetpackProperty(
             @NonNull android.app.appsearch.AppSearchSchema.PropertyConfig platformProperty) {
@@ -153,16 +180,28 @@
                 instanceof android.app.appsearch.AppSearchSchema.StringPropertyConfig) {
             android.app.appsearch.AppSearchSchema.StringPropertyConfig stringProperty =
                     (android.app.appsearch.AppSearchSchema.StringPropertyConfig) platformProperty;
-            return new AppSearchSchema.StringPropertyConfig.Builder(stringProperty.getName())
-                    .setCardinality(stringProperty.getCardinality())
-                    .setIndexingType(stringProperty.getIndexingType())
-                    .setTokenizerType(stringProperty.getTokenizerType())
-                    .build();
+            AppSearchSchema.StringPropertyConfig.Builder jetpackBuilder =
+                    new AppSearchSchema.StringPropertyConfig.Builder(stringProperty.getName())
+                            .setCardinality(stringProperty.getCardinality())
+                            .setIndexingType(stringProperty.getIndexingType())
+                            .setTokenizerType(stringProperty.getTokenizerType());
+            if (BuildCompat.isAtLeastU()) {
+                jetpackBuilder.setJoinableValueType(
+                        ApiHelperForU.getJoinableValueType(stringProperty));
+            }
+            return jetpackBuilder.build();
         } else if (platformProperty
                 instanceof android.app.appsearch.AppSearchSchema.LongPropertyConfig) {
-            return new AppSearchSchema.LongPropertyConfig.Builder(platformProperty.getName())
-                    .setCardinality(platformProperty.getCardinality())
-                    .build();
+            android.app.appsearch.AppSearchSchema.LongPropertyConfig longProperty =
+                    (android.app.appsearch.AppSearchSchema.LongPropertyConfig) platformProperty;
+            AppSearchSchema.LongPropertyConfig.Builder jetpackBuilder =
+                    new AppSearchSchema.LongPropertyConfig.Builder(longProperty.getName())
+                            .setCardinality(longProperty.getCardinality());
+            if (BuildCompat.isAtLeastU()) {
+                jetpackBuilder.setIndexingType(
+                        ApiHelperForU.getIndexingType(longProperty));
+            }
+            return jetpackBuilder.build();
         } else if (platformProperty
                 instanceof android.app.appsearch.AppSearchSchema.DoublePropertyConfig) {
             return new AppSearchSchema.DoublePropertyConfig.Builder(platformProperty.getName())
@@ -194,4 +233,47 @@
                             + ": " + platformProperty);
         }
     }
+
+    // TODO(b/265311462): Replace literal '34' with Build.VERSION_CODES.UPSIDE_DOWN_CAKE when the
+    // SDK_INT is finalized.
+    @RequiresApi(34)
+    private static class ApiHelperForU {
+        private ApiHelperForU() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void setJoinableValueType(
+                android.app.appsearch.AppSearchSchema.StringPropertyConfig.Builder builder,
+                @AppSearchSchema.StringPropertyConfig.JoinableValueType int joinableValueType) {
+            builder.setJoinableValueType(joinableValueType);
+        }
+
+        // Most stringProperty.get calls cause WrongConstant lint errors because the methods are not
+        // defined as returning the same constants as the corresponding setter expects, but they do
+        @SuppressLint("WrongConstant")
+        @DoNotInline
+        @AppSearchSchema.StringPropertyConfig.JoinableValueType
+        static int getJoinableValueType(
+                android.app.appsearch.AppSearchSchema.StringPropertyConfig stringPropertyConfig) {
+            return stringPropertyConfig.getJoinableValueType();
+        }
+
+        @DoNotInline
+        static void setIndexingType(
+                android.app.appsearch.AppSearchSchema.LongPropertyConfig.Builder builder,
+                @AppSearchSchema.LongPropertyConfig.IndexingType int longIndexingType) {
+            builder.setIndexingType(longIndexingType);
+        }
+
+        // Most LongProperty.get calls cause WrongConstant lint errors because the methods are not
+        // defined as returning the same constants as the corresponding setter expects, but they do
+        @SuppressLint("WrongConstant")
+        @DoNotInline
+        @AppSearchSchema.LongPropertyConfig.IndexingType
+        static int getIndexingType(
+                android.app.appsearch.AppSearchSchema.LongPropertyConfig longPropertyConfig) {
+            return longPropertyConfig.getIndexingType();
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchContextToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchContextToPlatformConverter.java
index 49b0564..37b1526 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchContextToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchContextToPlatformConverter.java
@@ -28,7 +28,7 @@
 /**
  * Translates a Jetpack {@link androidx.appsearch.platformstorage.PlatformStorage.SearchContext}
  * into a platform {@link android.app.appsearch.AppSearchManager.SearchContext}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
index 707234d..a44ed5d 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
@@ -30,7 +31,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of {@link SearchResult}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -38,6 +39,8 @@
     private SearchResultToPlatformConverter() {}
 
     /** Translates from Platform to Jetpack versions of {@link SearchResult}. */
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
     @BuildCompat.PrereleaseSdkCheck
     @NonNull
     public static SearchResult toJetpackSearchResult(
@@ -55,10 +58,15 @@
             SearchResult.MatchInfo jetpackMatchInfo = toJetpackMatchInfo(platformMatches.get(i));
             builder.addMatchInfo(jetpackMatchInfo);
         }
+        if (BuildCompat.isAtLeastU()) {
+            for (android.app.appsearch.SearchResult joinedResult :
+                    ApiHelperForU.getJoinedResults(platformResult)) {
+                builder.addJoinedResult(toJetpackSearchResult(joinedResult));
+            }
+        }
         return builder.build();
     }
 
-    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     private static SearchResult.MatchInfo toJetpackMatchInfo(
             @NonNull android.app.appsearch.SearchResult.MatchInfo platformMatchInfo) {
@@ -73,12 +81,46 @@
                         new SearchResult.MatchRange(
                                 platformMatchInfo.getSnippetRange().getStart(),
                                 platformMatchInfo.getSnippetRange().getEnd()));
-        if (BuildCompat.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             builder.setSubmatchRange(
                     new SearchResult.MatchRange(
-                            platformMatchInfo.getSubmatchRange().getStart(),
-                            platformMatchInfo.getSubmatchRange().getEnd()));
+                            ApiHelperForT.getSubmatchRangeStart(platformMatchInfo),
+                            ApiHelperForT.getSubmatchRangeEnd(platformMatchInfo)));
         }
         return builder.build();
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private static class ApiHelperForT {
+        private ApiHelperForT() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static int getSubmatchRangeStart(@NonNull
+                android.app.appsearch.SearchResult.MatchInfo platformMatchInfo) {
+            return platformMatchInfo.getSubmatchRange().getStart();
+        }
+
+        @DoNotInline
+        static int getSubmatchRangeEnd(@NonNull
+                android.app.appsearch.SearchResult.MatchInfo platformMatchInfo) {
+            return platformMatchInfo.getSubmatchRange().getEnd();
+        }
+    }
+
+    // TODO(b/265311462): Replace literal '34' with Build.VERSION_CODES.UPSIDE_DOWN_CAKE when the
+    // SDK_INT is finalized.
+    @RequiresApi(34)
+    private static class ApiHelperForU {
+        private ApiHelperForU() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static List<android.app.appsearch.SearchResult> getJoinedResults(@NonNull
+                android.app.appsearch.SearchResult result) {
+            return result.getJoinedResults();
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSpecToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSpecToPlatformConverter.java
index cc2bd0a..2bfa48b 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSpecToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSpecToPlatformConverter.java
@@ -19,11 +19,14 @@
 import android.annotation.SuppressLint;
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.appsearch.app.Features;
+import androidx.appsearch.app.JoinSpec;
 import androidx.appsearch.app.SearchSpec;
+import androidx.core.os.BuildCompat;
 import androidx.core.util.Preconditions;
 
 import java.util.List;
@@ -32,7 +35,7 @@
 /**
  * Translates between Platform and Jetpack versions of {@link SearchSpec}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -44,35 +47,50 @@
     // Most jetpackSearchSpec.get calls cause WrongConstant lint errors because the methods are not
     // defined as returning the same constants as the corresponding setter expects, but they do
     @SuppressLint("WrongConstant")
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
+    @BuildCompat.PrereleaseSdkCheck
     @NonNull
     public static android.app.appsearch.SearchSpec toPlatformSearchSpec(
             @NonNull SearchSpec jetpackSearchSpec) {
         Preconditions.checkNotNull(jetpackSearchSpec);
 
-        if (!jetpackSearchSpec.getAdvancedRankingExpression().isEmpty()) {
-            // TODO(b/261474063): Remove this once advanced ranking becomes available.
-            throw new UnsupportedOperationException(
-                    Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION
-                            + " is not available on this AppSearch implementation.");
-        }
-
         android.app.appsearch.SearchSpec.Builder platformBuilder =
                 new android.app.appsearch.SearchSpec.Builder();
 
+        if (!jetpackSearchSpec.getAdvancedRankingExpression().isEmpty()) {
+            if (!BuildCompat.isAtLeastU()) {
+                throw new UnsupportedOperationException(
+                        Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION
+                                + " is not available on this AppSearch implementation.");
+            }
+            ApiHelperForU.setRankingStrategy(
+                    platformBuilder, jetpackSearchSpec.getAdvancedRankingExpression());
+        } else {
+            platformBuilder.setRankingStrategy(jetpackSearchSpec.getRankingStrategy());
+        }
+
         platformBuilder
                 .setTermMatch(jetpackSearchSpec.getTermMatch())
                 .addFilterSchemas(jetpackSearchSpec.getFilterSchemas())
                 .addFilterNamespaces(jetpackSearchSpec.getFilterNamespaces())
                 .addFilterPackageNames(jetpackSearchSpec.getFilterPackageNames())
                 .setResultCountPerPage(jetpackSearchSpec.getResultCountPerPage())
-                .setRankingStrategy(jetpackSearchSpec.getRankingStrategy())
                 .setOrder(jetpackSearchSpec.getOrder())
                 .setSnippetCount(jetpackSearchSpec.getSnippetCount())
                 .setSnippetCountPerProperty(jetpackSearchSpec.getSnippetCountPerProperty())
                 .setMaxSnippetSize(jetpackSearchSpec.getMaxSnippetSize());
-        //TODO(b/262512396): add the enabledFeatures set from the SearchSpec once it is synced
-        // across to platform.
         if (jetpackSearchSpec.getResultGroupingTypeFlags() != 0) {
+            // TODO(b/258715421): Add Build.VERSION.SDK_INT condition once
+            // SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA is supported on Android U.
+            if (true) {
+                if ((jetpackSearchSpec.getResultGroupingTypeFlags()
+                        & SearchSpec.GROUPING_TYPE_PER_SCHEMA) != 0) {
+                    throw new UnsupportedOperationException(
+                        Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA
+                            + " is not available on this AppSearch implementation.");
+                }
+            }
             platformBuilder.setResultGrouping(
                     jetpackSearchSpec.getResultGroupingTypeFlags(),
                     jetpackSearchSpec.getResultGroupingLimit());
@@ -82,13 +100,82 @@
             platformBuilder.addProjection(projection.getKey(), projection.getValue());
         }
 
-        // TODO(b/203700301) : Update to reflect support in Android U+ once this
-        // feature is synced over into service-appsearch.
         if (!jetpackSearchSpec.getPropertyWeights().isEmpty()) {
-            throw new UnsupportedOperationException(
-                    "Property weights are not supported with this backend/Android API level "
-                            + "combination.");
+            if (!BuildCompat.isAtLeastU()) {
+                throw new UnsupportedOperationException(
+                        "Property weights are not supported with this backend/Android API level "
+                                + "combination.");
+            }
+            ApiHelperForU.setPropertyWeights(platformBuilder,
+                    jetpackSearchSpec.getPropertyWeights());
+        }
+
+        if (!jetpackSearchSpec.getEnabledFeatures().isEmpty()) {
+            if (jetpackSearchSpec.isNumericSearchEnabled()
+                    || jetpackSearchSpec.isVerbatimSearchEnabled()
+                    || jetpackSearchSpec.isListFilterQueryLanguageEnabled()) {
+                if (!BuildCompat.isAtLeastU()) {
+                    throw new UnsupportedOperationException(
+                            "Advanced query features (NUMERIC_SEARCH, VERBATIM_SEARCH and "
+                                    + "LIST_FILTER_QUERY_LANGUAGE) are not supported with this "
+                                    + "backend/Android API level combination.");
+                }
+                ApiHelperForU.copyEnabledFeatures(platformBuilder, jetpackSearchSpec);
+            }
+        }
+
+        if (jetpackSearchSpec.getJoinSpec() != null) {
+            if (!BuildCompat.isAtLeastU()) {
+                throw new UnsupportedOperationException("JoinSpec is not available on this "
+                        + "AppSearch implementation.");
+            }
+            ApiHelperForU.setJoinSpec(platformBuilder, jetpackSearchSpec.getJoinSpec());
         }
         return platformBuilder.build();
     }
+
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed. Also, replace literal '34' with
+    //  Build.VERSION_CODES.UPSIDE_DOWN_CAKE once the SDK_INT is finalized.
+    @BuildCompat.PrereleaseSdkCheck
+    @RequiresApi(34)
+    private static class ApiHelperForU {
+        private ApiHelperForU() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void setJoinSpec(@NonNull android.app.appsearch.SearchSpec.Builder builder,
+                JoinSpec jetpackJoinSpec) {
+            builder.setJoinSpec(JoinSpecToPlatformConverter.toPlatformJoinSpec(jetpackJoinSpec));
+        }
+
+        @DoNotInline
+        static void setRankingStrategy(@NonNull android.app.appsearch.SearchSpec.Builder builder,
+                @NonNull String rankingExpression) {
+            builder.setRankingStrategy(rankingExpression);
+        }
+
+        @DoNotInline
+        static void copyEnabledFeatures(@NonNull android.app.appsearch.SearchSpec.Builder builder,
+                @NonNull SearchSpec jetpackSpec) {
+            if (jetpackSpec.isNumericSearchEnabled()) {
+                builder.setNumericSearchEnabled(true);
+            }
+            if (jetpackSpec.isVerbatimSearchEnabled()) {
+                builder.setVerbatimSearchEnabled(true);
+            }
+            if (jetpackSpec.isListFilterQueryLanguageEnabled()) {
+                builder.setListFilterQueryLanguageEnabled(true);
+            }
+        }
+
+        @DoNotInline
+        static void setPropertyWeights(@NonNull android.app.appsearch.SearchSpec.Builder builder,
+                @NonNull Map<String, Map<String, Double>> propertyWeightsMap) {
+            for (Map.Entry<String, Map<String, Double>> entry : propertyWeightsMap.entrySet()) {
+                builder.setPropertyWeights(entry.getKey(), entry.getValue());
+            }
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionResultToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionResultToPlatformConverter.java
new file mode 100644
index 0000000..e2d145b
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionResultToPlatformConverter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.appsearch.platformstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.SearchSuggestionResult;
+import androidx.core.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Translates between Platform and Jetpack versions of {@link SearchSuggestionResult}.
+ *
+ * @exportToFramework:hide
+ */
+// TODO(b/227356108) replace literal '34' with Build.VERSION_CODES.U once the SDK_INT is finalized.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@RequiresApi(34)
+public class SearchSuggestionResultToPlatformConverter {
+    private SearchSuggestionResultToPlatformConverter() {}
+
+    /** Translates from Platform to Jetpack versions of {@linkSearchSuggestionResult}   */
+    @NonNull
+    public static List<SearchSuggestionResult> toJetpackSearchSuggestionResults(
+            @NonNull List<android.app.appsearch.SearchSuggestionResult>
+                    platformSearchSuggestionResults) {
+        Preconditions.checkNotNull(platformSearchSuggestionResults);
+        List<SearchSuggestionResult> jetpackSearchSuggestionResults =
+                new ArrayList<>(platformSearchSuggestionResults.size());
+        for (int i = 0; i < platformSearchSuggestionResults.size(); i++) {
+            jetpackSearchSuggestionResults.add(new SearchSuggestionResult.Builder()
+                    .setSuggestedResult(platformSearchSuggestionResults.get(i).getSuggestedResult())
+                    .build());
+        }
+        return jetpackSearchSuggestionResults;
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionSpecToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionSpecToPlatformConverter.java
new file mode 100644
index 0000000..8ddbc54
--- /dev/null
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SearchSuggestionSpecToPlatformConverter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appsearch.platformstorage.converter;
+
+import android.annotation.SuppressLint;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.SearchSuggestionSpec;
+import androidx.core.util.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Translates between Platform and Jetpack versions of {@link SearchSuggestionSpec}.
+ *
+ * @exportToFramework:hide
+ */
+// TODO(b/227356108) replace literal '34' with Build.VERSION_CODES.U once the SDK_INT is finalized.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@RequiresApi(34)
+public final class SearchSuggestionSpecToPlatformConverter {
+    private SearchSuggestionSpecToPlatformConverter() {
+    }
+
+    /** Translates from Jetpack to Platform version of {@link SearchSuggestionSpec}. */
+    // Most jetpackSearchSuggestionSpec.get calls cause WrongConstant lint errors because the
+    // methods are not defined as returning the same constants as the corresponding setter
+    // expects, but they do
+    @SuppressLint("WrongConstant")
+    @NonNull
+    public static android.app.appsearch.SearchSuggestionSpec toPlatformSearchSuggestionSpec(
+            @NonNull SearchSuggestionSpec jetpackSearchSuggestionSpec) {
+        Preconditions.checkNotNull(jetpackSearchSuggestionSpec);
+
+        android.app.appsearch.SearchSuggestionSpec.Builder platformBuilder =
+                new android.app.appsearch.SearchSuggestionSpec.Builder(
+                        jetpackSearchSuggestionSpec.getMaximumResultCount());
+
+        platformBuilder
+                .addFilterNamespaces(jetpackSearchSuggestionSpec.getFilterNamespaces())
+                .addFilterSchemas(jetpackSearchSuggestionSpec.getFilterSchemas())
+                .setRankingStrategy(jetpackSearchSuggestionSpec.getRankingStrategy());
+        for (Map.Entry<String, List<String>> documentIdFilters :
+                jetpackSearchSuggestionSpec.getFilterDocumentIds().entrySet()) {
+            platformBuilder.addFilterDocumentIds(documentIdFilters.getKey(),
+                    documentIdFilters.getValue());
+        }
+        return platformBuilder.build();
+    }
+}
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
index 48c3ede..acb91a1 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
@@ -36,7 +37,7 @@
 
 /**
  * Translates between Platform and Jetpack versions of {@link SetSchemaRequest}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
@@ -47,6 +48,8 @@
      * Translates a jetpack {@link SetSchemaRequest} into a platform
      * {@link android.app.appsearch.SetSchemaRequest}.
      */
+    // TODO(b/265311462): Remove BuildCompat.PrereleaseSdkCheck annotation once usage of
+    //  BuildCompat.isAtLeastU() is removed.
     @BuildCompat.PrereleaseSdkCheck
     @NonNull
     public static android.app.appsearch.SetSchemaRequest toPlatformSetSchemaRequest(
@@ -82,7 +85,7 @@
             for (Map.Entry<String, Set<Set<Integer>>> entry :
                     jetpackRequest.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {
                 for (Set<Integer> permissionGroup : entry.getValue()) {
-                    platformBuilder.addRequiredPermissionsForSchemaTypeVisibility(
+                    ApiHelperForT.addRequiredPermissionsForSchemaTypeVisibility(platformBuilder,
                             entry.getKey(), permissionGroup);
                 }
             }
@@ -163,4 +166,18 @@
         }
         return jetpackBuilder.build();
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    private static class ApiHelperForT {
+        private ApiHelperForT() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void addRequiredPermissionsForSchemaTypeVisibility(
+                android.app.appsearch.SetSchemaRequest.Builder platformBuilder,
+                String schemaType, Set<Integer> permissions) {
+            platformBuilder.addRequiredPermissionsForSchemaTypeVisibility(schemaType, permissions);
+        }
+    }
 }
diff --git a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/util/BatchResultCallbackAdapter.java b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/util/BatchResultCallbackAdapter.java
index 226e274..18bde24 100644
--- a/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/util/BatchResultCallbackAdapter.java
+++ b/appsearch/appsearch-platform-storage/src/main/java/androidx/appsearch/platformstorage/util/BatchResultCallbackAdapter.java
@@ -37,7 +37,7 @@
  * @param <PlatformValue> The type of value in the Framework's
  *                        {@link android.app.appsearch.AppSearchBatchResult}.
  * @param <JetpackValue>  The type of value in Jetpack's {@link AppSearchBatchResult}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 @RequiresApi(Build.VERSION_CODES.S)
diff --git a/appsearch/appsearch-play-services-storage/api/current.txt b/appsearch/appsearch-play-services-storage/api/current.txt
new file mode 100644
index 0000000..8d9c55f
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/api/current.txt
@@ -0,0 +1,27 @@
+// Signature format: 4.0
+package androidx.appsearch.playservicesstorage {
+
+  public final class PlayServicesStorage {
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSessionAsync(androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext);
+  }
+
+  public static final class PlayServicesStorage.GlobalSearchContext {
+  }
+
+  public static final class PlayServicesStorage.GlobalSearchContext.Builder {
+    ctor public PlayServicesStorage.GlobalSearchContext.Builder(android.content.Context);
+    method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext build();
+  }
+
+  public static final class PlayServicesStorage.SearchContext {
+    method public String getDatabaseName();
+  }
+
+  public static final class PlayServicesStorage.SearchContext.Builder {
+    ctor public PlayServicesStorage.SearchContext.Builder(android.content.Context, String);
+    method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext build();
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/appsearch/appsearch-play-services-storage/api/res-current.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to appsearch/appsearch-play-services-storage/api/res-current.txt
diff --git a/appsearch/appsearch-play-services-storage/api/restricted_current.txt b/appsearch/appsearch-play-services-storage/api/restricted_current.txt
new file mode 100644
index 0000000..8d9c55f
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/api/restricted_current.txt
@@ -0,0 +1,27 @@
+// Signature format: 4.0
+package androidx.appsearch.playservicesstorage {
+
+  public final class PlayServicesStorage {
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.GlobalSearchSession!> createGlobalSearchSessionAsync(androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.AppSearchSession!> createSearchSessionAsync(androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext);
+  }
+
+  public static final class PlayServicesStorage.GlobalSearchContext {
+  }
+
+  public static final class PlayServicesStorage.GlobalSearchContext.Builder {
+    ctor public PlayServicesStorage.GlobalSearchContext.Builder(android.content.Context);
+    method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext build();
+  }
+
+  public static final class PlayServicesStorage.SearchContext {
+    method public String getDatabaseName();
+  }
+
+  public static final class PlayServicesStorage.SearchContext.Builder {
+    ctor public PlayServicesStorage.SearchContext.Builder(android.content.Context, String);
+    method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext build();
+  }
+
+}
+
diff --git a/appsearch/appsearch-play-services-storage/build.gradle b/appsearch/appsearch-play-services-storage/build.gradle
new file mode 100644
index 0000000..042eb5d
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/build.gradle
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+}
+
+dependencies {
+    implementation project(":appsearch:appsearch")
+    // TODO(b/278583111) Swap with the core library version in which Function gets added.
+    implementation project(":core:core")
+    implementation("androidx.concurrent:concurrent-futures:1.0.0")
+    implementation('androidx.collection:collection:1.2.0')
+    implementation("com.google.android.gms:play-services-appsearch:16.0.0", {
+        exclude group: "androidx.fragment", module: "fragment"
+        exclude group: "androidx.core", module: "core"
+    })
+
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.truth)
+    androidTestImplementation(libs.junit)
+}
+
+androidx {
+    name = "AppSearch Play Services Storage"
+    publish = Publish.SNAPSHOT_AND_RELEASE
+    inceptionYear = "2023"
+    description =
+            "An implementation of AppSearchSession and GlobalSearchSession on pre-S devices using " +
+                    "play-services-appsearch SDK with Gogle Play Services as storage backend."
+}
+
+android {
+    namespace "androidx.appsearch.playservicesstorage"
+}
diff --git a/appsearch/appsearch-play-services-storage/src/androidTest/AndroidManifest.xml b/appsearch/appsearch-play-services-storage/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..0cd568b
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+</manifest>
\ No newline at end of file
diff --git a/appsearch/appsearch-play-services-storage/src/androidTest/java/androidx/appsearch/playservicesstorage/PlayServicesStorageTest.java b/appsearch/appsearch-play-services-storage/src/androidTest/java/androidx/appsearch/playservicesstorage/PlayServicesStorageTest.java
new file mode 100644
index 0000000..0f4db6d
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/androidTest/java/androidx/appsearch/playservicesstorage/PlayServicesStorageTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.appsearch.playservicesstorage;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Test;
+
+public class PlayServicesStorageTest {
+    @Test
+    public void testSearchContext_databaseName() {
+        PlayServicesStorage.SearchContext searchContext =
+                new PlayServicesStorage.SearchContext.Builder(
+                        ApplicationProvider.getApplicationContext(),
+                        /*databaseName=*/"dbName").build();
+
+        assertThat(searchContext.getDatabaseName()).isEqualTo("dbName");
+    }
+
+    @Test
+    public void testSearchContext_withInvalidDatabaseName() {
+        // Test special character can present in database name. When a special character is banned
+        // in database name, add checker in SearchContext.Builder and reflect it in java doc.
+
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new PlayServicesStorage.SearchContext.Builder(
+                        ApplicationProvider.getApplicationContext(),
+                        "testDatabaseNameEndWith/").build());
+        assertThat(e).hasMessageThat().isEqualTo("Database name cannot contain '/'");
+        e = assertThrows(IllegalArgumentException.class,
+                () -> new PlayServicesStorage.SearchContext.Builder(
+                        ApplicationProvider.getApplicationContext(),
+                        "/testDatabaseNameStartWith").build());
+        assertThat(e).hasMessageThat().isEqualTo("Database name cannot contain '/'");
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/AndroidManifest.xml b/appsearch/appsearch-play-services-storage/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8a693a4
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest />
\ No newline at end of file
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/FeaturesImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/FeaturesImpl.java
new file mode 100644
index 0000000..2441e57d
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/FeaturesImpl.java
@@ -0,0 +1,79 @@
+/*
+ * 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.appsearch.playservicesstorage;
+
+import androidx.annotation.NonNull;
+import androidx.appsearch.app.Features;
+
+/**
+ * An implementation of {@link Features}. Feature availability is dependent on Android API
+ * level and GMSCore AppSearch module.
+ */
+final class FeaturesImpl implements Features {
+    @Override
+    public boolean isFeatureSupported(@NonNull String feature) {
+        // TODO(b/274986359): Update based on features available in {@link Features} and those
+        //  supported by play-services-appsearch.
+        switch (feature) {
+            // Android T Features
+            case Features.ADD_PERMISSIONS_AND_GET_VISIBILITY:
+                // fall through
+            case Features.GLOBAL_SEARCH_SESSION_GET_SCHEMA:
+                // fall through
+            case Features.GLOBAL_SEARCH_SESSION_GET_BY_ID:
+                // fall through
+            case Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH:
+                // fall through
+                return true; // AppSearch features in T, present in GMSCore AppSearch.
+
+            // RegisterObserver and UnregisterObserver are not yet supported by GMSCore AppSearch.
+            // TODO(b/208654892) : Update to reflect support once this feature is supported.
+            case Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK:
+            // Android U Features
+            case Features.SEARCH_SPEC_PROPERTY_WEIGHTS:
+                // TODO(b/203700301) : Update to reflect support in Android U+ once this feature is
+                //  synced over into service-appsearch.
+                // fall through
+            case Features.TOKENIZER_TYPE_RFC822:
+                // TODO(b/259294369) : Update to reflect support in Android U+ once this feature is
+                //  synced over into service-appsearch.
+                // fall through
+            case Features.NUMERIC_SEARCH:
+                // TODO(b/259744228) : Update to reflect support in Android U+ once this feature is
+                // synced over into service-appsearch.
+                // fall through
+            case SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION:
+                // TODO(b/261474063) : Update to reflect support in Android U+ once advanced
+                //  ranking becomes available.
+                // fall through
+            case Features.JOIN_SPEC_AND_QUALIFIED_ID:
+                // TODO(b/256022027) : Update to reflect support in Android U+ once this feature is
+                //  synced over into service-appsearch.
+                // fall through
+            case Features.VERBATIM_SEARCH:
+                // TODO(b/204333391) : Update to reflect support in Android U+ once this feature is
+                //  synced over into service-appsearch.
+                // fall through
+            case Features.LIST_FILTER_QUERY_LANGUAGE:
+                // TODO(b/208654892) : Update to reflect support in Android U+ once this feature is
+                //  synced over into service-appsearch.
+                return false;
+            default:
+                return false; // AppSearch features in U+, absent in GMSCore AppSearch.
+        }
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java
new file mode 100644
index 0000000..dc693e8
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.appsearch.playservicesstorage;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchBatchResult;
+import androidx.appsearch.app.Features;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.GlobalSearchSession;
+import androidx.appsearch.app.ReportSystemUsageRequest;
+import androidx.appsearch.app.SearchResults;
+import androidx.appsearch.app.SearchSpec;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.observer.ObserverCallback;
+import androidx.appsearch.observer.ObserverSpec;
+import androidx.appsearch.playservicesstorage.converter.AppSearchResultToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.GenericDocumentToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.GetSchemaResponseToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.RequestToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.SearchSpecToGmsConverter;
+import androidx.appsearch.playservicesstorage.util.AppSearchTaskFutures;
+import androidx.core.util.Preconditions;
+
+import com.google.android.gms.appsearch.GlobalSearchClient;
+import com.google.android.gms.tasks.Task;
+import com.google.android.gms.tasks.Tasks;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.concurrent.Executor;
+
+/**
+ * An implementation of {@link GlobalSearchSession} which proxies to a Google Play Service's
+ * {@link GlobalSearchClient}.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class GlobalSearchSessionImpl implements GlobalSearchSession {
+
+    private final GlobalSearchClient mGmsClient;
+    private final Features mFeatures;
+
+    GlobalSearchSessionImpl(
+            @NonNull GlobalSearchClient gmsClient,
+            @NonNull Features features) {
+        mGmsClient = Preconditions.checkNotNull(gmsClient);
+        mFeatures = Preconditions.checkNotNull(features);
+    }
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
+            @NonNull String packageName, @NonNull String databaseName,
+            @NonNull GetByDocumentIdRequest request) {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getByDocumentId(packageName, databaseName,
+                        RequestToGmsConverter.toGmsGetByDocumentIdRequest(request)),
+                result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack(
+                        result, GenericDocumentToGmsConverter::toJetpackGenericDocument));
+    }
+
+    @NonNull
+    @Override
+    public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
+        com.google.android.gms.appsearch.SearchResults searchResults =
+                mGmsClient.search(queryExpression,
+                        SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec));
+        return new SearchResultsImpl(searchResults, searchSpec);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<Void> reportSystemUsageAsync(
+            @NonNull ReportSystemUsageRequest request) {
+        Task<Void> flushTask = Tasks.forResult(null);
+        return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync(@NonNull String packageName,
+            @NonNull String databaseName) {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getSchema(packageName, databaseName),
+                GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse);
+    }
+
+    @NonNull
+    @Override
+    public Features getFeatures() {
+        return mFeatures;
+    }
+
+    @Override
+    public void registerObserverCallback(@NonNull String targetPackageName,
+            @NonNull ObserverSpec spec, @NonNull Executor executor,
+            @NonNull ObserverCallback observer) throws AppSearchException {
+        // TODO(b/274986359): Implement registerObserverCallback for PlayServicesStorage.
+        throw new UnsupportedOperationException(
+                "registerObserverCallback is not yet supported on this AppSearch implementation.");
+    }
+
+    @Override
+    public void unregisterObserverCallback(@NonNull String targetPackageName,
+            @NonNull ObserverCallback observer) throws AppSearchException {
+        // TODO(b/274986359): Implement unregisterObserverCallback for PlayServicesStorage.
+        throw new UnsupportedOperationException(
+                "unregisterObserverCallback is not yet supported on this "
+                        + "AppSearch implementation.");
+    }
+
+    @Override
+    public void close() {
+        mGmsClient.close();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java
new file mode 100644
index 0000000..eab92f9
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java
@@ -0,0 +1,157 @@
+/*
+ * 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.appsearch.playservicesstorage;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.appsearch.app.AppSearchSession;
+import androidx.appsearch.app.GlobalSearchSession;
+import androidx.appsearch.playservicesstorage.util.AppSearchTaskFutures;
+import androidx.core.util.Preconditions;
+
+import com.google.android.gms.appsearch.AppSearch;
+import com.google.android.gms.appsearch.AppSearchClient;
+import com.google.android.gms.appsearch.GlobalSearchClient;
+import com.google.android.gms.tasks.Task;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * An AppSearch storage system which stores data in the central AppSearch service in Google
+ * Play Services.
+ */
+public final class PlayServicesStorage {
+
+    private PlayServicesStorage() {
+    }
+
+    /** Contains information about how to create the search session. */
+    public static final class SearchContext {
+        final Context mContext;
+        final String mDatabaseName;
+
+        SearchContext(@NonNull Context context, @NonNull String databaseName) {
+            mContext = Preconditions.checkNotNull(context);
+            mDatabaseName = Preconditions.checkNotNull(databaseName);
+        }
+
+        /**
+         * Returns the name of the database to create or open.
+         */
+        @NonNull
+        public String getDatabaseName() {
+            return mDatabaseName;
+        }
+
+        /** Builder for {@link SearchContext} objects. */
+        public static final class Builder {
+            private final Context mContext;
+            private final String mDatabaseName;
+
+            /**
+             * Creates a {@link SearchContext.Builder} instance.
+             *
+             * <p>{@link AppSearchSession} will create or open a database under the given name.
+             *
+             * <p>Databases with different names are fully separate with distinct schema types,
+             * namespaces, and documents.
+             *
+             * <p>The database name cannot contain {@code '/'}.
+             *
+             * <p>The database name will be visible to all system UI or third-party applications
+             * that have been granted access to any of the database's documents (for example,
+             * using {@link
+             * androidx.appsearch.app.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage}).
+             *
+             * @param databaseName The name of the database.
+             * @throws IllegalArgumentException if the databaseName contains {@code '/'}.
+             */
+            public Builder(@NonNull Context context, @NonNull String databaseName) {
+                mContext = Preconditions.checkNotNull(context);
+                Preconditions.checkNotNull(databaseName);
+                if (databaseName.contains("/")) {
+                    throw new IllegalArgumentException("Database name cannot contain '/'");
+                }
+                mDatabaseName = databaseName;
+            }
+
+            /** Builds a {@link SearchContext} instance. */
+            @NonNull
+            public SearchContext build() {
+                return new SearchContext(mContext, mDatabaseName);
+            }
+        }
+    }
+
+    /** Contains information relevant to creating a global search session. */
+    public static final class GlobalSearchContext {
+        final Context mContext;
+
+        GlobalSearchContext(@NonNull Context context) {
+            mContext = Preconditions.checkNotNull(context);
+        }
+
+        /** Builder for {@link GlobalSearchContext} objects. */
+        public static final class Builder {
+            private final Context mContext;
+
+            public Builder(@NonNull Context context) {
+                mContext = Preconditions.checkNotNull(context);
+            }
+
+            /** Builds a {@link GlobalSearchContext} instance. */
+            @NonNull
+            public GlobalSearchContext build() {
+                return new GlobalSearchContext(mContext);
+            }
+        }
+    }
+
+    /**
+     * Opens a new {@link AppSearchSession} on this storage.
+     *
+     * @param context The {@link SearchContext} contains all information to create a new
+     *                {@link AppSearchSession}
+     */
+    @NonNull
+    public static ListenableFuture<AppSearchSession> createSearchSessionAsync(
+            @NonNull SearchContext context) {
+        Preconditions.checkNotNull(context);
+        Task<AppSearchClient> appSearchClientTask = AppSearch
+                .createAppSearchClient(context.mContext);
+        return AppSearchTaskFutures.toListenableFuture(
+                appSearchClientTask,
+                task -> new SearchSessionImpl(task, new FeaturesImpl(), context.mDatabaseName));
+    }
+
+    /**
+     * Opens a new {@link GlobalSearchSession} on this storage.
+     *
+     * @param context The {@link GlobalSearchContext} contains all information to create a new
+     *                {@link GlobalSearchSession}
+     */
+    @NonNull
+    public static ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync(
+            @NonNull GlobalSearchContext context) {
+        Preconditions.checkNotNull(context);
+        Task<GlobalSearchClient> globalSearchClientTask = AppSearch
+                .createGlobalSearchClient(context.mContext);
+        return AppSearchTaskFutures.toListenableFuture(
+                globalSearchClientTask,
+                task -> new GlobalSearchSessionImpl(task, new FeaturesImpl()));
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java
new file mode 100644
index 0000000..ba23844
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java
@@ -0,0 +1,60 @@
+/*
+ * 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.appsearch.playservicesstorage;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.SearchResult;
+import androidx.appsearch.app.SearchResults;
+import androidx.appsearch.app.SearchSpec;
+import androidx.appsearch.playservicesstorage.converter.SearchResultToGmsConverter;
+import androidx.appsearch.playservicesstorage.util.AppSearchTaskFutures;
+import androidx.core.util.Preconditions;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.List;
+
+/**
+ * GooglePlayService's implementation of {@link SearchResults} which proxies to the
+ * GooglePlayService's {@link com.google.android.gms.appsearch.SearchResults}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class SearchResultsImpl implements SearchResults {
+    private final com.google.android.gms.appsearch.SearchResults mGmsResults;
+
+    SearchResultsImpl(
+            @NonNull com.google.android.gms.appsearch.SearchResults gmsResults,
+            @NonNull SearchSpec searchSpec) {
+        mGmsResults = Preconditions.checkNotNull(gmsResults);
+    }
+
+    @Override
+    @NonNull
+    public ListenableFuture<List<SearchResult>> getNextPageAsync() {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsResults.getNextPage(),
+                SearchResultToGmsConverter::toJetpackSearchResultList
+        );
+    }
+
+    @Override
+    public void close() {
+        mGmsResults.close();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java
new file mode 100644
index 0000000..e34c08c
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java
@@ -0,0 +1,216 @@
+/*
+ * 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.appsearch.playservicesstorage;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchBatchResult;
+import androidx.appsearch.app.AppSearchSession;
+import androidx.appsearch.app.Features;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PutDocumentsRequest;
+import androidx.appsearch.app.RemoveByDocumentIdRequest;
+import androidx.appsearch.app.ReportUsageRequest;
+import androidx.appsearch.app.SearchResults;
+import androidx.appsearch.app.SearchSpec;
+import androidx.appsearch.app.SearchSuggestionResult;
+import androidx.appsearch.app.SearchSuggestionSpec;
+import androidx.appsearch.app.SetSchemaRequest;
+import androidx.appsearch.app.SetSchemaResponse;
+import androidx.appsearch.app.StorageInfo;
+import androidx.appsearch.playservicesstorage.converter.AppSearchResultToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.GenericDocumentToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.GetSchemaResponseToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.RequestToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.ResponseToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.SearchSpecToGmsConverter;
+import androidx.appsearch.playservicesstorage.converter.SetSchemaRequestToGmsConverter;
+import androidx.appsearch.playservicesstorage.util.AppSearchTaskFutures;
+import androidx.core.util.Preconditions;
+
+import com.google.android.gms.appsearch.AppSearchClient;
+import com.google.android.gms.tasks.Task;
+import com.google.android.gms.tasks.Tasks;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.io.Closeable;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * An implementation of {@link AppSearchSession} which proxies to a Google Play Service's
+ * {@link AppSearchClient}.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class SearchSessionImpl implements AppSearchSession, Closeable {
+    private final AppSearchClient mGmsClient;
+    private final Features mFeatures;
+    private final String mDatabaseName;
+
+
+    SearchSessionImpl(
+            @NonNull AppSearchClient gmsClient,
+            @NonNull Features features,
+            @NonNull String databaseName) {
+        mGmsClient = Preconditions.checkNotNull(gmsClient);
+        mFeatures = Preconditions.checkNotNull(features);
+        mDatabaseName = Preconditions.checkNotNull(databaseName);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<SetSchemaResponse> setSchemaAsync(@NonNull SetSchemaRequest request) {
+        Preconditions.checkNotNull(request);
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.setSchema(
+                        SetSchemaRequestToGmsConverter.toGmsSetSchemaRequest(
+                                request),
+                        mDatabaseName),
+                SetSchemaRequestToGmsConverter::toJetpackSetSchemaResponse);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<GetSchemaResponse> getSchemaAsync() {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getSchema(mDatabaseName),
+                GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<Set<String>> getNamespacesAsync() {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getNamespaces(mDatabaseName),
+                /* valueMapper= */ i -> i);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, Void>> putAsync(
+            @NonNull PutDocumentsRequest request) {
+        Preconditions.checkNotNull(request);
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.put(
+                        RequestToGmsConverter.toGmsPutDocumentsRequest(request),
+                        mDatabaseName),
+                result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack(
+                        result, /* valueMapper= */ i -> i));
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, GenericDocument>> getByDocumentIdAsync(
+            @NonNull GetByDocumentIdRequest request) {
+        Preconditions.checkNotNull(request);
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getByDocumentId(
+                        RequestToGmsConverter.toGmsGetByDocumentIdRequest(request),
+                        mDatabaseName),
+                result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack(
+                                result, GenericDocumentToGmsConverter::toJetpackGenericDocument));
+    }
+
+    @NonNull
+    @Override
+    public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) {
+        Preconditions.checkNotNull(queryExpression);
+        Preconditions.checkNotNull(searchSpec);
+        com.google.android.gms.appsearch.SearchResults gmsSearchResults =
+                mGmsClient.search(
+                        queryExpression,
+                        SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec),
+                        mDatabaseName);
+        return new SearchResultsImpl(gmsSearchResults, searchSpec);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<List<SearchSuggestionResult>> searchSuggestionAsync(
+            @NonNull String suggestionQueryExpression,
+            @NonNull SearchSuggestionSpec searchSuggestionSpec) {
+        // TODO(b/274986359): Implement searchSuggestionAsync for PlayServicesStorage.
+        throw new UnsupportedOperationException(
+                "Search Suggestion is not yet supported on this AppSearch implementation.");
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<Void> reportUsageAsync(@NonNull ReportUsageRequest request) {
+        Preconditions.checkNotNull(request);
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.reportUsage(
+                        RequestToGmsConverter.toGmsReportUsageRequest(request),
+                        mDatabaseName),
+                /* valueMapper= */ i -> i);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<AppSearchBatchResult<String, Void>> removeAsync(
+            @NonNull RemoveByDocumentIdRequest request) {
+        Preconditions.checkNotNull(request);
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.remove(
+                        RequestToGmsConverter
+                                .toGmsRemoveByDocumentIdRequest(request),
+                        mDatabaseName),
+                result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack(
+                        result, /* valueMapper= */ i -> i));
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<Void> removeAsync(@NonNull String queryExpression,
+            @NonNull SearchSpec searchSpec) {
+        Preconditions.checkNotNull(queryExpression);
+        Preconditions.checkNotNull(searchSpec);
+        return AppSearchTaskFutures.toListenableFuture(mGmsClient.remove(
+                        queryExpression,
+                        SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec),
+                        mDatabaseName),
+                /* valueMapper= */ i -> i);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<StorageInfo> getStorageInfoAsync() {
+        return AppSearchTaskFutures.toListenableFuture(
+                mGmsClient.getStorageInfo(mDatabaseName),
+                ResponseToGmsConverter::toJetpackStorageInfo);
+    }
+
+    @NonNull
+    @Override
+    public ListenableFuture<Void> requestFlushAsync() {
+        Task<Void> flushTask = Tasks.forResult(null);
+        return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i);
+    }
+
+    @NonNull
+    @Override
+    public Features getFeatures() {
+        return mFeatures;
+    }
+
+    @Override
+    public void close() {
+        mGmsClient.close();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/AppSearchResultToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/AppSearchResultToGmsConverter.java
new file mode 100644
index 0000000..73aea40
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/AppSearchResultToGmsConverter.java
@@ -0,0 +1,138 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchBatchResult;
+import androidx.appsearch.app.AppSearchResult;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.concurrent.futures.ResolvableFuture;
+import androidx.core.util.Function;
+import androidx.core.util.Preconditions;
+
+import java.util.Map;
+
+/**
+ * Translates {@link androidx.appsearch.app.AppSearchResult} and
+ * {@link androidx.appsearch.app.AppSearchBatchResult} to Gms versions.
+ *
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class AppSearchResultToGmsConverter {
+    private AppSearchResultToGmsConverter() {
+    }
+
+    /**
+     * Converts an {@link com.google.android.gms.appsearch.AppSearchResult} into a jetpack
+     * {@link androidx.appsearch.app.AppSearchResult}.
+     */
+    @NonNull
+    public static <GmsType, JetpackType> AppSearchResult<JetpackType>
+            gmsAppSearchResultToJetpack(
+            @NonNull com.google.android.gms.appsearch.AppSearchResult<GmsType> gmsResult,
+            @NonNull Function<GmsType, JetpackType> valueMapper) {
+        Preconditions.checkNotNull(gmsResult);
+        if (gmsResult.isSuccess()) {
+            try {
+                JetpackType jetpackType = valueMapper.apply(gmsResult.getResultValue());
+                return AppSearchResult.newSuccessfulResult(jetpackType);
+            } catch (Throwable t) {
+                return AppSearchResult.throwableToFailedResult(t);
+            }
+        }
+        return AppSearchResult.newFailedResult(
+                gmsResult.getResultCode(),
+                gmsResult.getErrorMessage());
+    }
+
+    /**
+     * Uses the given {@link com.google.android.gms.appsearch.AppSearchResult} to populate the given
+     * {@link ResolvableFuture}, transforming it using {@code valueMapper}.
+     */
+    public static <GmsType, JetpackType> void
+            gmsAppSearchResultToFuture(
+            @NonNull com.google.android.gms.appsearch.AppSearchResult<GmsType>
+                    gmsResult,
+            @NonNull ResolvableFuture<JetpackType> future,
+            @NonNull Function<GmsType, JetpackType> valueMapper) {
+        Preconditions.checkNotNull(gmsResult);
+        Preconditions.checkNotNull(future);
+        if (gmsResult.isSuccess()) {
+            try {
+                JetpackType jetpackType = valueMapper.apply(gmsResult.getResultValue());
+                future.set(jetpackType);
+            } catch (Throwable t) {
+                future.setException(t);
+            }
+        } else {
+            future.setException(new AppSearchException(
+                    gmsResult.getResultCode(), gmsResult.getErrorMessage()));
+        }
+    }
+
+    /**
+     * Uses the given {@link com.google.android.gms.appsearch.AppSearchResult}
+     * to populate the given {@link ResolvableFuture}.
+     */
+    public static <T> void gmsAppSearchResultToFuture(
+            @NonNull com.google.android.gms.appsearch.AppSearchResult<T> gmsResult,
+            @NonNull ResolvableFuture<T> future) {
+        gmsAppSearchResultToFuture(gmsResult,
+                future,
+                /* valueMapper= */ i -> i);
+    }
+
+    /**
+     * Converts the given Gms
+     * {@link com.google.android.gms.appsearch.AppSearchBatchResult} to a Jetpack
+     * {@link AppSearchBatchResult}.
+     *
+     * <p>Each value is translated using the provided {@code valueMapper} function.
+     */
+    @NonNull
+    public static <K, GmsValue, JetpackValue> AppSearchBatchResult<K,
+            JetpackValue> gmsAppSearchBatchResultToJetpack(
+            @NonNull com.google.android.gms.appsearch.AppSearchBatchResult<K,
+                    GmsValue> gmsResult,
+            @NonNull Function<GmsValue, JetpackValue> valueMapper) {
+        Preconditions.checkNotNull(gmsResult);
+        Preconditions.checkNotNull(valueMapper);
+        AppSearchBatchResult.Builder<K, JetpackValue> jetpackResult =
+                new AppSearchBatchResult.Builder<>();
+        for (Map.Entry<K, GmsValue> success :
+                gmsResult.getSuccesses().entrySet()) {
+            try {
+                JetpackValue jetpackValue = valueMapper.apply(success.getValue());
+                jetpackResult.setSuccess(success.getKey(), jetpackValue);
+            } catch (Throwable t) {
+                jetpackResult.setResult(
+                        success.getKey(), AppSearchResult.throwableToFailedResult(t));
+            }
+        }
+        for (Map.Entry<K,
+                com.google.android.gms.appsearch.AppSearchResult<GmsValue>> failure :
+                gmsResult.getFailures().entrySet()) {
+            jetpackResult.setFailure(
+                    failure.getKey(),
+                    failure.getValue().getResultCode(),
+                    failure.getValue().getErrorMessage());
+        }
+        return jetpackResult.build();
+    }
+}
+
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GenericDocumentToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GenericDocumentToGmsConverter.java
new file mode 100644
index 0000000..2b78fbf
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GenericDocumentToGmsConverter.java
@@ -0,0 +1,131 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.GenericDocument;
+import androidx.core.util.Preconditions;
+
+/**
+ * Translates between Gms and Jetpack versions of {@link GenericDocument}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class GenericDocumentToGmsConverter {
+    private GenericDocumentToGmsConverter() {
+    }
+
+    /**
+     * Translates a jetpack {@link androidx.appsearch.app.GenericDocument} into a Gms
+     * {@link com.google.android.gms.appsearch.GenericDocument}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.GenericDocument toGmsGenericDocument(
+            @NonNull GenericDocument jetpackDocument) {
+        Preconditions.checkNotNull(jetpackDocument);
+        com.google.android.gms.appsearch.GenericDocument.Builder<
+                com.google.android.gms.appsearch.GenericDocument.Builder<?>>
+                gmsBuilder =
+                new com.google.android.gms.appsearch.GenericDocument.Builder<>(
+                        jetpackDocument.getNamespace(),
+                        jetpackDocument.getId(),
+                        jetpackDocument.getSchemaType());
+        gmsBuilder
+                .setScore(jetpackDocument.getScore())
+                .setTtlMillis(jetpackDocument.getTtlMillis())
+                .setCreationTimestampMillis(jetpackDocument.getCreationTimestampMillis());
+        for (String propertyName : jetpackDocument.getPropertyNames()) {
+            Object property = jetpackDocument.getProperty(propertyName);
+            if (property instanceof String[]) {
+                gmsBuilder.setPropertyString(propertyName, (String[]) property);
+            } else if (property instanceof long[]) {
+                gmsBuilder.setPropertyLong(propertyName, (long[]) property);
+            } else if (property instanceof double[]) {
+                gmsBuilder.setPropertyDouble(propertyName, (double[]) property);
+            } else if (property instanceof boolean[]) {
+                gmsBuilder.setPropertyBoolean(propertyName, (boolean[]) property);
+            } else if (property instanceof byte[][]) {
+                byte[][] byteValues = (byte[][]) property;
+                gmsBuilder.setPropertyBytes(propertyName, byteValues);
+            } else if (property instanceof GenericDocument[]) {
+                GenericDocument[] documentValues = (GenericDocument[]) property;
+                com.google.android.gms.appsearch.GenericDocument[] gmsSubDocuments =
+                        new com.google.android.gms.appsearch.GenericDocument[documentValues.length];
+                for (int j = 0; j < documentValues.length; j++) {
+                    gmsSubDocuments[j] = toGmsGenericDocument(documentValues[j]);
+                }
+                gmsBuilder.setPropertyDocument(propertyName,
+                        gmsSubDocuments);
+            } else {
+                throw new IllegalStateException(
+                        String.format("Property \"%s\" has unsupported value type %s",
+                                propertyName,
+                                property.getClass().toString()));
+            }
+        }
+        return gmsBuilder.build();
+    }
+
+    /**
+     * Translates a Gms {@link com.google.android.gms.appsearch.GenericDocument}
+     * into a jetpack {@link androidx.appsearch.app.GenericDocument}.
+     */
+    @NonNull
+    public static GenericDocument toJetpackGenericDocument(
+            @NonNull com.google.android.gms.appsearch.GenericDocument
+                    gmsDocument) {
+        Preconditions.checkNotNull(gmsDocument);
+        GenericDocument.Builder<GenericDocument.Builder<?>> jetpackBuilder =
+                new GenericDocument.Builder<>(
+                        gmsDocument.getNamespace(),
+                        gmsDocument.getId(),
+                        gmsDocument.getSchemaType());
+        jetpackBuilder
+                .setScore(gmsDocument.getScore())
+                .setTtlMillis(gmsDocument.getTtlMillis())
+                .setCreationTimestampMillis(gmsDocument
+                        .getCreationTimestampMillis());
+        for (String propertyName : gmsDocument.getPropertyNames()) {
+            Object property = gmsDocument.getProperty(propertyName);
+            if (property instanceof String[]) {
+                jetpackBuilder.setPropertyString(propertyName, (String[]) property);
+            } else if (property instanceof long[]) {
+                jetpackBuilder.setPropertyLong(propertyName, (long[]) property);
+            } else if (property instanceof double[]) {
+                jetpackBuilder.setPropertyDouble(propertyName, (double[]) property);
+            } else if (property instanceof boolean[]) {
+                jetpackBuilder.setPropertyBoolean(propertyName, (boolean[]) property);
+            } else if (property instanceof byte[][]) {
+                jetpackBuilder.setPropertyBytes(propertyName, (byte[][]) property);
+            } else if (property instanceof com.google.android.gms.appsearch.GenericDocument[]) {
+                com.google.android.gms.appsearch.GenericDocument[] documentValues =
+                        (com.google.android.gms.appsearch.GenericDocument[]) property;
+                GenericDocument[] jetpackSubDocuments = new GenericDocument[documentValues.length];
+                for (int j = 0; j < documentValues.length; j++) {
+                    jetpackSubDocuments[j] = toJetpackGenericDocument(documentValues[j]);
+                }
+                jetpackBuilder.setPropertyDocument(propertyName, jetpackSubDocuments);
+            } else {
+                throw new IllegalStateException(
+                        String.format("Property \"%s\" has unsupported value type %s", propertyName,
+                                property.getClass().toString()));
+            }
+        }
+        return jetpackBuilder.build();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GetSchemaResponseToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GetSchemaResponseToGmsConverter.java
new file mode 100644
index 0000000..bacb0b8
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/GetSchemaResponseToGmsConverter.java
@@ -0,0 +1,100 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.GetSchemaResponse;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.collection.ArraySet;
+import androidx.core.util.Preconditions;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Translates between Gms and Jetpack versions of {@link GetSchemaResponse}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class GetSchemaResponseToGmsConverter {
+    private GetSchemaResponseToGmsConverter() {
+    }
+
+    /**
+     * Translates a Gms {@link com.google.android.gms.appsearch.GetSchemaResponse}
+     * into a jetpack
+     * {@link GetSchemaResponse}.
+     */
+    @NonNull
+    public static GetSchemaResponse toJetpackGetSchemaResponse(
+            @NonNull com.google.android.gms.appsearch.GetSchemaResponse
+                    gmsResponse) {
+        Preconditions.checkNotNull(gmsResponse);
+        GetSchemaResponse.Builder jetpackBuilder;
+        jetpackBuilder = new GetSchemaResponse.Builder();
+        for (com.google.android.gms.appsearch.AppSearchSchema gmsSchema :
+                gmsResponse.getSchemas()) {
+            jetpackBuilder.addSchema(SchemaToGmsConverter.toJetpackSchema(
+                    gmsSchema));
+        }
+        jetpackBuilder.setVersion(gmsResponse.getVersion());
+        // Convert schemas not displayed by system
+        for (String schemaTypeNotDisplayedBySystem :
+                gmsResponse.getSchemaTypesNotDisplayedBySystem()) {
+            jetpackBuilder.addSchemaTypeNotDisplayedBySystem(schemaTypeNotDisplayedBySystem);
+        }
+        // Convert schemas visible to packages
+        convertSchemasVisibleToPackages(gmsResponse, jetpackBuilder);
+        // Convert schemas visible to permissions
+        for (Map.Entry<String, Set<Set<Integer>>> entry :
+                gmsResponse.getRequiredPermissionsForSchemaTypeVisibility()
+                        .entrySet()) {
+            jetpackBuilder.setRequiredPermissionsForSchemaTypeVisibility(entry.getKey(),
+                    entry.getValue());
+        }
+        return jetpackBuilder.build();
+    }
+
+    /**
+     * Adds package visibilities in a Gms
+     * {@link com.google.android.gms.appsearch.GetSchemaResponse} into
+     * the given jetpack {@link GetSchemaResponse}.
+     */
+    private static void convertSchemasVisibleToPackages(
+            @NonNull com.google.android.gms.appsearch.GetSchemaResponse gmsResponse,
+            @NonNull GetSchemaResponse.Builder jetpackBuilder) {
+        Map<String, Set<com.google.android.gms.appsearch.PackageIdentifier>>
+                schemaTypesVisibleToPackages =
+                gmsResponse.getSchemaTypesVisibleToPackages();
+        if (schemaTypesVisibleToPackages != null) {
+            for (Map.Entry<String, Set<com.google.android.gms.appsearch.PackageIdentifier>> entry
+                    : schemaTypesVisibleToPackages.entrySet()) {
+                Set<PackageIdentifier> jetpackPackageIdentifiers =
+                        new ArraySet<>(entry.getValue().size());
+                for (com.google.android.gms.appsearch.PackageIdentifier frameworkPackageIdentifier
+                        : entry.getValue()) {
+                    jetpackPackageIdentifiers.add(new PackageIdentifier(
+                            frameworkPackageIdentifier.getPackageName(),
+                            frameworkPackageIdentifier.getSha256Certificate()));
+                }
+                jetpackBuilder.setSchemaTypeVisibleToPackages(
+                        entry.getKey(), jetpackPackageIdentifiers);
+            }
+        }
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/RequestToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/RequestToGmsConverter.java
new file mode 100644
index 0000000..34cebb8
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/RequestToGmsConverter.java
@@ -0,0 +1,105 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.GetByDocumentIdRequest;
+import androidx.appsearch.app.PutDocumentsRequest;
+import androidx.appsearch.app.RemoveByDocumentIdRequest;
+import androidx.appsearch.app.ReportUsageRequest;
+import androidx.core.util.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Translates between Gms and Jetpack versions of requests.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class RequestToGmsConverter {
+    private RequestToGmsConverter() {
+    }
+
+    /**
+     * Translates a jetpack {@link PutDocumentsRequest} into a Gms
+     * {@link com.google.android.gms.appsearch.PutDocumentsRequest}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.PutDocumentsRequest toGmsPutDocumentsRequest(
+            @NonNull PutDocumentsRequest jetpackRequest) {
+        Preconditions.checkNotNull(jetpackRequest);
+        com.google.android.gms.appsearch.PutDocumentsRequest.Builder gmsBuilder =
+                new com.google.android.gms.appsearch.PutDocumentsRequest.Builder();
+        for (GenericDocument jetpackDocument : jetpackRequest.getGenericDocuments()) {
+            gmsBuilder.addGenericDocuments(
+                    GenericDocumentToGmsConverter.toGmsGenericDocument(
+                            jetpackDocument));
+        }
+        return gmsBuilder.build();
+    }
+
+    /**
+     * Translates a jetpack {@link GetByDocumentIdRequest} into a Gms
+     * {@link com.google.android.gms.appsearch.GetByDocumentIdRequest}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.GetByDocumentIdRequest
+            toGmsGetByDocumentIdRequest(@NonNull GetByDocumentIdRequest jetpackRequest) {
+        Preconditions.checkNotNull(jetpackRequest);
+        com.google.android.gms.appsearch.GetByDocumentIdRequest.Builder gmsBuilder =
+                new com.google.android.gms.appsearch.GetByDocumentIdRequest.Builder(
+                        jetpackRequest.getNamespace())
+                        .addIds(jetpackRequest.getIds());
+        for (Map.Entry<String, List<String>> projection :
+                jetpackRequest.getProjectionsInternal().entrySet()) {
+            gmsBuilder.addProjection(projection.getKey(), projection.getValue());
+        }
+        return gmsBuilder.build();
+    }
+
+    /**
+     * Translates a jetpack {@link RemoveByDocumentIdRequest} into a Gms
+     * {@link com.google.android.gms.appsearch.RemoveByDocumentIdRequest}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.RemoveByDocumentIdRequest
+            toGmsRemoveByDocumentIdRequest(@NonNull RemoveByDocumentIdRequest jetpackRequest) {
+        Preconditions.checkNotNull(jetpackRequest);
+        return new com.google.android.gms.appsearch.RemoveByDocumentIdRequest.Builder(
+                jetpackRequest.getNamespace())
+                .addIds(jetpackRequest.getIds())
+                .build();
+    }
+
+    /**
+     * Translates a jetpack {@link androidx.appsearch.app.ReportUsageRequest} into a
+     * Gms
+     * {@link com.google.android.gms.appsearch.ReportUsageRequest}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.ReportUsageRequest
+            toGmsReportUsageRequest(@NonNull ReportUsageRequest jetpackRequest) {
+        Preconditions.checkNotNull(jetpackRequest);
+        return new com.google.android.gms.appsearch.ReportUsageRequest.Builder(
+                jetpackRequest.getNamespace(), jetpackRequest.getDocumentId())
+                .setUsageTimestampMillis(jetpackRequest.getUsageTimestampMillis())
+                .build();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/ResponseToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/ResponseToGmsConverter.java
new file mode 100644
index 0000000..3aa15b2
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/ResponseToGmsConverter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.StorageInfo;
+import androidx.core.util.Preconditions;
+
+/**
+ * Translates between Gms and Jetpack versions of responses.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class ResponseToGmsConverter {
+    private ResponseToGmsConverter() {
+    }
+
+    /**
+     * Translates a Gms {@link com.google.android.gms.appsearch.StorageInfo} into
+     * a jetpack {@link StorageInfo}.
+     */
+    @NonNull
+    public static StorageInfo toJetpackStorageInfo(
+            @NonNull com.google.android.gms.appsearch.StorageInfo gmsStorageInfo) {
+        Preconditions.checkNotNull(gmsStorageInfo);
+        return new StorageInfo.Builder()
+                .setAliveNamespacesCount(gmsStorageInfo.getAliveNamespacesCount())
+                .setAliveDocumentsCount(gmsStorageInfo.getAliveDocumentsCount())
+                .setSizeBytes(gmsStorageInfo.getSizeBytes())
+                .build();
+
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SchemaToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SchemaToGmsConverter.java
new file mode 100644
index 0000000..3c507a5
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SchemaToGmsConverter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.core.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Translates a jetpack {@link androidx.appsearch.app.AppSearchSchema} into a Gms
+ * {@link com.google.android.gms.appsearch.AppSearchSchema}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class SchemaToGmsConverter {
+    private SchemaToGmsConverter() {
+    }
+
+    /**
+     * Translates a jetpack {@link androidx.appsearch.app.AppSearchSchema} into a Gms
+     * {@link com.google.android.gms.appsearch.AppSearchSchema}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.AppSearchSchema toGmsSchema(
+            @NonNull AppSearchSchema jetpackSchema) {
+        Preconditions.checkNotNull(jetpackSchema);
+        com.google.android.gms.appsearch.AppSearchSchema.Builder gmsBuilder =
+                new com.google.android.gms.appsearch.AppSearchSchema
+                        .Builder(jetpackSchema.getSchemaType());
+        List<AppSearchSchema.PropertyConfig> properties = jetpackSchema.getProperties();
+        for (int i = 0; i < properties.size(); i++) {
+            com.google.android.gms.appsearch.AppSearchSchema.PropertyConfig gmsProperty =
+                    toGmsProperty(properties.get(i));
+            gmsBuilder.addProperty(gmsProperty);
+        }
+        return gmsBuilder.build();
+    }
+
+    /**
+     * Translates a Gms {@link com.google.android.gms.appsearch.AppSearchSchema}
+     * to a jetpack
+     * {@link androidx.appsearch.app.AppSearchSchema}.
+     */
+    @NonNull
+    public static AppSearchSchema toJetpackSchema(
+            @NonNull com.google.android.gms.appsearch.AppSearchSchema gmsSchema) {
+        Preconditions.checkNotNull(gmsSchema);
+        AppSearchSchema.Builder jetpackBuilder =
+                new AppSearchSchema.Builder(gmsSchema.getSchemaType());
+        List<com.google.android.gms.appsearch.AppSearchSchema.PropertyConfig> properties =
+                gmsSchema.getProperties();
+        for (int i = 0; i < properties.size(); i++) {
+            AppSearchSchema.PropertyConfig jetpackProperty = toJetpackProperty(properties.get(i));
+            jetpackBuilder.addProperty(jetpackProperty);
+        }
+        return jetpackBuilder.build();
+    }
+
+    @NonNull
+    private static com.google.android.gms.appsearch.AppSearchSchema.PropertyConfig toGmsProperty(
+            @NonNull AppSearchSchema.PropertyConfig jetpackProperty) {
+        Preconditions.checkNotNull(jetpackProperty);
+        if (jetpackProperty instanceof AppSearchSchema.StringPropertyConfig) {
+            AppSearchSchema.StringPropertyConfig stringProperty =
+                    (AppSearchSchema.StringPropertyConfig) jetpackProperty;
+            com.google.android.gms.appsearch.AppSearchSchema.StringPropertyConfig.Builder
+                    gmsBuilder =
+                    new com.google.android.gms.appsearch.AppSearchSchema.StringPropertyConfig
+                            .Builder(stringProperty.getName())
+                            .setCardinality(stringProperty.getCardinality())
+                            .setIndexingType(stringProperty.getIndexingType())
+                            .setTokenizerType(stringProperty.getTokenizerType());
+            if (stringProperty.getDeletionPropagation()) {
+                // TODO(b/268521214): Update once deletion propagation is available.
+                throw new UnsupportedOperationException("Setting deletion propagation is not "
+                        + "supported on this AppSearch implementation.");
+            }
+
+            if (stringProperty.getJoinableValueType()
+                    == AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID) {
+                //TODO(b/274986359) Add GMSCore feature check for Joins once available.
+                throw new UnsupportedOperationException(
+                        "StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID is not supported"
+                                + " on this AppSearch implementation.");
+            }
+            return gmsBuilder.build();
+        } else if (jetpackProperty instanceof AppSearchSchema.LongPropertyConfig) {
+            AppSearchSchema.LongPropertyConfig longProperty =
+                    (AppSearchSchema.LongPropertyConfig) jetpackProperty;
+            com.google.android.gms.appsearch.AppSearchSchema.LongPropertyConfig.Builder
+                    longPropertyBuilder =
+                    new com.google.android.gms.appsearch.AppSearchSchema.LongPropertyConfig
+                            .Builder(jetpackProperty.getName())
+                            .setCardinality(jetpackProperty.getCardinality());
+            if (longProperty.getIndexingType()
+                    == AppSearchSchema.LongPropertyConfig.INDEXING_TYPE_RANGE) {
+                //TODO(b/274986359) Add GMSCore feature check for Indexing Range once available.
+                throw new UnsupportedOperationException(
+                        "LongProperty.INDEXING_TYPE_RANGE is not supported on this AppSearch "
+                                + "implementation.");
+            }
+            return longPropertyBuilder.build();
+        } else if (jetpackProperty instanceof AppSearchSchema.DoublePropertyConfig) {
+            return new com.google.android.gms.appsearch.AppSearchSchema.DoublePropertyConfig
+                    .Builder(
+                    jetpackProperty.getName())
+                    .setCardinality(jetpackProperty.getCardinality())
+                    .build();
+        } else if (jetpackProperty instanceof AppSearchSchema.BooleanPropertyConfig) {
+            return new com.google.android.gms.appsearch.AppSearchSchema.BooleanPropertyConfig
+                    .Builder(
+                    jetpackProperty.getName())
+                    .setCardinality(jetpackProperty.getCardinality())
+                    .build();
+        } else if (jetpackProperty instanceof AppSearchSchema.BytesPropertyConfig) {
+            return new com.google.android.gms.appsearch.AppSearchSchema.BytesPropertyConfig
+                    .Builder(
+                    jetpackProperty.getName())
+                    .setCardinality(jetpackProperty.getCardinality())
+                    .build();
+        } else if (jetpackProperty instanceof AppSearchSchema.DocumentPropertyConfig) {
+            AppSearchSchema.DocumentPropertyConfig documentProperty =
+                    (AppSearchSchema.DocumentPropertyConfig) jetpackProperty;
+            return new com.google.android.gms.appsearch.AppSearchSchema.DocumentPropertyConfig
+                    .Builder(
+                    documentProperty.getName(), documentProperty.getSchemaType())
+                    .setCardinality(documentProperty.getCardinality())
+                    .setShouldIndexNestedProperties(documentProperty.shouldIndexNestedProperties())
+                    .build();
+        } else {
+            throw new IllegalArgumentException(
+                    "Invalid dataType: " + jetpackProperty.getDataType());
+        }
+    }
+
+    @NonNull
+    private static AppSearchSchema.PropertyConfig toJetpackProperty(
+            @NonNull com.google.android.gms.appsearch.AppSearchSchema.PropertyConfig
+                    gmsProperty) {
+        Preconditions.checkNotNull(gmsProperty);
+        if (gmsProperty
+                instanceof com.google.android.gms.appsearch.AppSearchSchema.StringPropertyConfig) {
+            com.google.android.gms.appsearch.AppSearchSchema.StringPropertyConfig stringProperty =
+                    (com.google.android.gms.appsearch.AppSearchSchema.StringPropertyConfig)
+                            gmsProperty;
+            return new AppSearchSchema.StringPropertyConfig.Builder(stringProperty.getName())
+                    .setCardinality(stringProperty.getCardinality())
+                    .setIndexingType(stringProperty.getIndexingType())
+                    .setTokenizerType(stringProperty.getTokenizerType())
+                    .build();
+        } else if (gmsProperty
+                instanceof com.google.android.gms.appsearch.AppSearchSchema.LongPropertyConfig) {
+            return new AppSearchSchema.LongPropertyConfig.Builder(
+                    gmsProperty.getName())
+                    .setCardinality(gmsProperty.getCardinality())
+                    .build();
+        } else if (gmsProperty
+                instanceof com.google.android.gms.appsearch.AppSearchSchema.DoublePropertyConfig) {
+            return new AppSearchSchema.DoublePropertyConfig.Builder(
+                    gmsProperty.getName())
+                    .setCardinality(gmsProperty.getCardinality())
+                    .build();
+        } else if (gmsProperty
+                instanceof com.google.android.gms.appsearch.AppSearchSchema.BooleanPropertyConfig) {
+            return new AppSearchSchema.BooleanPropertyConfig.Builder(
+                    gmsProperty.getName())
+                    .setCardinality(gmsProperty.getCardinality())
+                    .build();
+        } else if (gmsProperty
+                instanceof com.google.android.gms.appsearch.AppSearchSchema.BytesPropertyConfig) {
+            return new AppSearchSchema.BytesPropertyConfig.Builder(
+                    gmsProperty.getName())
+                    .setCardinality(gmsProperty.getCardinality())
+                    .build();
+        } else if (gmsProperty
+                instanceof
+                com.google.android.gms.appsearch.AppSearchSchema.DocumentPropertyConfig) {
+            com.google.android.gms.appsearch.AppSearchSchema.DocumentPropertyConfig
+                    documentProperty =
+                    (com.google.android.gms.appsearch.AppSearchSchema.DocumentPropertyConfig)
+                            gmsProperty;
+            return new AppSearchSchema.DocumentPropertyConfig.Builder(
+                    documentProperty.getName(),
+                    documentProperty.getSchemaType())
+                    .setCardinality(documentProperty.getCardinality())
+                    .setShouldIndexNestedProperties(documentProperty.shouldIndexNestedProperties())
+                    .build();
+        } else {
+            throw new IllegalArgumentException(
+                    "Invalid property type " + gmsProperty.getClass()
+                            + ": " + gmsProperty);
+        }
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchResultToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchResultToGmsConverter.java
new file mode 100644
index 0000000..81a0206
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchResultToGmsConverter.java
@@ -0,0 +1,95 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.SearchResult;
+import androidx.core.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Translates between Gms and Jetpack versions of {@link SearchResult}.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class SearchResultToGmsConverter {
+    private SearchResultToGmsConverter() {
+    }
+
+    /** Translates from Gms to Jetpack versions of list of {@link SearchResult}. */
+    @NonNull
+    public static List<SearchResult> toJetpackSearchResultList(
+            @NonNull List<com.google.android.gms.appsearch.SearchResult> gmsResultList) {
+        Preconditions.checkNotNull(gmsResultList);
+        List<androidx.appsearch.app.SearchResult> jetpackResults =
+                new ArrayList<>(gmsResultList.size());
+        for (int i = 0; i < gmsResultList.size(); i++) {
+            androidx.appsearch.app.SearchResult jetpackResult =
+                    toJetpackSearchResult(gmsResultList.get(i));
+            jetpackResults.add(jetpackResult);
+        }
+        return jetpackResults;
+    }
+
+    /** Translates from Gms to Jetpack versions of {@link SearchResult}. */
+    @NonNull
+    public static SearchResult toJetpackSearchResult(
+            @NonNull com.google.android.gms.appsearch.SearchResult gmsResult) {
+        Preconditions.checkNotNull(gmsResult);
+        GenericDocument document =
+                GenericDocumentToGmsConverter.toJetpackGenericDocument(
+                        gmsResult.getGenericDocument());
+        SearchResult.Builder builder = new SearchResult.Builder(
+                gmsResult.getPackageName(),
+                gmsResult.getDatabaseName())
+                .setGenericDocument(document)
+                .setRankingSignal(gmsResult.getRankingSignal());
+        List<com.google.android.gms.appsearch.SearchResult.MatchInfo> gmsMatches =
+                gmsResult.getMatchInfos();
+        for (int i = 0; i < gmsMatches.size(); i++) {
+            SearchResult.MatchInfo jetpackMatchInfo = toJetpackMatchInfo(
+                    gmsMatches.get(i));
+            builder.addMatchInfo(jetpackMatchInfo);
+        }
+        return builder.build();
+    }
+
+    @NonNull
+    private static SearchResult.MatchInfo toJetpackMatchInfo(
+            @NonNull com.google.android.gms.appsearch.SearchResult.MatchInfo
+                    gmsMatchInfo) {
+        Preconditions.checkNotNull(gmsMatchInfo);
+        SearchResult.MatchInfo.Builder builder = new SearchResult.MatchInfo.Builder(
+                gmsMatchInfo.getPropertyPath())
+                .setExactMatchRange(
+                        new SearchResult.MatchRange(
+                                gmsMatchInfo.getExactMatchRange().getStart(),
+                                gmsMatchInfo.getExactMatchRange().getEnd()))
+                .setSnippetRange(
+                        new SearchResult.MatchRange(
+                                gmsMatchInfo.getSnippetRange().getStart(),
+                                gmsMatchInfo.getSnippetRange().getEnd()));
+        builder.setSubmatchRange(
+                new SearchResult.MatchRange(
+                        gmsMatchInfo.getSubmatchRange().getStart(),
+                        gmsMatchInfo.getSubmatchRange().getEnd()));
+        return builder.build();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchSpecToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchSpecToGmsConverter.java
new file mode 100644
index 0000000..8922bd4
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SearchSpecToGmsConverter.java
@@ -0,0 +1,103 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.Features;
+import androidx.appsearch.app.SearchSpec;
+import androidx.core.util.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Translates between Gms and Jetpack versions of {@link SearchSpec}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class SearchSpecToGmsConverter {
+    private SearchSpecToGmsConverter() {
+    }
+
+    /** Translates from Jetpack to Gms version of {@link SearchSpec}. */
+    @NonNull
+    public static com.google.android.gms.appsearch.SearchSpec toGmsSearchSpec(
+            @NonNull SearchSpec jetpackSearchSpec) {
+        Preconditions.checkNotNull(jetpackSearchSpec);
+        com.google.android.gms.appsearch.SearchSpec.Builder gmsBuilder =
+                new com.google.android.gms.appsearch.SearchSpec.Builder();
+
+        if (!jetpackSearchSpec.getAdvancedRankingExpression().isEmpty()) {
+            //TODO(b/274986359) Add GMSCore feature check for Advanced Ranking once available.
+            throw new UnsupportedOperationException(
+                    Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION
+                            + " is not available on this AppSearch implementation.");
+        } else {
+            gmsBuilder.setRankingStrategy(jetpackSearchSpec.getRankingStrategy());
+        }
+
+        gmsBuilder
+                .setTermMatch(jetpackSearchSpec.getTermMatch())
+                .addFilterSchemas(jetpackSearchSpec.getFilterSchemas())
+                .addFilterNamespaces(jetpackSearchSpec.getFilterNamespaces())
+                .addFilterPackageNames(jetpackSearchSpec.getFilterPackageNames())
+                .setResultCountPerPage(jetpackSearchSpec.getResultCountPerPage())
+                .setRankingStrategy(jetpackSearchSpec.getRankingStrategy())
+                .setOrder(jetpackSearchSpec.getOrder())
+                .setSnippetCount(jetpackSearchSpec.getSnippetCount())
+                .setSnippetCountPerProperty(jetpackSearchSpec.getSnippetCountPerProperty())
+                .setMaxSnippetSize(jetpackSearchSpec.getMaxSnippetSize());
+        if (jetpackSearchSpec.getResultGroupingTypeFlags() != 0) {
+            gmsBuilder.setResultGrouping(
+                    jetpackSearchSpec.getResultGroupingTypeFlags(),
+                    jetpackSearchSpec.getResultGroupingLimit());
+        }
+        for (Map.Entry<String, List<String>> projection :
+                jetpackSearchSpec.getProjections().entrySet()) {
+            gmsBuilder.addProjection(projection.getKey(), projection.getValue());
+        }
+
+        if (!jetpackSearchSpec.getEnabledFeatures().isEmpty()) {
+            if (jetpackSearchSpec.isNumericSearchEnabled()
+                    || jetpackSearchSpec.isVerbatimSearchEnabled()
+                    || jetpackSearchSpec.isListFilterQueryLanguageEnabled()) {
+                //TODO(b/274986359) Add GMSCore feature check for NUMERIC_SEARCH,
+                // VERBATIM_SEARCH and LIST_FILTER_QUERY_LANGUAGE once available.
+                throw new UnsupportedOperationException(
+                        "Advanced query features (NUMERIC_SEARCH, VERBATIM_SEARCH and "
+                                + "LIST_FILTER_QUERY_LANGUAGE) are not supported with this "
+                                + "backend/Android API level combination.");
+            }
+        }
+
+        if (!jetpackSearchSpec.getPropertyWeights().isEmpty()) {
+            //TODO(b/274986359) Add GMSCore feature check for Property Weights once available.
+            throw new UnsupportedOperationException(
+                    "Property weights are not supported with this backend/Android API level "
+                            + "combination.");
+        }
+
+        if (jetpackSearchSpec.getJoinSpec() != null) {
+            //TODO(b/274986359) Add GMSCore feature check for Joins once available.
+            throw new UnsupportedOperationException("JoinSpec is not available on this "
+                    + "AppSearch implementation.");
+        }
+
+        return gmsBuilder.build();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SetSchemaRequestToGmsConverter.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SetSchemaRequestToGmsConverter.java
new file mode 100644
index 0000000..3929b54
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/converter/SetSchemaRequestToGmsConverter.java
@@ -0,0 +1,164 @@
+/*
+ * 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.appsearch.playservicesstorage.converter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.app.Migrator;
+import androidx.appsearch.app.PackageIdentifier;
+import androidx.appsearch.app.SetSchemaRequest;
+import androidx.appsearch.app.SetSchemaResponse;
+import androidx.core.util.Preconditions;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Translates between Gms and Jetpack versions of {@link SetSchemaRequest}.
+
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public final class SetSchemaRequestToGmsConverter {
+    private SetSchemaRequestToGmsConverter() {
+    }
+
+    /**
+     * Translates a jetpack {@link SetSchemaRequest} into a googleGms
+     * {@link com.google.android.gms.appsearch.SetSchemaRequest}.
+     */
+    @NonNull
+    public static com.google.android.gms.appsearch.SetSchemaRequest toGmsSetSchemaRequest(
+            @NonNull SetSchemaRequest jetpackRequest) {
+        Preconditions.checkNotNull(jetpackRequest);
+        com.google.android.gms.appsearch.SetSchemaRequest.Builder gmsBuilder =
+                new com.google.android.gms.appsearch.SetSchemaRequest.Builder();
+        for (AppSearchSchema jetpackSchema : jetpackRequest.getSchemas()) {
+            gmsBuilder.addSchemas(SchemaToGmsConverter.toGmsSchema(jetpackSchema));
+        }
+        for (String schemaNotDisplayedBySystem : jetpackRequest.getSchemasNotDisplayedBySystem()) {
+            gmsBuilder.setSchemaTypeDisplayedBySystem(
+                    schemaNotDisplayedBySystem, /*displayed=*/ false);
+        }
+        for (Map.Entry<String, Set<PackageIdentifier>> jetpackSchemaVisibleToPackage :
+                jetpackRequest.getSchemasVisibleToPackagesInternal().entrySet()) {
+            for (PackageIdentifier jetpackPackageIdentifier :
+                    jetpackSchemaVisibleToPackage.getValue()) {
+                gmsBuilder.setSchemaTypeVisibilityForPackage(
+                        jetpackSchemaVisibleToPackage.getKey(),
+                        /*visible=*/ true,
+                        new com.google.android.gms.appsearch.PackageIdentifier(
+                                jetpackPackageIdentifier.getPackageName(),
+                                jetpackPackageIdentifier.getSha256Certificate()));
+            }
+        }
+        if (!jetpackRequest.getRequiredPermissionsForSchemaTypeVisibility().isEmpty()) {
+            for (Map.Entry<String, Set<Set<Integer>>> entry :
+                    jetpackRequest.getRequiredPermissionsForSchemaTypeVisibility().entrySet()) {
+                for (Set<Integer> permissionGroup : entry.getValue()) {
+                    gmsBuilder.addRequiredPermissionsForSchemaTypeVisibility(
+                            entry.getKey(), permissionGroup);
+                }
+            }
+        }
+        for (Map.Entry<String, Migrator> entry : jetpackRequest.getMigrators().entrySet()) {
+            Migrator jetpackMigrator = entry.getValue();
+            com.google.android.gms.appsearch.Migrator gmsMigrator =
+                    new com.google.android.gms.appsearch.Migrator() {
+                        @Override
+                        public boolean shouldMigrate(int currentVersion, int finalVersion) {
+                            return jetpackMigrator.shouldMigrate(currentVersion, finalVersion);
+                        }
+
+                        @NonNull
+                        @Override
+                        public com.google.android.gms.appsearch.GenericDocument onUpgrade(
+                                int currentVersion,
+                                int finalVersion,
+                                @NonNull com.google.android.gms.appsearch.GenericDocument
+                                        inGmsDocument) {
+                            GenericDocument inJetpackDocument =
+                                    GenericDocumentToGmsConverter
+                                            .toJetpackGenericDocument(
+                                                    inGmsDocument);
+                            GenericDocument outJetpackDocument = jetpackMigrator.onUpgrade(
+                                    currentVersion, finalVersion, inJetpackDocument);
+                            if (inJetpackDocument.equals(outJetpackDocument)) {
+                                return inGmsDocument; // Same object; no conversion occurred.
+                            }
+                            return GenericDocumentToGmsConverter
+                                    .toGmsGenericDocument(
+                                            outJetpackDocument);
+                        }
+
+                        @NonNull
+                        @Override
+                        public com.google.android.gms.appsearch.GenericDocument onDowngrade(
+                                int currentVersion,
+                                int finalVersion,
+                                @NonNull com.google.android.gms.appsearch.GenericDocument
+                                        inGmsDocument) {
+                            GenericDocument inJetpackDocument =
+                                    GenericDocumentToGmsConverter
+                                            .toJetpackGenericDocument(
+                                                    inGmsDocument);
+                            GenericDocument outJetpackDocument = jetpackMigrator.onDowngrade(
+                                    currentVersion, finalVersion, inJetpackDocument);
+                            if (inJetpackDocument.equals(outJetpackDocument)) {
+                                return inGmsDocument; // Same object; no conversion occurred.
+                            }
+                            return GenericDocumentToGmsConverter
+                                    .toGmsGenericDocument(
+                                            outJetpackDocument);
+                        }
+                    };
+            gmsBuilder.setMigrator(entry.getKey(), gmsMigrator);
+        }
+        return gmsBuilder
+                .setForceOverride(jetpackRequest.isForceOverride())
+                .setVersion(jetpackRequest.getVersion())
+                .build();
+    }
+
+    /**
+     * Translates a gms
+     * {@link com.google.android.gms.appsearch.SetSchemaResponse} into a jetpack
+     * {@link SetSchemaResponse}.
+     */
+    @NonNull
+    public static SetSchemaResponse toJetpackSetSchemaResponse(
+            @NonNull com.google.android.gms.appsearch.SetSchemaResponse
+                    gmsResponse) {
+        Preconditions.checkNotNull(gmsResponse);
+        SetSchemaResponse.Builder jetpackBuilder = new SetSchemaResponse.Builder()
+                .addDeletedTypes(gmsResponse.getDeletedTypes())
+                .addIncompatibleTypes(gmsResponse.getIncompatibleTypes())
+                .addMigratedTypes(gmsResponse.getMigratedTypes());
+        for (com.google.android.gms.appsearch.SetSchemaResponse.MigrationFailure migrationFailure :
+                gmsResponse.getMigrationFailures()) {
+            jetpackBuilder.addMigrationFailure(new SetSchemaResponse.MigrationFailure(
+                    migrationFailure.getNamespace(),
+                    migrationFailure.getDocumentId(),
+                    migrationFailure.getSchemaType(),
+                    AppSearchResultToGmsConverter.gmsAppSearchResultToJetpack(
+                            migrationFailure.getAppSearchResult(), /* valueMapper= */ i -> i))
+            );
+        }
+        return jetpackBuilder.build();
+    }
+}
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java
new file mode 100644
index 0000000..d737512a
--- /dev/null
+++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java
@@ -0,0 +1,94 @@
+/*
+ * 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.appsearch.playservicesstorage.util;
+
+import static androidx.appsearch.app.AppSearchResult.RESULT_NOT_FOUND;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.exceptions.AppSearchException;
+import androidx.appsearch.util.LogUtil;
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+import androidx.core.util.Function;
+
+import com.google.android.gms.tasks.Task;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/** Utilities for converting {@link Task} to {@link ListenableFuture}. */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+public class AppSearchTaskFutures {
+
+    private static final String TAG = "AppSearchTaskFutures";
+
+    private AppSearchTaskFutures() {}
+
+    /**
+     * Converts a {@link Task} to a {@link ListenableFuture} to more easily interact with other
+     * androidx apis.
+     * <p>Note: Calling {@link java.util.concurrent.Future#cancel(boolean)} on the returned result
+     * is a no-op since {@link Task} has no equivalent method.
+     */
+    @NonNull
+    public static <GmsType, JetpackType> ListenableFuture<JetpackType> toListenableFuture(
+            @NonNull Task<GmsType> task,
+            @NonNull Function<GmsType, JetpackType> valueMapper) {
+        return CallbackToFutureAdapter.getFuture(
+                completer -> task.addOnCompleteListener(
+                        completedTask -> {
+                            if (completedTask.isCanceled()) {
+                                completer.setCancelled();
+                            } else if (completedTask.isSuccessful()) {
+                                JetpackType jetpackType = valueMapper.apply(
+                                        completedTask.getResult());
+                                completer.set(jetpackType);
+                            } else {
+                                Exception exception = task.getException();
+                                completer.setException(toJetpackException(exception));
+                            }
+                        }));
+    }
+
+    /**
+     * Converts the given Exception to AppSearchException if from PlayServicesAppSearch otherwise
+     * just returns it.
+     */
+    @NonNull
+    private static Exception toJetpackException(@NonNull Exception exception) {
+        if (exception instanceof com.google.android.gms.appsearch.exceptions.AppSearchException) {
+            com.google.android.gms.appsearch.exceptions.AppSearchException
+                    gmsException =
+                    (com.google.android.gms.appsearch.exceptions.AppSearchException) exception;
+            if (gmsException.getResultCode() == RESULT_NOT_FOUND && LogUtil.DEBUG) {
+                // Log for traceability. NOT_FOUND is logged at VERBOSE because this
+                // error can occur during the regular operation of the system
+                // (b/183550974). Everything else is indicative of an actual
+                // problem and is logged at WARN.
+                Log.v(TAG, "Failed to call PlayServicesAppSearch: "
+                        + exception);
+            }
+
+            return new AppSearchException(
+                    gmsException.getResultCode(),
+                    gmsException.getMessage());
+        }
+
+        Log.w(TAG, "Failed to call PlayServicesAppSearch", exception);
+        return exception;
+    }
+}
diff --git a/appsearch/appsearch-test-util/lint-baseline.xml b/appsearch/appsearch-test-util/lint-baseline.xml
deleted file mode 100644
index 0d3fe4a..0000000
--- a/appsearch/appsearch-test-util/lint-baseline.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class AppSearchEmail extends GenericDocument {"
-        errorLine2="             ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/testutil/AppSearchEmail.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class AppSearchTestUtils {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SimpleTestLogger implements AppSearchLogger {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/testutil/SimpleTestLogger.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class TestObserverCallback implements ObserverCallback {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/testutil/TestObserverCallback.java"/>
-    </issue>
-
-</issues>
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchEmail.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchEmail.java
index 5aec156..dc07d90 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchEmail.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchEmail.java
@@ -19,6 +19,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchSchema;
 import androidx.appsearch.app.AppSearchSchema.PropertyConfig;
 import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig;
@@ -29,7 +30,7 @@
  *
  * <p>This class is a higher level implement of {@link GenericDocument}.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class AppSearchEmail extends GenericDocument {
@@ -170,6 +171,7 @@
         /**
          * Sets the from address of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setFrom(@NonNull String from) {
             return setPropertyString(KEY_FROM, from);
@@ -178,6 +180,7 @@
         /**
          * Sets the destination address of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTo(@NonNull String... to) {
             return setPropertyString(KEY_TO, to);
@@ -186,6 +189,7 @@
         /**
          * Sets the CC list of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setCc(@NonNull String... cc) {
             return setPropertyString(KEY_CC, cc);
@@ -194,6 +198,7 @@
         /**
          * Sets the BCC list of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setBcc(@NonNull String... bcc) {
             return setPropertyString(KEY_BCC, bcc);
@@ -202,6 +207,7 @@
         /**
          * Sets the subject of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSubject(@NonNull String subject) {
             return setPropertyString(KEY_SUBJECT, subject);
@@ -210,6 +216,7 @@
         /**
          * Sets the body of {@link AppSearchEmail}
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setBody(@NonNull String body) {
             return setPropertyString(KEY_BODY, body);
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
index 3c2943e..6d996e9 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/AppSearchTestUtils.java
@@ -37,7 +37,7 @@
 /**
  * Class with helper functions for testing for AppSearch.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class AppSearchTestUtils {
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/SimpleTestLogger.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/SimpleTestLogger.java
index 6e91f93..0c9464b 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/SimpleTestLogger.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/SimpleTestLogger.java
@@ -35,7 +35,7 @@
 /**
  * Non-thread-safe simple logger implementation for testing.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SimpleTestLogger implements AppSearchLogger {
diff --git a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
index a22d02e..f1cb259 100644
--- a/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
+++ b/appsearch/appsearch-test-util/src/main/java/androidx/appsearch/testutil/TestObserverCallback.java
@@ -33,7 +33,7 @@
  * <p>You should wait for all notifications to be delivered using {@link #waitForNotificationCount}
  * before using the public lists to avoid concurrency issues.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class TestObserverCallback implements ObserverCallback {
diff --git a/appsearch/appsearch/api/current.txt b/appsearch/appsearch/api/current.txt
index 7b7f92e..61fa4ed 100644
--- a/appsearch/appsearch/api/current.txt
+++ b/appsearch/appsearch/api/current.txt
@@ -46,6 +46,7 @@
 
   @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface Document.StringProperty {
     method public abstract int indexingType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
+    method public abstract int joinableValueType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE;
     method public abstract String name() default "";
     method public abstract boolean required() default false;
     method public abstract int tokenizerType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN;
@@ -80,6 +81,7 @@
     method public boolean isSuccess();
     method public static <ValueType> androidx.appsearch.app.AppSearchResult<ValueType!> newFailedResult(int, String?);
     method public static <ValueType> androidx.appsearch.app.AppSearchResult<ValueType!> newSuccessfulResult(ValueType?);
+    field public static final int RESULT_DENIED = 9; // 0x9
     field public static final int RESULT_INTERNAL_ERROR = 2; // 0x2
     field public static final int RESULT_INVALID_ARGUMENT = 3; // 0x3
     field public static final int RESULT_INVALID_SCHEMA = 7; // 0x7
@@ -163,6 +165,7 @@
   }
 
   public static final class AppSearchSchema.StringPropertyConfig extends androidx.appsearch.app.AppSearchSchema.PropertyConfig {
+    method public boolean getDeletionPropagation();
     method public int getIndexingType();
     method public int getJoinableValueType();
     method public int getTokenizerType();
@@ -181,6 +184,7 @@
     ctor public AppSearchSchema.StringPropertyConfig.Builder(String);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig build();
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setCardinality(int);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.SCHEMA_SET_DELETION_PROPAGATION) public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setDeletionPropagation(boolean);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setIndexingType(int);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setJoinableValueType(int);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setTokenizerType(int);
@@ -199,11 +203,13 @@
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsageAsync(androidx.appsearch.app.ReportUsageRequest);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlushAsync();
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchSuggestionResult!>!> searchSuggestionAsync(String, androidx.appsearch.app.SearchSuggestionSpec);
     method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchemaAsync(androidx.appsearch.app.SetSchemaRequest);
   }
 
   public interface DocumentClassFactory<T> {
     method public T fromGenericDocument(androidx.appsearch.app.GenericDocument) throws androidx.appsearch.exceptions.AppSearchException;
+    method public java.util.List<java.lang.Class<?>!> getNestedDocumentClasses() throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.AppSearchSchema getSchema() throws androidx.appsearch.exceptions.AppSearchException;
     method public String getSchemaName();
     method public androidx.appsearch.app.GenericDocument toGenericDocument(T) throws androidx.appsearch.exceptions.AppSearchException;
@@ -218,9 +224,12 @@
     field public static final String JOIN_SPEC_AND_QUALIFIED_ID = "JOIN_SPEC_AND_QUALIFIED_ID";
     field public static final String LIST_FILTER_QUERY_LANGUAGE = "LIST_FILTER_QUERY_LANGUAGE";
     field public static final String NUMERIC_SEARCH = "NUMERIC_SEARCH";
+    field public static final String SCHEMA_SET_DELETION_PROPAGATION = "SCHEMA_SET_DELETION_PROPAGATION";
     field public static final String SEARCH_RESULT_MATCH_INFO_SUBMATCH = "SEARCH_RESULT_MATCH_INFO_SUBMATCH";
     field public static final String SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION = "SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION";
+    field public static final String SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA = "SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA";
     field public static final String SEARCH_SPEC_PROPERTY_WEIGHTS = "SEARCH_SPEC_PROPERTY_WEIGHTS";
+    field public static final String SEARCH_SUGGESTION = "SEARCH_SUGGESTION";
     field public static final String TOKENIZER_TYPE_RFC822 = "TOKENIZER_TYPE_RFC822";
     field public static final String VERBATIM_SEARCH = "VERBATIM_SEARCH";
   }
@@ -329,7 +338,6 @@
     field public static final int AGGREGATION_SCORING_OUTER_RESULT_RANKING_SIGNAL = 0; // 0x0
     field public static final int AGGREGATION_SCORING_RESULT_COUNT = 1; // 0x1
     field public static final int AGGREGATION_SCORING_SUM_RANKING_SIGNAL = 5; // 0x5
-    field public static final String QUALIFIED_ID = "this.qualifiedId()";
   }
 
   public static final class JoinSpec.Builder {
@@ -495,6 +503,7 @@
     method public boolean isVerbatimSearchEnabled();
     field public static final int GROUPING_TYPE_PER_NAMESPACE = 2; // 0x2
     field public static final int GROUPING_TYPE_PER_PACKAGE = 1; // 0x1
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA) public static final int GROUPING_TYPE_PER_SCHEMA = 4; // 0x4
     field public static final int ORDER_ASCENDING = 1; // 0x1
     field public static final int ORDER_DESCENDING = 0; // 0x0
     field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
@@ -546,7 +555,7 @@
     method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.VERBATIM_SEARCH) public androidx.appsearch.app.SearchSpec.Builder setVerbatimSearchEnabled(boolean);
   }
 
-  public class SearchSuggestionResult {
+  public final class SearchSuggestionResult {
     method public String getSuggestedResult();
   }
 
@@ -556,7 +565,7 @@
     method public androidx.appsearch.app.SearchSuggestionResult.Builder setSuggestedResult(String);
   }
 
-  public class SearchSuggestionSpec {
+  public final class SearchSuggestionSpec {
     method public java.util.Map<java.lang.String!,java.util.List<java.lang.String!>!> getFilterDocumentIds();
     method public java.util.List<java.lang.String!> getFilterNamespaces();
     method public java.util.List<java.lang.String!> getFilterSchemas();
@@ -577,7 +586,7 @@
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterNamespaces(java.util.Collection<java.lang.String!>);
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterSchemas(java.lang.String!...);
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterSchemas(java.util.Collection<java.lang.String!>);
-    method public androidx.appsearch.app.SearchSuggestionSpec build() throws androidx.appsearch.exceptions.AppSearchException;
+    method public androidx.appsearch.app.SearchSuggestionSpec build();
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder setRankingStrategy(int);
   }
 
diff --git a/appsearch/appsearch/api/restricted_current.txt b/appsearch/appsearch/api/restricted_current.txt
index 7b7f92e..61fa4ed 100644
--- a/appsearch/appsearch/api/restricted_current.txt
+++ b/appsearch/appsearch/api/restricted_current.txt
@@ -46,6 +46,7 @@
 
   @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface Document.StringProperty {
     method public abstract int indexingType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
+    method public abstract int joinableValueType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE;
     method public abstract String name() default "";
     method public abstract boolean required() default false;
     method public abstract int tokenizerType() default androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN;
@@ -80,6 +81,7 @@
     method public boolean isSuccess();
     method public static <ValueType> androidx.appsearch.app.AppSearchResult<ValueType!> newFailedResult(int, String?);
     method public static <ValueType> androidx.appsearch.app.AppSearchResult<ValueType!> newSuccessfulResult(ValueType?);
+    field public static final int RESULT_DENIED = 9; // 0x9
     field public static final int RESULT_INTERNAL_ERROR = 2; // 0x2
     field public static final int RESULT_INVALID_ARGUMENT = 3; // 0x3
     field public static final int RESULT_INVALID_SCHEMA = 7; // 0x7
@@ -163,6 +165,7 @@
   }
 
   public static final class AppSearchSchema.StringPropertyConfig extends androidx.appsearch.app.AppSearchSchema.PropertyConfig {
+    method public boolean getDeletionPropagation();
     method public int getIndexingType();
     method public int getJoinableValueType();
     method public int getTokenizerType();
@@ -181,6 +184,7 @@
     ctor public AppSearchSchema.StringPropertyConfig.Builder(String);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig build();
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setCardinality(int);
+    method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.SCHEMA_SET_DELETION_PROPAGATION) public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setDeletionPropagation(boolean);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setIndexingType(int);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setJoinableValueType(int);
     method public androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.Builder setTokenizerType(int);
@@ -199,11 +203,13 @@
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> reportUsageAsync(androidx.appsearch.app.ReportUsageRequest);
     method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> requestFlushAsync();
     method public androidx.appsearch.app.SearchResults search(String, androidx.appsearch.app.SearchSpec);
+    method public com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.appsearch.app.SearchSuggestionResult!>!> searchSuggestionAsync(String, androidx.appsearch.app.SearchSuggestionSpec);
     method public com.google.common.util.concurrent.ListenableFuture<androidx.appsearch.app.SetSchemaResponse!> setSchemaAsync(androidx.appsearch.app.SetSchemaRequest);
   }
 
   public interface DocumentClassFactory<T> {
     method public T fromGenericDocument(androidx.appsearch.app.GenericDocument) throws androidx.appsearch.exceptions.AppSearchException;
+    method public java.util.List<java.lang.Class<?>!> getNestedDocumentClasses() throws androidx.appsearch.exceptions.AppSearchException;
     method public androidx.appsearch.app.AppSearchSchema getSchema() throws androidx.appsearch.exceptions.AppSearchException;
     method public String getSchemaName();
     method public androidx.appsearch.app.GenericDocument toGenericDocument(T) throws androidx.appsearch.exceptions.AppSearchException;
@@ -218,9 +224,12 @@
     field public static final String JOIN_SPEC_AND_QUALIFIED_ID = "JOIN_SPEC_AND_QUALIFIED_ID";
     field public static final String LIST_FILTER_QUERY_LANGUAGE = "LIST_FILTER_QUERY_LANGUAGE";
     field public static final String NUMERIC_SEARCH = "NUMERIC_SEARCH";
+    field public static final String SCHEMA_SET_DELETION_PROPAGATION = "SCHEMA_SET_DELETION_PROPAGATION";
     field public static final String SEARCH_RESULT_MATCH_INFO_SUBMATCH = "SEARCH_RESULT_MATCH_INFO_SUBMATCH";
     field public static final String SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION = "SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION";
+    field public static final String SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA = "SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA";
     field public static final String SEARCH_SPEC_PROPERTY_WEIGHTS = "SEARCH_SPEC_PROPERTY_WEIGHTS";
+    field public static final String SEARCH_SUGGESTION = "SEARCH_SUGGESTION";
     field public static final String TOKENIZER_TYPE_RFC822 = "TOKENIZER_TYPE_RFC822";
     field public static final String VERBATIM_SEARCH = "VERBATIM_SEARCH";
   }
@@ -329,7 +338,6 @@
     field public static final int AGGREGATION_SCORING_OUTER_RESULT_RANKING_SIGNAL = 0; // 0x0
     field public static final int AGGREGATION_SCORING_RESULT_COUNT = 1; // 0x1
     field public static final int AGGREGATION_SCORING_SUM_RANKING_SIGNAL = 5; // 0x5
-    field public static final String QUALIFIED_ID = "this.qualifiedId()";
   }
 
   public static final class JoinSpec.Builder {
@@ -495,6 +503,7 @@
     method public boolean isVerbatimSearchEnabled();
     field public static final int GROUPING_TYPE_PER_NAMESPACE = 2; // 0x2
     field public static final int GROUPING_TYPE_PER_PACKAGE = 1; // 0x1
+    field @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA) public static final int GROUPING_TYPE_PER_SCHEMA = 4; // 0x4
     field public static final int ORDER_ASCENDING = 1; // 0x1
     field public static final int ORDER_DESCENDING = 0; // 0x0
     field public static final String PROJECTION_SCHEMA_TYPE_WILDCARD = "*";
@@ -546,7 +555,7 @@
     method @RequiresFeature(enforcement="androidx.appsearch.app.Features#isFeatureSupported", name=androidx.appsearch.app.Features.VERBATIM_SEARCH) public androidx.appsearch.app.SearchSpec.Builder setVerbatimSearchEnabled(boolean);
   }
 
-  public class SearchSuggestionResult {
+  public final class SearchSuggestionResult {
     method public String getSuggestedResult();
   }
 
@@ -556,7 +565,7 @@
     method public androidx.appsearch.app.SearchSuggestionResult.Builder setSuggestedResult(String);
   }
 
-  public class SearchSuggestionSpec {
+  public final class SearchSuggestionSpec {
     method public java.util.Map<java.lang.String!,java.util.List<java.lang.String!>!> getFilterDocumentIds();
     method public java.util.List<java.lang.String!> getFilterNamespaces();
     method public java.util.List<java.lang.String!> getFilterSchemas();
@@ -577,7 +586,7 @@
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterNamespaces(java.util.Collection<java.lang.String!>);
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterSchemas(java.lang.String!...);
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder addFilterSchemas(java.util.Collection<java.lang.String!>);
-    method public androidx.appsearch.app.SearchSuggestionSpec build() throws androidx.appsearch.exceptions.AppSearchException;
+    method public androidx.appsearch.app.SearchSuggestionSpec build();
     method public androidx.appsearch.app.SearchSuggestionSpec.Builder setRankingStrategy(int);
   }
 
diff --git a/appsearch/appsearch/build.gradle b/appsearch/appsearch/build.gradle
index f991e23..c4fbedbb 100644
--- a/appsearch/appsearch/build.gradle
+++ b/appsearch/appsearch/build.gradle
@@ -40,9 +40,15 @@
     implementation('androidx.core:core:1.7.0')
 
     androidTestAnnotationProcessor project(':appsearch:appsearch-compiler')
+    androidTestImplementation project(':appsearch:appsearch-builtin-types')
     androidTestImplementation project(':appsearch:appsearch-local-storage')
     androidTestImplementation project(':appsearch:appsearch-platform-storage')
+    androidTestImplementation project(':appsearch:appsearch-play-services-storage')
     androidTestImplementation project(':appsearch:appsearch-test-util')
+    // Needed to check if PlayServicesAppSearch throws ApiException.
+    androidTestImplementation("com.google.android.gms:play-services-basement:18.1.0", {
+        exclude group: "androidx.core", module: "core"
+    })
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.truth)
diff --git a/appsearch/appsearch/lint-baseline.xml b/appsearch/appsearch/lint-baseline.xml
index 00718c8..d830b1c 100644
--- a/appsearch/appsearch/lint-baseline.xml
+++ b/appsearch/appsearch/lint-baseline.xml
@@ -1,653 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public void checkSuccess() {"
-        errorLine2="                ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchBatchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public interface AppSearchObserverCallback extends ObserverCallback {}"
-        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface ResultCode {}"
-        errorLine2="                      ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public static &lt;ValueType> AppSearchResult&lt;ValueType> newFailedResult("
-        errorLine2="                                                         ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public static &lt;ValueType> AppSearchResult&lt;ValueType> throwableToFailedResult("
-        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public AppSearchSchema(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface DataType {}"
-        errorLine2="                          ~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_STRING = 1;"
-        errorLine2="                                ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_LONG = 2;"
-        errorLine2="                                ~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_DOUBLE = 3;"
-        errorLine2="                                ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_BOOLEAN = 4;"
-        errorLine2="                                ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_BYTES = 5;"
-        errorLine2="                                ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static final int DATA_TYPE_DOCUMENT = 6;"
-        errorLine2="                                ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface Cardinality {}"
-        errorLine2="                          ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @DataType int getDataType() {"
-        errorLine2="                             ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public static PropertyConfig fromBundle(@NonNull Bundle propertyBundle) {"
-        errorLine2="                                     ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface IndexingType {}"
-        errorLine2="                          ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface TokenizerType {}"
-        errorLine2="                          ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface JoinableValueType {}"
-        errorLine2="                          ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public @interface IndexingType {}"
-        errorLine2="                          ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSchema.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    ListenableFuture&lt;List&lt;SearchSuggestionResult>> searchSuggestionAsync("
-        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/AppSearchSession.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class BundleUtil {"
-        errorLine2="                   ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/util/BundleUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class DocumentClassFactoryRegistry {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/DocumentClassFactoryRegistry.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public GenericDocument(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/GenericDocument.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/GenericDocument.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Map&lt;String, List&lt;String>> getProjectionsInternal() {"
-        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/GetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Builder(boolean getVisibilitySettingSupported) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/GetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class IllegalSchemaException extends IllegalArgumentException {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/exceptions/IllegalSchemaException.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class IndentingStringBuilder {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/util/IndentingStringBuilder.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class InternalSetSchemaResponse {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface AggregationScoringStrategy {"
-        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/JoinSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public JoinSpec(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/JoinSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/JoinSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class LogUtil {"
-        errorLine2="                   ~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/util/LogUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public ObserverSpec(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/observer/ObserverSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/observer/ObserverSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public PackageIdentifier(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/PackageIdentifier.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/PackageIdentifier.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SchemaMigrationStats {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public final class SchemaMigrationUtil {"
-        errorLine2="                   ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/util/SchemaMigrationUtil.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public SearchResult(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class SearchResultPage {"
-        errorLine2="             ~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchResultPage.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public static final int DEFAULT_NUM_PER_PAGE = 10;"
-        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface TermMatch {"
-        errorLine2="                      ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface RankingStrategy {"
-        errorLine2="                      ~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Order {"
-        errorLine2="                      ~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface GroupingType {"
-        errorLine2="                      ~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public SearchSpec(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public List&lt;String> getEnabledFeatures() {"
-        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionResult.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public SearchSuggestionSpec(@NonNull Bundle bundle) {"
-        errorLine2="           ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface SuggestionRankingStrategy {"
-        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Map&lt;String, List&lt;String>> getFilterProperties() {"
-        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Builder addFilterProperties(@NonNull String schema,"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Builder addFilterPropertyPaths(@NonNull String schema,"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Builder addFilterProperties(@NonNull Class&lt;?> documentClass,"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Builder addFilterPropertyPaths(@NonNull Class&lt;?> documentClass,"
-        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface AppSearchSupportedPermission {}"
-        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SetSchemaRequest.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Map&lt;String, Set&lt;PackageIdentifier>> getSchemasVisibleToPackagesInternal() {"
-        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SetSchemaRequest.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Builder toBuilder() {"
-        errorLine2="                   ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="        public Bundle getBundle() {"
-        errorLine2="                      ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/SetSchemaResponse.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public Bundle getBundle() {"
-        errorLine2="                  ~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/StorageInfo.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityDocument extends GenericDocument {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/VisibilityDocument.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="public class VisibilityPermissionDocument extends GenericDocument {"
-        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java"/>
-    </issue>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="SupportAnnotationUsage"
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
index 2e657eb..1f25e64 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AnnotationProcessorTestBase.java
@@ -17,15 +17,26 @@
 package androidx.appsearch.app;
 
 import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES;
+import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID;
 import static androidx.appsearch.app.AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN;
 import static androidx.appsearch.testutil.AppSearchTestUtils.checkIsBatchResultSuccess;
 import static androidx.appsearch.testutil.AppSearchTestUtils.convertSearchResultsToDocuments;
+import static androidx.appsearch.testutil.AppSearchTestUtils.doGet;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
 import androidx.annotation.NonNull;
 import androidx.appsearch.annotation.Document;
+import androidx.appsearch.builtintypes.PotentialAction;
+import androidx.appsearch.builtintypes.Thing;
+import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.testutil.AppSearchEmail;
+import androidx.appsearch.util.DocumentIdUtil;
+import androidx.test.core.app.ApplicationProvider;
 
 import com.google.auto.value.AutoValue;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -40,6 +51,8 @@
 
 public abstract class AnnotationProcessorTestBase {
     private AppSearchSession mSession;
+    private static final String TEST_PACKAGE_NAME =
+            ApplicationProvider.getApplicationContext().getPackageName();
     private static final String DB_NAME_1 = "";
 
     protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
@@ -241,7 +254,7 @@
             assertThat(first.toArray()).isEqualTo(second.toArray());
         }
 
-        public static Gift createPopulatedGift() {
+        public static Gift createPopulatedGift() throws AppSearchException {
             Gift gift = new Gift();
             gift.mNamespace = "gift.namespace";
             gift.mId = "gift.id";
@@ -295,6 +308,33 @@
         }
     }
 
+
+    @Document
+    static class CardAction {
+        @Document.Namespace
+        String mNamespace;
+
+        @Document.Id
+        String mId;
+        @Document.StringProperty(name = "cardRef",
+                joinableValueType = JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+        String mCardReference; // 3a
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof CardAction)) {
+                return false;
+            }
+            CardAction otherGift = (CardAction) other;
+            assertThat(otherGift.mNamespace).isEqualTo(this.mNamespace);
+            assertThat(otherGift.mId).isEqualTo(this.mId);
+            assertThat(otherGift.mCardReference).isEqualTo(this.mCardReference);
+            return true;
+        }
+    }
+
     @Test
     public void testAnnotationProcessor() throws Exception {
         //TODO(b/156296904) add test for int, float, GenericDocument, and class with
@@ -323,9 +363,9 @@
     @Test
     public void testAnnotationProcessor_queryByType() throws Exception {
         mSession.setSchemaAsync(
-                new SetSchemaRequest.Builder()
-                        .addDocumentClasses(Card.class, Gift.class)
-                        .addSchemas(AppSearchEmail.SCHEMA).build())
+                        new SetSchemaRequest.Builder()
+                                .addDocumentClasses(Card.class, Gift.class)
+                                .addSchemas(AppSearchEmail.SCHEMA).build())
                 .get();
 
         // Create documents and index them
@@ -377,6 +417,61 @@
     }
 
     @Test
+    public void testAnnotationProcessor_simpleJoin() throws Exception {
+        assumeTrue(mSession.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+        mSession.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addDocumentClasses(Card.class, CardAction.class)
+                                .build())
+                .get();
+
+        // Index a Card and a Gift referencing it.
+        Card peetsCard = new Card();
+        peetsCard.mNamespace = "personal";
+        peetsCard.mId = "peets1";
+        CardAction bdayGift = new CardAction();
+        bdayGift.mNamespace = "personal";
+        bdayGift.mId = "2023-jan-31";
+        bdayGift.mCardReference = DocumentIdUtil.createQualifiedId(TEST_PACKAGE_NAME, DB_NAME_1,
+                GenericDocument.fromDocumentClass(peetsCard));
+        checkIsBatchResultSuccess(mSession.putAsync(
+                new PutDocumentsRequest.Builder().addDocuments(peetsCard, bdayGift).build()));
+
+        // Retrieve cards with any given gifts.
+        SearchSpec innerSpec = new SearchSpec.Builder()
+                .addFilterDocumentClasses(CardAction.class)
+                .build();
+        JoinSpec js = new JoinSpec.Builder("cardRef")
+                .setNestedSearch(/*nestedQuery*/ "", innerSpec)
+                .build();
+        SearchResults resultsIter = mSession.search(/*queryExpression*/ "",
+                new SearchSpec.Builder()
+                        .addFilterDocumentClasses(Card.class)
+                        .setJoinSpec(js)
+                        .build());
+
+        // Verify that search results include card(s) joined with gift(s).
+        List<SearchResult> results = resultsIter.getNextPageAsync().get();
+        assertThat(results).hasSize(1);
+        GenericDocument cardResultDoc = results.get(0).getGenericDocument();
+        assertThat(cardResultDoc.getId()).isEqualTo(peetsCard.mId);
+        List<SearchResult> joinedCardResults = results.get(0).getJoinedResults();
+        assertThat(joinedCardResults).hasSize(1);
+        GenericDocument giftResultDoc = joinedCardResults.get(0).getGenericDocument();
+        assertThat(giftResultDoc.getId()).isEqualTo(bdayGift.mId);
+    }
+
+    @Test
+    public void testAnnotationProcessor_onTAndBelow_joinNotSupported() throws Exception {
+        assumeFalse(mSession.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+        Exception e = assertThrows(UnsupportedOperationException.class,
+                () -> mSession.setSchemaAsync(
+                        new SetSchemaRequest.Builder()
+                                .addDocumentClasses(Card.class, CardAction.class)
+                                .build()));
+    }
+
+    @Test
     public void testGenericDocumentConversion() throws Exception {
         Gift inGift = Gift.createPopulatedGift();
         GenericDocument genericDocument1 = GenericDocument.fromDocumentClass(inGift);
@@ -472,4 +567,123 @@
         List<GenericDocument> documents = convertSearchResultsToDocuments(searchResults);
         assertThat(documents).containsExactly(genericDocument);
     }
+
+    @Test
+    public void testActionDocumentPutAndRetrieveHelper() throws Exception {
+        String namespace = "namespace";
+        String id = "docId";
+        String name = "View";
+        String uri = "package://view";
+        String description = "View action";
+        long creationMillis = 300;
+
+        GenericDocument genericDocAction = new GenericDocument.Builder<>(namespace, id,
+                "builtin:PotentialAction")
+                .setPropertyString("name", name)
+                .setPropertyString("uri", uri)
+                .setPropertyString("description", description)
+                .setCreationTimestampMillis(creationMillis)
+                .build();
+
+        mSession.setSchemaAsync(
+                new SetSchemaRequest.Builder().addDocumentClasses(PotentialAction.class)
+                        .setForceOverride(true).build()).get();
+        checkIsBatchResultSuccess(
+                mSession.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(
+                        genericDocAction).build()));
+
+        GetByDocumentIdRequest request = new GetByDocumentIdRequest.Builder(namespace)
+                .addIds(id)
+                .build();
+        List<GenericDocument> outDocuments = doGet(mSession, request);
+        assertThat(outDocuments).hasSize(1);
+        PotentialAction potentialAction =
+                outDocuments.get(0).toDocumentClass(PotentialAction.class);
+
+        assertThat(potentialAction.getName()).isEqualTo(name);
+        assertThat(potentialAction.getUri()).isEqualTo(uri);
+        assertThat(potentialAction.getDescription()).isEqualTo(description);
+    }
+
+    @Test
+    public void testDependentSchemas() throws Exception {
+        // Test that makes sure if you call setSchema on Thing, PotentialAction also goes in.
+        String namespace = "namespace";
+        String name = "View";
+        String uri = "package://view";
+        String description = "View action";
+        long creationMillis = 300;
+
+        GenericDocument genericDocAction = new GenericDocument.Builder<>(namespace, "actionid",
+                "builtin:PotentialAction")
+                .setPropertyString("name", name)
+                .setPropertyString("uri", uri)
+                .setPropertyString("description", description)
+                .setCreationTimestampMillis(creationMillis)
+                .build();
+
+        Thing thing = new Thing.Builder(namespace, "thingid")
+                .setName(name)
+                .setCreationTimestampMillis(creationMillis).build();
+
+        SetSchemaRequest request = new SetSchemaRequest.Builder().addDocumentClasses(Thing.class)
+                .setForceOverride(true).build();
+
+        // Both Thing and PotentialAction should be set as schemas
+        assertThat(request.getSchemas()).hasSize(2);
+        mSession.setSchemaAsync(request).get();
+
+        assertThat(mSession.getSchemaAsync().get().getSchemas()).hasSize(2);
+
+        // We should be able to put a PotentialAction as well as a Thing
+        checkIsBatchResultSuccess(
+                mSession.putAsync(new PutDocumentsRequest.Builder()
+                        .addDocuments(thing)
+                        .addGenericDocuments(genericDocAction)
+                        .build()));
+
+        GetByDocumentIdRequest getDocRequest = new GetByDocumentIdRequest.Builder(namespace)
+                .addIds("thingid")
+                .build();
+        List<GenericDocument> outDocuments = doGet(mSession, getDocRequest);
+        assertThat(outDocuments).hasSize(1);
+        Thing potentialAction = outDocuments.get(0).toDocumentClass(Thing.class);
+
+        assertThat(potentialAction.getNamespace()).isEqualTo(namespace);
+        assertThat(potentialAction.getId()).isEqualTo("thingid");
+        assertThat(potentialAction.getName()).isEqualTo(name);
+        assertThat(potentialAction.getPotentialActions()).isEmpty();
+    }
+
+    @Document
+    static class Outer {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Middle mMiddle;
+    }
+
+    @Document
+    static class Middle {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Inner mInner;
+    }
+
+    @Document
+    static class Inner {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.StringProperty String mContents;
+    }
+
+    @Test
+    public void testMultipleDependentSchemas() throws Exception {
+        SetSchemaRequest request = new SetSchemaRequest.Builder().addDocumentClasses(Outer.class)
+                .setForceOverride(true).build();
+
+        // Outer, as well as Middle and Inner should be set.
+        assertThat(request.getSchemas()).hasSize(3);
+        mSession.setSchemaAsync(request).get();
+        assertThat(mSession.getSchemaAsync().get().getSchemas()).hasSize(3);
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchSessionInternalTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchSessionInternalTestBase.java
index 8310664..c289e9e 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchSessionInternalTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/AppSearchSessionInternalTestBase.java
@@ -17,12 +17,18 @@
 package androidx.appsearch.app;
 
 import static androidx.appsearch.testutil.AppSearchTestUtils.checkIsBatchResultSuccess;
+import static androidx.appsearch.testutil.AppSearchTestUtils.convertSearchResultsToDocuments;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
+
 import androidx.annotation.NonNull;
 import androidx.appsearch.app.AppSearchSchema.PropertyConfig;
 import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig;
+import androidx.appsearch.testutil.AppSearchEmail;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -32,6 +38,7 @@
 import org.junit.Test;
 
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 
 public abstract class AppSearchSessionInternalTestBase {
@@ -167,4 +174,382 @@
                         .build()).get();
         assertThat(suggestions).containsExactly(resultOne, resultThree, resultFour);
     }
+
+    // TODO(b/258715421): move this test to cts test once we un-hide schema type grouping API.
+    @Test
+    public void testQuery_ResultGroupingLimits_SchemaGroupingSupported() throws Exception {
+        assumeTrue(mDb1.getFeatures()
+                .isFeatureSupported(Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA));
+        // Schema registration
+        AppSearchSchema genericSchema = new AppSearchSchema.Builder("Generic")
+                .addProperty(new StringPropertyConfig.Builder("foo")
+                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                .build()
+            ).build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .addSchemas(AppSearchEmail.SCHEMA)
+                .addSchemas(genericSchema)
+                .build())
+            .get();
+
+        // Index four documents.
+        AppSearchEmail inEmail1 =
+                new AppSearchEmail.Builder("namespace1", "id1")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
+        AppSearchEmail inEmail2 =
+                new AppSearchEmail.Builder("namespace1", "id2")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
+        AppSearchEmail inEmail3 =
+                new AppSearchEmail.Builder("namespace2", "id3")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail3).build()));
+        AppSearchEmail inEmail4 =
+                new AppSearchEmail.Builder("namespace2", "id4")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail4).build()));
+        AppSearchEmail inEmail5 =
+                new AppSearchEmail.Builder("namespace2", "id5")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail5).build()));
+        GenericDocument inDoc1 =
+                new GenericDocument.Builder<>("namespace3", "id6", "Generic")
+                .setPropertyString("foo", "body").build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inDoc1).build()));
+        GenericDocument inDoc2 =
+                new GenericDocument.Builder<>("namespace3", "id7", "Generic")
+                .setPropertyString("foo", "body").build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inDoc2).build()));
+        GenericDocument inDoc3 =
+                new GenericDocument.Builder<>("namespace4", "id8", "Generic")
+                .setPropertyString("foo", "body").build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inDoc3).build()));
+
+        // Query with per package result grouping. Only the last document 'doc3' should be
+        // returned.
+        SearchResults searchResults = mDb1.search("body", new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+                .build());
+        List<GenericDocument> documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3);
+
+        // Query with per namespace result grouping. Only the last document in each namespace should
+        // be returned ('doc3', 'doc2', 'email5' and 'email2').
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail2);
+
+        // Query with per namespace result grouping. Two of the last documents in each namespace
+        // should be returned ('doc3', 'doc2', 'doc1', 'email5', 'email4', 'email2', 'email1')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inDoc1, inEmail5, inEmail4, inEmail2,
+                inEmail1);
+
+        // Query with per schema result grouping. Only the last document of each schema type should
+        // be returned ('doc3', 'email5')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inEmail5);
+
+        // Query with per schema result grouping. Only the last two documents of each schema type
+        // should be returned ('doc3', 'doc2', 'email5', 'email4')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail4);
+
+        // Query with per package and per namespace result grouping. Only the last document in each
+        // namespace should be returned ('doc3', 'doc2', 'email5' and 'email2').
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail2);
+
+        // Query with per package and per namespace result grouping. Only the last two documents
+        // in each namespace should be returned ('doc3', 'doc2', 'doc1', 'email5', 'email4',
+        // 'email2', 'email1')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inDoc1, inEmail5, inEmail4, inEmail2,
+                inEmail1);
+
+        // Query with per package and per schema type result grouping. Only the last document in
+        // each schema type should be returned. ('doc3', 'email5')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_SCHEMA
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inEmail5);
+
+        // Query with per package and per schema type result grouping. Only the last two document in
+        // each schema type should be returned. ('doc3', 'doc2', 'email5', 'email4')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_SCHEMA
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail4);
+
+        // Query with per namespace and per schema type result grouping. Only the last document in
+        // each namespace should be returned. ('doc3', 'doc2', 'email5' and 'email2').
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail2);
+
+        // Query with per namespace and per schema type result grouping. Only the last two documents
+        // in each namespace should be returned. ('doc3', 'doc2', 'doc1', 'email5', 'email4',
+        // 'email2', 'email1')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                    | SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inDoc1, inEmail5, inEmail4, inEmail2,
+                inEmail1);
+
+        // Query with per namespace, per package and per schema type result grouping. Only the last
+        // document in each namespace should be returned. ('doc3', 'doc2', 'email5' and 'email2')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE | SearchSpec.GROUPING_TYPE_PER_SCHEMA
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inEmail5, inEmail2);
+
+        // Query with per namespace, per package and per schema type result grouping. Only the last
+        // two documents in each namespace should be returned.('doc3', 'doc2', 'doc1', 'email5',
+        // 'email4', 'email2', 'email1')
+        searchResults = mDb1.search("body", new SearchSpec.Builder()
+            .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+            .setResultGrouping(
+                SearchSpec.GROUPING_TYPE_PER_NAMESPACE | SearchSpec.GROUPING_TYPE_PER_SCHEMA
+                    | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 2)
+            .build());
+        documents = convertSearchResultsToDocuments(searchResults);
+        assertThat(documents).containsExactly(inDoc3, inDoc2, inDoc1, inEmail5, inEmail4, inEmail2,
+                inEmail1);
+    }
+
+    // TODO(b/258715421): move this test to cts test once we un-hide schema type grouping API.
+    @Test
+    public void testQuery_ResultGroupingLimits_SchemaGroupingNotSupported() throws Exception {
+        assumeFalse(mDb1.getFeatures()
+                .isFeatureSupported(Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA));
+        // Schema registration
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+            .addSchemas(AppSearchEmail.SCHEMA).build()).get();
+
+        // Index four documents.
+        AppSearchEmail inEmail1 =
+                new AppSearchEmail.Builder("namespace1", "id1")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
+        AppSearchEmail inEmail2 =
+                new AppSearchEmail.Builder("namespace1", "id2")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
+        AppSearchEmail inEmail3 =
+                new AppSearchEmail.Builder("namespace2", "id3")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail3).build()));
+        AppSearchEmail inEmail4 =
+                new AppSearchEmail.Builder("namespace2", "id4")
+                .setFrom("from@example.com")
+                .setTo("to1@example.com", "to2@example.com")
+                .setSubject("testPut example")
+                .setBody("This is the body of the testPut email")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail4).build()));
+
+        // SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA is not supported.
+        // UnsupportedOperationException will be thrown.
+        SearchSpec searchSpec1 = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 1)
+                .build();
+        UnsupportedOperationException exception = assertThrows(UnsupportedOperationException.class,
+                () -> mDb1.search("body", searchSpec1));
+        assertThat(exception).hasMessageThat().contains(
+                Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA + " is not available on this"
+                + " AppSearch implementation.");
+
+        // SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA is not supported.
+        // UnsupportedOperationException will be thrown.
+        SearchSpec searchSpec2 = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_PACKAGE
+                | SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 1)
+                .build();
+        exception = assertThrows(UnsupportedOperationException.class,
+            () -> mDb1.search("body", searchSpec2));
+        assertThat(exception).hasMessageThat().contains(
+                Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA + " is not available on this"
+                + " AppSearch implementation.");
+
+        // SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA is not supported.
+        // UnsupportedOperationException will be thrown.
+        SearchSpec searchSpec3 = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                | SearchSpec.GROUPING_TYPE_PER_SCHEMA, /*resultLimit=*/ 1)
+                .build();
+        exception = assertThrows(UnsupportedOperationException.class,
+                () -> mDb1.search("body", searchSpec3));
+        assertThat(exception).hasMessageThat().contains(
+                Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA + " is not available on this"
+                + " AppSearch implementation.");
+
+        // SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA is not supported.
+        // UnsupportedOperationException will be thrown.
+        SearchSpec searchSpec4 = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                | SearchSpec.GROUPING_TYPE_PER_SCHEMA
+                | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+                .build();
+        exception = assertThrows(UnsupportedOperationException.class,
+                () -> mDb1.search("body", searchSpec4));
+        assertThat(exception).hasMessageThat().contains(
+                Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA + " is not available on this"
+                + " AppSearch implementation.");
+    }
+
+    // TODO(b/268521214): Move test to cts once deletion propagation is available in framework.
+    @Test
+    public void testGetSchema_joinableValueType() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.SCHEMA_SET_DELETION_PROPAGATION));
+        AppSearchSchema inSchema = new AppSearchSchema.Builder("Test")
+                .addProperty(new StringPropertyConfig.Builder("normalStr")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .build()
+                ).addProperty(new StringPropertyConfig.Builder("optionalQualifiedIdStr")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setJoinableValueType(StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .build()
+                ).addProperty(new StringPropertyConfig.Builder("requiredQualifiedIdStr")
+                        .setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
+                        .setJoinableValueType(StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .setDeletionPropagation(true)
+                        .build()
+                ).build();
+
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(inSchema).build();
+
+        mDb1.setSchemaAsync(request).get();
+
+        Set<AppSearchSchema> actual = mDb1.getSchemaAsync().get().getSchemas();
+        assertThat(actual).hasSize(1);
+        assertThat(actual).containsExactlyElementsIn(request.getSchemas());
+    }
+
+    // TODO(b/268521214): Move test to cts once deletion propagation is available in framework.
+    @Test
+    public void testGetSchema_deletionPropagation_unsupported() {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(
+                Features.SCHEMA_SET_DELETION_PROPAGATION));
+        AppSearchSchema schema = new AppSearchSchema.Builder("Test")
+                .addProperty(new StringPropertyConfig.Builder("qualifiedIdDeletionPropagation")
+                        .setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
+                        .setJoinableValueType(StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .setDeletionPropagation(true)
+                        .build()
+                ).build();
+        SetSchemaRequest request = new SetSchemaRequest.Builder()
+                .addSchemas(schema).build();
+        Exception e = assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.setSchemaAsync(request).get());
+        assertThat(e.getMessage()).isEqualTo("Setting deletion propagation is not supported "
+                + "on this AppSearch implementation.");
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSuggestionSpecInternalTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSuggestionSpecInternalTest.java
index 3130c92..bc68f37 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSuggestionSpecInternalTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SearchSuggestionSpecInternalTest.java
@@ -16,14 +16,10 @@
 
 package androidx.appsearch.app;
 
-import static androidx.appsearch.app.AppSearchResult.RESULT_INVALID_ARGUMENT;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
-import androidx.appsearch.exceptions.AppSearchException;
-
 import com.google.common.collect.ImmutableList;
 
 import org.junit.Test;
@@ -54,12 +50,11 @@
 
     @Test
     public void testPropertyFilterMustMatchSchemaFilter() throws Exception {
-        AppSearchException e = assertThrows(AppSearchException.class,
+        IllegalStateException e = assertThrows(IllegalStateException.class,
                 () -> new SearchSuggestionSpec.Builder(/*totalResultCount=*/123)
                         .addFilterSchemas("Person")
                         .addFilterProperties("Email", ImmutableList.of("Subject", "body"))
                         .build());
-        assertThat(e.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
         assertThat(e).hasMessageThat().contains("The schema: Email exists in the "
                 + "property filter but doesn't exist in the schema filter.");
     }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
index 799584a..37e1255 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/app/SetSchemaResponseInternalTest.java
@@ -18,8 +18,15 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertThrows;
+
+import androidx.appsearch.app.AppSearchSchema.PropertyConfig;
+import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig;
+
 import org.junit.Test;
 
+import java.util.List;
+
 /** Tests for private APIs of {@link SetSchemaResponse}. */
 public class SetSchemaResponseInternalTest {
     @Test
@@ -67,4 +74,41 @@
         assertThat(rebuild.getMigratedTypes()).containsExactly("migrated1", "migrated2");
         assertThat(rebuild.getMigrationFailures()).containsExactly(failure1, failure2);
     }
+
+    // TODO(b/268521214): Move test to cts once deletion propagation is available in framework.
+    @Test
+    public void testPropertyConfig_deletionPropagation() {
+        AppSearchSchema schema = new AppSearchSchema.Builder("Test")
+                .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("qualifiedId1")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setJoinableValueType(StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .setDeletionPropagation(true)
+                        .build())
+                .build();
+
+        assertThat(schema.getSchemaType()).isEqualTo("Test");
+        List<PropertyConfig> properties = schema.getProperties();
+        assertThat(properties).hasSize(1);
+
+        assertThat(properties.get(0).getName()).isEqualTo("qualifiedId1");
+        assertThat(properties.get(0).getCardinality())
+                .isEqualTo(PropertyConfig.CARDINALITY_OPTIONAL);
+        assertThat(((StringPropertyConfig) properties.get(0)).getJoinableValueType())
+                .isEqualTo(StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID);
+        assertThat(((StringPropertyConfig) properties.get(0)).getDeletionPropagation())
+                .isEqualTo(true);
+    }
+
+    // TODO(b/268521214): Move test to cts once deletion propagation is available in framework.
+    @Test
+    public void testStringPropertyConfig_setJoinableProperty_deletePropagationError() {
+        final StringPropertyConfig.Builder builder =
+                new StringPropertyConfig.Builder("qualifiedId")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setDeletionPropagation(true);
+        IllegalStateException e =
+                assertThrows(IllegalStateException.class, () -> builder.build());
+        assertThat(e).hasMessageThat().contains(
+                "Cannot set deletion propagation without setting a joinable value type");
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
index 75b3888..0d0ac6e 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSchemaMigrationLocalCtsTest.java
@@ -22,12 +22,10 @@
 import androidx.appsearch.app.AppSearchSession;
 import androidx.appsearch.localstorage.LocalStorage;
 import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.FlakyTest;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
-@FlakyTest(bugId = 242761389)
-public class AppSearchSchemaMigrationLocalCtsTest extends AppSearchSchemaMigrationCtsTestBase{
+public class AppSearchSchemaMigrationLocalCtsTest extends AppSearchSchemaMigrationCtsTestBase {
     @Override
     protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName) {
         Context context = ApplicationProvider.getApplicationContext();
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
index bf470fd..01924df 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionCtsTestBase.java
@@ -36,6 +36,7 @@
 import androidx.appsearch.app.AppSearchBatchResult;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.AppSearchSchema.DocumentPropertyConfig;
 import androidx.appsearch.app.AppSearchSchema.LongPropertyConfig;
 import androidx.appsearch.app.AppSearchSchema.PropertyConfig;
 import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig;
@@ -94,10 +95,10 @@
     private AppSearchSession mDb2;
 
     protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
-            @NonNull String dbName);
+            @NonNull String dbName) throws Exception;
 
     protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
-            @NonNull String dbName, @NonNull ExecutorService executor);
+            @NonNull String dbName, @NonNull ExecutorService executor) throws Exception;
 
     @Before
     public void setUp() throws Exception {
@@ -147,20 +148,22 @@
         AppSearchSchema emailSchema1 = new AppSearchSchema.Builder(AppSearchEmail.SCHEMA_TYPE)
                 .build();
 
-        Throwable throwable = assertThrows(ExecutionException.class,
-                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
-                        .addSchemas(emailSchema1).build()).get()).getCause();
-        assertThat(throwable).isInstanceOf(AppSearchException.class);
-        AppSearchException exception = (AppSearchException) throwable;
+        SetSchemaRequest setSchemaRequest1 =
+                new SetSchemaRequest.Builder().addSchemas(emailSchema1).build();
+        ExecutionException executionException =
+                assertThrows(ExecutionException.class,
+                        () -> mDb1.setSchemaAsync(setSchemaRequest1).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_SCHEMA);
         assertThat(exception).hasMessageThat().contains("Schema is incompatible.");
         assertThat(exception).hasMessageThat().contains("Incompatible types: {builtin:Email}");
 
-        throwable = assertThrows(ExecutionException.class,
-                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
-
-        assertThat(throwable).isInstanceOf(AppSearchException.class);
-        exception = (AppSearchException) throwable;
+        SetSchemaRequest setSchemaRequest2 = new SetSchemaRequest.Builder().build();
+        executionException = assertThrows(ExecutionException.class,
+                () -> mDb1.setSchemaAsync(setSchemaRequest2).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_SCHEMA);
         assertThat(exception).hasMessageThat().contains("Schema is incompatible.");
         assertThat(exception).hasMessageThat().contains("Deleted types: {builtin:Email}");
@@ -228,6 +231,118 @@
         assertThat(getSchemaResponse.getVersion()).isEqualTo(246);
     }
 
+    @Test
+    public void testSetSchemaWithValidCycle_allowCircularReferences() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SET_SCHEMA_CIRCULAR_REFERENCES));
+
+        // Create schema with valid cycle: Person -> Organization -> Person...
+        AppSearchSchema personSchema = new AppSearchSchema.Builder("Person")
+                .addProperty(new StringPropertyConfig.Builder("name")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .addProperty(new DocumentPropertyConfig.Builder("worksFor", "Organization")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setShouldIndexNestedProperties(true)
+                        .build())
+                .build();
+        AppSearchSchema organizationSchema = new AppSearchSchema.Builder("Organization")
+                .addProperty(new StringPropertyConfig.Builder("name")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .addProperty(new DocumentPropertyConfig.Builder("funder", "Person")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setShouldIndexNestedProperties(false)
+                        .build())
+                .build();
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(personSchema, organizationSchema)
+                        .build()).get();
+
+        // Test that documents following the circular schema are indexable, and that its sections
+        // are searchable
+        GenericDocument person = new GenericDocument.Builder<>("namespace", "person1", "Person")
+                .setPropertyString("name", "John")
+                .setPropertyDocument("worksFor")
+                .build();
+        GenericDocument org = new GenericDocument.Builder<>("namespace", "org1", "Organization")
+                .setPropertyString("name", "Org")
+                .setPropertyDocument("funder", person)
+                .build();
+        GenericDocument person2 = new GenericDocument.Builder<>("namespace", "person2", "Person")
+                .setPropertyString("name", "Jane")
+                .setPropertyDocument("worksFor", org)
+                .build();
+
+        AppSearchBatchResult<String, Void> putResult =
+                checkIsBatchResultSuccess(mDb1.putAsync(
+                        new PutDocumentsRequest.Builder().addGenericDocuments(person, org,
+                                person2).build()));
+        assertThat(putResult.getSuccesses()).containsExactly("person1", null, "org1", null,
+                "person2", null);
+        assertThat(putResult.getFailures()).isEmpty();
+
+        GetByDocumentIdRequest getByDocumentIdRequest =
+                new GetByDocumentIdRequest.Builder("namespace")
+                        .addIds("person1", "person2", "org1")
+                        .build();
+        List<GenericDocument> outDocuments = doGet(mDb1, getByDocumentIdRequest);
+        assertThat(outDocuments).hasSize(3);
+        assertThat(outDocuments).containsExactly(person, person2, org);
+
+        // Both org1 and person2 should be returned for query "Org"
+        // For org1 this matches the 'name' property and for person2 this matches the
+        // 'worksFor.name' property.
+        SearchResults searchResults = mDb1.search("Org", new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build());
+        outDocuments = convertSearchResultsToDocuments(searchResults);
+        assertThat(outDocuments).hasSize(2);
+        assertThat(outDocuments).containsExactly(person2, org);
+    }
+
+    @Test
+    public void testSetSchemaWithValidCycle_circularReferencesNotSupported() {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.SET_SCHEMA_CIRCULAR_REFERENCES));
+
+        // Create schema with valid cycle: Person -> Organization -> Person...
+        AppSearchSchema personSchema = new AppSearchSchema.Builder("Person")
+                .addProperty(new StringPropertyConfig.Builder("name")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .addProperty(new DocumentPropertyConfig.Builder("worksFor", "Organization")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setShouldIndexNestedProperties(true)
+                        .build())
+                .build();
+        AppSearchSchema organizationSchema = new AppSearchSchema.Builder("Organization")
+                .addProperty(new StringPropertyConfig.Builder("name")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build())
+                .addProperty(new DocumentPropertyConfig.Builder("funder", "Person")
+                        .setCardinality(PropertyConfig.CARDINALITY_REPEATED)
+                        .setShouldIndexNestedProperties(false)
+                        .build())
+                .build();
+
+        SetSchemaRequest setSchemaRequest =
+                new SetSchemaRequest.Builder().addSchemas(personSchema, organizationSchema).build();
+        ExecutionException executionException =
+                assertThrows(ExecutionException.class,
+                        () -> mDb1.setSchemaAsync(setSchemaRequest).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().containsMatch("Invalid cycle|Infinite loop");
+    }
+
 // @exportToFramework:startStrip()
 
     @Test
@@ -515,7 +630,6 @@
 
     @Test
     public void testGetSchema_longPropertyIndexingTypeNone_succeeds() throws Exception {
-        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.NUMERIC_SEARCH));
         AppSearchSchema inSchema = new AppSearchSchema.Builder("Test")
                 .addProperty(new LongPropertyConfig.Builder("long")
                         .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
@@ -546,8 +660,10 @@
         SetSchemaRequest request = new SetSchemaRequest.Builder()
                 .addSchemas(inSchema).build();
 
-        assertThrows(UnsupportedOperationException.class, () ->
+        UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class, () ->
                 mDb1.setSchemaAsync(request).get());
+        assertThat(e.getMessage()).isEqualTo("LongProperty.INDEXING_TYPE_RANGE is not "
+                + "supported on this AppSearch implementation.");
     }
 
     @Test
@@ -579,7 +695,6 @@
 
     @Test
     public void testGetSchema_joinableValueTypeNone_succeeds() throws Exception {
-        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
         AppSearchSchema inSchema = new AppSearchSchema.Builder("Test")
                 .addProperty(new StringPropertyConfig.Builder("optionalString")
                         .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
@@ -618,8 +733,11 @@
         SetSchemaRequest request = new SetSchemaRequest.Builder()
                 .addSchemas(inSchema).build();
 
-        assertThrows(UnsupportedOperationException.class, () ->
+        UnsupportedOperationException e = assertThrows(UnsupportedOperationException.class, () ->
                 mDb1.setSchemaAsync(request).get());
+        assertThat(e.getMessage()).isEqualTo(
+                "StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID is not supported on this "
+                        + "AppSearch implementation.");
     }
 
     @Test
@@ -947,10 +1065,11 @@
         assertThat(outEmail).isEqualTo(email);
 
         // Try to remove the email schema. This should fail as it's an incompatible change.
-        Throwable failResult1 = assertThrows(
-                ExecutionException.class,
-                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
-        assertThat(failResult1).isInstanceOf(AppSearchException.class);
+        SetSchemaRequest setSchemaRequest = new SetSchemaRequest.Builder().build();
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> mDb1.setSchemaAsync(setSchemaRequest).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException failResult1 = (AppSearchException) executionException.getCause();
         assertThat(failResult1).hasMessageThat().contains("Schema is incompatible");
         assertThat(failResult1).hasMessageThat().contains(
                 "Deleted types: {builtin:Email}");
@@ -1020,10 +1139,11 @@
 
         // Try to remove the email schema in database1. This should fail as it's an incompatible
         // change.
-        Throwable failResult1 = assertThrows(
-                ExecutionException.class,
-                () -> mDb1.setSchemaAsync(new SetSchemaRequest.Builder().build()).get()).getCause();
-        assertThat(failResult1).isInstanceOf(AppSearchException.class);
+        SetSchemaRequest setSchemaRequest = new SetSchemaRequest.Builder().build();
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> mDb1.setSchemaAsync(setSchemaRequest).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException failResult1 = (AppSearchException) executionException.getCause();
         assertThat(failResult1).hasMessageThat().contains("Schema is incompatible");
         assertThat(failResult1).hasMessageThat().contains(
                 "Deleted types: {builtin:Email}");
@@ -1619,21 +1739,17 @@
         checkIsBatchResultSuccess(mDb1.putAsync(
                 new PutDocumentsRequest.Builder().addGenericDocuments(doc).build()));
 
-        // TODO(b/208654892); Remove setListFilterQueryLanguageEnabled once advanced query is fully
-        //  supported.
         // Query for the document
         // Use advanced query but disable NUMERIC_SEARCH in the SearchSpec.
         SearchResults searchResults = mDb1.search("price < 20",
                 new SearchSpec.Builder()
-                        .setListFilterQueryLanguageEnabled(true)
                         .setNumericSearchEnabled(false)
                         .build());
 
-        Throwable failResult = assertThrows(
-                ExecutionException.class,
-                () -> searchResults.getNextPageAsync().get()).getCause();
-        assertThat(failResult).isInstanceOf(AppSearchException.class);
-        AppSearchException exception = (AppSearchException) failResult;
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> searchResults.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
         assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
         assertThat(exception).hasMessageThat().contains(Features.NUMERIC_SEARCH);
@@ -1738,6 +1854,130 @@
     }
 
     @Test
+    public void testQuery_advancedRankingWithPropertyWeights() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION));
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.SEARCH_SPEC_PROPERTY_WEIGHTS));
+
+        // Schema registration
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder()
+                        .addSchemas(AppSearchEmail.SCHEMA)
+                        .build()).get();
+
+        // Index a document
+        AppSearchEmail inEmail =
+                new AppSearchEmail.Builder("namespace", "id1")
+                        .setFrom("test from")
+                        .setTo("test to")
+                        .setSubject("subject")
+                        .setBody("test body")
+                        .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
+
+        // Query for the document, and set an advanced ranking expression that evaluates to 0.7.
+        SearchResults searchResults = mDb1.search("test", new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setPropertyWeights(AppSearchEmail.SCHEMA_TYPE,
+                        ImmutableMap.of("from", 0.1, "to", 0.2,
+                                "subject", 2.0, "body", 0.4))
+                // this.propertyWeights() returns normalized property weights, in which each
+                // weight is divided by the maximum weight.
+                // As a result, this expression will evaluates to the list {0.1 / 2.0, 0.2 / 2.0,
+                // 0.4 / 2.0}, since the matched properties are "from", "to" and "body", and the
+                // maximum weight provided is 2.0.
+                // Thus, sum(this.propertyWeights()) will be evaluated to 0.05 + 0.1 + 0.2 = 0.35.
+                .setRankingStrategy("sum(this.propertyWeights())")
+                .build());
+        List<SearchResult> results = retrieveAllSearchResults(searchResults);
+        assertThat(results).hasSize(1);
+        assertThat(results.get(0).getGenericDocument()).isEqualTo(inEmail);
+        assertThat(results.get(0).getRankingSignal()).isEqualTo(0.35);
+    }
+
+    @Test
+    public void testQuery_advancedRankingWithJoin() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION));
+        assumeTrue(mDb1.getFeatures()
+                .isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+
+        // A full example of how join might be used
+        AppSearchSchema actionSchema = new AppSearchSchema.Builder("ViewAction")
+                .addProperty(new StringPropertyConfig.Builder("entityId")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setJoinableValueType(StringPropertyConfig
+                                .JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).addProperty(new StringPropertyConfig.Builder("note")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+
+        // Schema registration
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA, actionSchema)
+                        .build()).get();
+
+        // Index a document
+        AppSearchEmail inEmail =
+                new AppSearchEmail.Builder("namespace", "id1")
+                        .setFrom("from@example.com")
+                        .setTo("to1@example.com", "to2@example.com")
+                        .setSubject("testPut example")
+                        .setBody("This is the body of the testPut email")
+                        .setScore(1)
+                        .build();
+
+        String qualifiedId = DocumentIdUtil.createQualifiedId(mContext.getPackageName(), DB_NAME_1,
+                "namespace", "id1");
+        GenericDocument viewAction1 = new GenericDocument.Builder<>("NS", "id2", "ViewAction")
+                .setScore(1)
+                .setPropertyString("entityId", qualifiedId)
+                .setPropertyString("note", "Viewed email on Monday").build();
+        GenericDocument viewAction2 = new GenericDocument.Builder<>("NS", "id3", "ViewAction")
+                .setScore(2)
+                .setPropertyString("entityId", qualifiedId)
+                .setPropertyString("note", "Viewed email on Tuesday").build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail, viewAction1,
+                        viewAction2).build()));
+
+        SearchSpec nestedSearchSpec =
+                new SearchSpec.Builder()
+                        .setRankingStrategy("2 * this.documentScore()")
+                        .setOrder(SearchSpec.ORDER_ASCENDING)
+                        .build();
+
+        JoinSpec js = new JoinSpec.Builder("entityId")
+                .setNestedSearch("", nestedSearchSpec)
+                .build();
+
+        SearchResults searchResults = mDb1.search("body email", new SearchSpec.Builder()
+                // this.childrenRankingSignals() evaluates to the list {1 * 2, 2 * 2}.
+                // Thus, sum(this.childrenRankingSignals()) evaluates to 6.
+                .setRankingStrategy("sum(this.childrenRankingSignals())")
+                .setJoinSpec(js)
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build());
+
+        List<SearchResult> sr = searchResults.getNextPageAsync().get();
+
+        assertThat(sr).hasSize(1);
+        assertThat(sr.get(0).getGenericDocument().getId()).isEqualTo("id1");
+        assertThat(sr.get(0).getJoinedResults()).hasSize(2);
+        assertThat(sr.get(0).getJoinedResults().get(0).getGenericDocument()).isEqualTo(viewAction1);
+        assertThat(sr.get(0).getJoinedResults().get(1).getGenericDocument()).isEqualTo(viewAction2);
+        assertThat(sr.get(0).getRankingSignal()).isEqualTo(6.0);
+    }
+
+    @Test
     public void testQuery_invalidAdvancedRanking() throws Exception {
         assumeTrue(mDb1.getFeatures().isFeatureSupported(
                 Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION));
@@ -1764,16 +2004,54 @@
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                 .setRankingStrategy("sqrt()")
                 .build());
-        Throwable throwable = assertThrows(ExecutionException.class,
-                () -> searchResults.getNextPageAsync().get()).getCause();
-        assertThat(throwable).isInstanceOf(AppSearchException.class);
-        AppSearchException exception = (AppSearchException) throwable;
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> searchResults.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
         assertThat(exception).hasMessageThat().contains(
                 "Math functions must have at least one argument.");
     }
 
     @Test
+    public void testQuery_invalidAdvancedRankingWithChildrenRankingSignals() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(
+                Features.SEARCH_SPEC_ADVANCED_RANKING_EXPRESSION));
+        assumeTrue(mDb1.getFeatures()
+                .isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
+
+        // Schema registration
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder()
+                        .addSchemas(AppSearchEmail.SCHEMA)
+                        .build()).get();
+
+        // Index a document
+        AppSearchEmail inEmail =
+                new AppSearchEmail.Builder("namespace", "id1")
+                        .setFrom("from@example.com")
+                        .setTo("to1@example.com", "to2@example.com")
+                        .setSubject("testPut example")
+                        .setBody("This is the body of the testPut email")
+                        .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail).build()));
+
+        SearchResults searchResults = mDb1.search("body", new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                // Using this.childrenRankingSignals() without the context of a join is invalid.
+                .setRankingStrategy("sum(this.childrenRankingSignals())")
+                .build());
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> searchResults.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().contains(
+                "childrenRankingSignals must only be used with join");
+    }
+
+    @Test
     public void testQuery_unsupportedAdvancedRanking() throws Exception {
         // Assume that advanced ranking has not been supported.
         assumeFalse(mDb1.getFeatures().isFeatureSupported(
@@ -2972,8 +3250,7 @@
         assertThat(doGet(mDb1, "namespace", "id1", "id2", "id3")).hasSize(3);
 
         // Delete the email type
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE)
                         .build())
@@ -3024,8 +3301,7 @@
         assertThat(doGet(mDb2, "namespace", "id2")).hasSize(1);
 
         // Delete the email type in instance 1
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterSchemas(AppSearchEmail.SCHEMA_TYPE)
                         .build())
@@ -3086,8 +3362,7 @@
         assertThat(doGet(mDb1, /*namespace=*/"document", "id3")).hasSize(1);
 
         // Delete the email namespace
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterNamespaces("email")
                         .build())
@@ -3142,8 +3417,7 @@
         assertThat(doGet(mDb2, /*namespace=*/"email", "id2")).hasSize(1);
 
         // Delete the email namespace in instance 1
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .addFilterNamespaces("email")
                         .build())
@@ -3198,8 +3472,7 @@
         assertThat(doGet(mDb2, "namespace", "id2")).hasSize(1);
 
         // Delete the all document in instance 1
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build())
                 .get();
@@ -3273,8 +3546,7 @@
         assertThat(documents).hasSize(2);
 
         // Delete the all document in instance 1 with TERM_MATCH_PREFIX
-        mDb1.removeAsync("",
-                new SearchSpec.Builder()
+        mDb1.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
                         .build())
                 .get();
@@ -3285,8 +3557,7 @@
         assertThat(documents).isEmpty();
 
         // Delete the all document in instance 2 with TERM_MATCH_EXACT_ONLY
-        mDb2.removeAsync("",
-                new SearchSpec.Builder()
+        mDb2.removeAsync("", new SearchSpec.Builder()
                         .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                         .build())
                 .get();
@@ -3331,7 +3602,7 @@
 
         // Delete the all documents
         mDb1.removeAsync("", new SearchSpec.Builder()
-                        .setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build()).get();
+                .setTermMatch(SearchSpec.TERM_MATCH_PREFIX).build()).get();
 
         // Make sure it's still gone
         getResult = mDb1.getByDocumentIdAsync(
@@ -3346,8 +3617,7 @@
         assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
 
         IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
-                () -> mDb2.removeAsync("",
-                new SearchSpec.Builder()
+                () -> mDb2.removeAsync("", new SearchSpec.Builder()
                         .setJoinSpec(new JoinSpec.Builder("entityId").build())
                         .build()));
         assertThat(e.getMessage()).isEqualTo("JoinSpec not allowed in removeByQuery, "
@@ -3480,12 +3750,12 @@
         mDb1.reportUsageAsync(new ReportUsageRequest.Builder("namespace", "id1").build()).get();
 
         // Use an incorrect namespace; it fails
-        ExecutionException e = assertThrows(
-                ExecutionException.class,
-                () -> mDb1.reportUsageAsync(
-                        new ReportUsageRequest.Builder("namespace2", "id1").build()).get());
-        assertThat(e).hasCauseThat().isInstanceOf(AppSearchException.class);
-        AppSearchException cause = (AppSearchException) e.getCause();
+        ReportUsageRequest reportUsageRequest =
+                new ReportUsageRequest.Builder("namespace2", "id1").build();
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> mDb1.reportUsageAsync(reportUsageRequest).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException cause = (AppSearchException) executionException.getCause();
         assertThat(cause.getResultCode()).isEqualTo(RESULT_NOT_FOUND);
     }
 
@@ -3596,8 +3866,7 @@
         // be returned ('email4' and 'email2').
         searchResults = mDb1.search("body", new SearchSpec.Builder()
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                .setResultGrouping(
-                        SearchSpec.GROUPING_TYPE_PER_NAMESPACE, /*resultLimit=*/ 1)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_NAMESPACE, /*resultLimit=*/ 1)
                 .build());
         documents = convertSearchResultsToDocuments(searchResults);
         assertThat(documents).containsExactly(inEmail4, inEmail2);
@@ -3606,9 +3875,8 @@
         // namespace should be returned ('email4' and 'email2').
         searchResults = mDb1.search("body", new SearchSpec.Builder()
                 .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                .setResultGrouping(
-                        SearchSpec.GROUPING_TYPE_PER_NAMESPACE
-                                | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
+                .setResultGrouping(SearchSpec.GROUPING_TYPE_PER_NAMESPACE
+                        | SearchSpec.GROUPING_TYPE_PER_PACKAGE, /*resultLimit=*/ 1)
                 .build());
         documents = convertSearchResultsToDocuments(searchResults);
         assertThat(documents).containsExactly(inEmail4, inEmail2);
@@ -3727,10 +3995,10 @@
         final SetSchemaRequest newRequest =
                 new SetSchemaRequest.Builder().addSchemas(newNestedSchema,
                         newSchema).build();
-        Throwable throwable = assertThrows(ExecutionException.class,
-                () -> mDb1.setSchemaAsync(newRequest).get()).getCause();
-        assertThat(throwable).isInstanceOf(AppSearchException.class);
-        AppSearchException exception = (AppSearchException) throwable;
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> mDb1.setSchemaAsync(newRequest).get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_SCHEMA);
         assertThat(exception).hasMessageThat().contains("Schema is incompatible.");
         assertThat(exception).hasMessageThat().contains("Incompatible types: {TypeA}");
@@ -3840,6 +4108,25 @@
     }
 
     @Test
+    public void testRfc822_unsupportedFeature_throwsException() {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.TOKENIZER_TYPE_RFC822));
+
+        AppSearchSchema emailSchema = new AppSearchSchema.Builder("Email")
+                .addProperty(new StringPropertyConfig.Builder("address")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_RFC822)
+                        .build()
+                ).build();
+
+        Exception e = assertThrows(IllegalArgumentException.class, () ->
+                mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                        .setForceOverride(true).addSchemas(emailSchema).build()).get());
+        assertThat(e.getMessage()).isEqualTo("tokenizerType is out of range of [0, 1] (too high)");
+    }
+
+
+    @Test
     public void testQuery_verbatimSearch() throws Exception {
         assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.VERBATIM_SEARCH));
         AppSearchSchema verbatimSchema = new AppSearchSchema.Builder("VerbatimSchema")
@@ -3886,26 +4173,243 @@
                 .build();
         mDb1.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(email).build()).get();
 
-        // TODO(b/208654892) Disable ListFilterQueryLanguage once EXPERIMENTAL_ICING_ADVANCED_QUERY
-        //  is fully supported.
         // ListFilterQueryLanguage is enabled so that EXPERIMENTAL_ICING_ADVANCED_QUERY gets enabled
         // in IcingLib.
         // Disable VERBATIM_SEARCH in the SearchSpec.
         SearchResults searchResults = mDb1.search("\"Hello, world!\"",
                 new SearchSpec.Builder()
-                        .setListFilterQueryLanguageEnabled(true)
                         .setVerbatimSearchEnabled(false)
                         .build());
-        Throwable throwable = assertThrows(ExecutionException.class,
-                () -> searchResults.getNextPageAsync().get()).getCause();
-        assertThat(throwable).isInstanceOf(AppSearchException.class);
-        AppSearchException exception = (AppSearchException) throwable;
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> searchResults.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
         assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
         assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
         assertThat(exception).hasMessageThat().contains(Features.VERBATIM_SEARCH);
     }
 
     @Test
+    public void testQuery_listFilterQueryWithEnablingFeatureSucceeds() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.LIST_FILTER_QUERY_LANGUAGE));
+        AppSearchSchema schema = new AppSearchSchema.Builder("Schema")
+                .addProperty(new StringPropertyConfig.Builder("prop")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setForceOverride(true).addSchemas(schema).build()).get();
+
+        GenericDocument email = new GenericDocument.Builder<>(
+                "namespace1", "id1", "Schema")
+                .setPropertyString("prop", "Hello, world!")
+                .build();
+        mDb1.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(email).build()).get();
+
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setListFilterQueryLanguageEnabled(true)
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build();
+        // Support for function calls `search`, `createList` was added in list filters
+        SearchResults searchResults = mDb1.search("search(\"hello\", createList(\"prop\"))",
+                searchSpec);
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+
+        // Support for prefix operator * was added in list filters.
+        searchResults = mDb1.search("wor*", searchSpec);
+        page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+
+        // Combining negations with compound statements and property restricts was added in list
+        // filters.
+        searchResults = mDb1.search("NOT (foo OR otherProp:hello)", searchSpec);
+        page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+    }
+
+    @Test
+    public void testQuery_PropertyDefinedWithEnablingFeatureSucceeds() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.LIST_FILTER_QUERY_LANGUAGE));
+        AppSearchSchema schema1 = new AppSearchSchema.Builder("Schema1")
+                .addProperty(new StringPropertyConfig.Builder("prop1")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+        AppSearchSchema schema2 = new AppSearchSchema.Builder("Schema2")
+                .addProperty(new StringPropertyConfig.Builder("prop2")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setForceOverride(true).addSchemas(schema1, schema2).build()).get();
+
+        GenericDocument doc1 = new GenericDocument.Builder<>(
+                "namespace1", "id1", "Schema1")
+                .setPropertyString("prop1", "Hello, world!")
+                .build();
+        GenericDocument doc2 = new GenericDocument.Builder<>(
+                "namespace1", "id2", "Schema2")
+                .setPropertyString("prop2", "Hello, world!")
+                .build();
+        mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(doc1, doc2).build()).get();
+
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setListFilterQueryLanguageEnabled(true)
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .build();
+        // Support for function calls `search`, `createList` was added in list filters
+        SearchResults searchResults = mDb1.search("propertyDefined(\"prop1\")",
+                searchSpec);
+        List<SearchResult> page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
+
+        // Support for prefix operator * was added in list filters.
+        searchResults = mDb1.search("propertyDefined(\"prop2\")", searchSpec);
+        page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
+
+        // Combining negations with compound statements and property restricts was added in list
+        // filters.
+        searchResults = mDb1.search("NOT propertyDefined(\"prop1\")", searchSpec);
+        page = searchResults.getNextPageAsync().get();
+        assertThat(page).hasSize(1);
+        assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
+    }
+
+    @Test
+    public void testQuery_listFilterQueryWithoutEnablingFeatureFails() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.LIST_FILTER_QUERY_LANGUAGE));
+        AppSearchSchema schema = new AppSearchSchema.Builder("Schema")
+                .addProperty(new StringPropertyConfig.Builder("prop")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .build()
+                ).build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder()
+                .setForceOverride(true).addSchemas(schema).build()).get();
+
+        GenericDocument email = new GenericDocument.Builder<>(
+                "namespace1", "id1", "Schema")
+                .setPropertyString("prop", "Hello, world!")
+                .build();
+        mDb1.putAsync(new PutDocumentsRequest.Builder().addGenericDocuments(email).build()).get();
+
+        // Disable LIST_FILTER_QUERY_LANGUAGE in the SearchSpec.
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setListFilterQueryLanguageEnabled(false)
+                .build();
+        SearchResults searchResults = mDb1.search("search(\"hello\", createList(\"prop\"))",
+                searchSpec);
+        ExecutionException executionException = assertThrows(ExecutionException.class,
+                () -> searchResults.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        AppSearchException exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
+        assertThat(exception).hasMessageThat().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
+
+        SearchResults searchResults2 = mDb1.search("wor*", searchSpec);
+        executionException = assertThrows(ExecutionException.class,
+                () -> searchResults2.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
+        assertThat(exception).hasMessageThat().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
+
+        SearchResults searchResults3 = mDb1.search("NOT (foo OR otherProp:hello)", searchSpec);
+        executionException = assertThrows(ExecutionException.class,
+                () -> searchResults3.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
+        assertThat(exception).hasMessageThat().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
+
+        SearchResults searchResults4 = mDb1.search("propertyDefined(\"prop\")", searchSpec);
+        executionException = assertThrows(ExecutionException.class,
+                () -> searchResults4.getNextPageAsync().get());
+        assertThat(executionException).hasCauseThat().isInstanceOf(AppSearchException.class);
+        exception = (AppSearchException) executionException.getCause();
+        assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
+        assertThat(exception).hasMessageThat().contains("Attempted use of unenabled feature");
+        assertThat(exception).hasMessageThat().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
+    }
+
+    @Test
+    public void testQuery_listFilterQueryFeatures_notSupported() throws Exception {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.NUMERIC_SEARCH));
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.VERBATIM_SEARCH));
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.LIST_FILTER_QUERY_LANGUAGE));
+
+        // UnsupportedOperationException will be thrown with these queries so no need to
+        // define a schema and index document.
+        SearchSpec.Builder builder = new SearchSpec.Builder();
+        SearchSpec searchSpec1 = builder.setNumericSearchEnabled(true).build();
+        SearchSpec searchSpec2 = builder.setVerbatimSearchEnabled(true).build();
+        SearchSpec searchSpec3 = builder.setListFilterQueryLanguageEnabled(true).build();
+
+        assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.search("\"Hello, world!\"", searchSpec1));
+        assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.search("\"Hello, world!\"", searchSpec2));
+        assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.search("\"Hello, world!\"", searchSpec3));
+    }
+
+    @Test
+    public void testQuery_propertyWeightsNotSupported() throws Exception {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SPEC_PROPERTY_WEIGHTS));
+
+        // Schema registration
+        mDb1.setSchemaAsync(
+                new SetSchemaRequest.Builder()
+                        .addSchemas(AppSearchEmail.SCHEMA)
+                        .build()).get();
+
+        // Index two documents
+        AppSearchEmail email1 =
+                new AppSearchEmail.Builder("namespace", "id1")
+                        .setCreationTimestampMillis(1000)
+                        .setSubject("foo")
+                        .build();
+        AppSearchEmail email2 =
+                new AppSearchEmail.Builder("namespace", "id2")
+                        .setCreationTimestampMillis(1000)
+                        .setBody("foo")
+                        .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder()
+                        .addGenericDocuments(email1, email2).build()));
+
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                .setRankingStrategy(SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE)
+                .setOrder(SearchSpec.ORDER_DESCENDING)
+                .setPropertyWeights(AppSearchEmail.SCHEMA_TYPE, ImmutableMap.of("subject",
+                        2.0, "body", 0.5))
+                .build();
+        UnsupportedOperationException exception =
+                assertThrows(UnsupportedOperationException.class,
+                        () -> mDb1.search("Hello", searchSpec));
+        assertThat(exception).hasMessageThat().contains("Property weights are not supported");
+    }
+
+    @Test
     public void testQuery_propertyWeights() throws Exception {
         assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SPEC_PROPERTY_WEIGHTS));
 
@@ -4159,7 +4663,7 @@
                 .isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
 
         // A full example of how join might be used
-        AppSearchSchema actionSchema = new AppSearchSchema.Builder("BookmarkAction")
+        AppSearchSchema actionSchema = new AppSearchSchema.Builder("ViewAction")
                 .addProperty(new StringPropertyConfig.Builder("entityId")
                         .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
                         .setIndexingType(StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
@@ -4203,18 +4707,29 @@
 
         String qualifiedId = DocumentIdUtil.createQualifiedId(mContext.getPackageName(), DB_NAME_1,
                 "namespace", "id1");
-        GenericDocument join = new GenericDocument.Builder<>("NS", "id3", "BookmarkAction")
+        GenericDocument viewAction1 = new GenericDocument.Builder<>("NS", "id3", "ViewAction")
+                .setScore(1)
                 .setPropertyString("entityId", qualifiedId)
-                .setPropertyString("note", "Hi this is a joined doc").build();
+                .setPropertyString("note", "Viewed email on Monday").build();
+        GenericDocument viewAction2 = new GenericDocument.Builder<>("NS", "id4", "ViewAction")
+                .setScore(2)
+                .setPropertyString("entityId", qualifiedId)
+                .setPropertyString("note", "Viewed email on Tuesday").build();
         checkIsBatchResultSuccess(mDb1.putAsync(
-                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail, inEmail2, join)
+                new PutDocumentsRequest.Builder().addGenericDocuments(inEmail, inEmail2,
+                                viewAction1, viewAction2)
                         .build()));
 
-        SearchSpec nestedSearchSpec = new SearchSpec.Builder().build();
+        SearchSpec nestedSearchSpec =
+                new SearchSpec.Builder()
+                        .setRankingStrategy(SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE)
+                        .setOrder(SearchSpec.ORDER_ASCENDING)
+                        .build();
 
         JoinSpec js = new JoinSpec.Builder("entityId")
                 .setNestedSearch("", nestedSearchSpec)
                 .setAggregationScoringStrategy(JoinSpec.AGGREGATION_SCORING_RESULT_COUNT)
+                .setMaxJoinedResultCount(1)
                 .build();
 
         SearchResults searchResults = mDb1.search("body email", new SearchSpec.Builder()
@@ -4230,8 +4745,11 @@
 
         assertThat(sr.get(0).getGenericDocument().getId()).isEqualTo("id1");
         assertThat(sr.get(0).getJoinedResults()).hasSize(1);
-        assertThat(sr.get(0).getJoinedResults().get(0).getGenericDocument()).isEqualTo(join);
-        assertThat(sr.get(0).getRankingSignal()).isEqualTo(1.0);
+        assertThat(sr.get(0).getJoinedResults().get(0).getGenericDocument()).isEqualTo(viewAction1);
+        // SearchSpec.Builder#setMaxJoinedResultCount only limits the number of child documents
+        // returned. It does not affect the number of child documents that are scored. So the score
+        // (the COUNT of the number of children) is 2, even though only one child is returned.
+        assertThat(sr.get(0).getRankingSignal()).isEqualTo(2.0);
 
         assertThat(sr.get(1).getGenericDocument().getId()).isEqualTo("id2");
         assertThat(sr.get(1).getRankingSignal()).isEqualTo(0.0);
@@ -4239,26 +4757,35 @@
     }
 
     @Test
-    public void testJoinWithoutSupport() throws Exception {
+    public void testJoin_unsupportedFeature_throwsException() throws Exception {
         assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.JOIN_SPEC_AND_QUALIFIED_ID));
 
         SearchSpec nestedSearchSpec = new SearchSpec.Builder().build();
         JoinSpec js = new JoinSpec.Builder("entityId").setNestedSearch("", nestedSearchSpec)
                 .build();
-        SearchResults searchResults = mDb1.search("", new SearchSpec.Builder()
-                .setJoinSpec(js)
-                .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
-                .build());
+        Exception e = assertThrows(UnsupportedOperationException.class, () -> mDb1.search(
+                /*queryExpression */ "",
+                new SearchSpec.Builder()
+                        .setJoinSpec(js)
+                        .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
+                        .build()));
+        assertThat(e.getMessage()).isEqualTo("JoinSpec is not available on this AppSearch "
+                + "implementation.");
+    }
 
-        Exception e = assertThrows(UnsupportedOperationException.class, () ->
-                searchResults.getNextPageAsync().get());
-        assertThat(e).isInstanceOf(UnsupportedOperationException.class);
-        assertThat(e.getMessage()).isEqualTo("Searching with a SearchSpec containing a JoinSpec "
-                + "is not supported on this AppSearch implementation.");
+    @Test
+    public void testSearchSuggestion_notSupported() throws Exception {
+        assumeFalse(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
+
+        assertThrows(UnsupportedOperationException.class, () ->
+                mDb1.searchSuggestionAsync(
+                        /*suggestionQueryExpression=*/"t",
+                        new SearchSuggestionSpec.Builder(/*totalResultCount=*/2).build()).get());
     }
 
     @Test
     public void testSearchSuggestion() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4311,6 +4838,7 @@
 
     @Test
     public void testSearchSuggestion_namespaceFilter() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4374,6 +4902,7 @@
 
     @Test
     public void testSearchSuggestion_documentIdFilter() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4449,6 +4978,7 @@
 
     @Test
     public void testSearchSuggestion_schemaFilter() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schemaType1 = new AppSearchSchema.Builder("Type1").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4527,6 +5057,7 @@
 
     @Test
     public void testSearchSuggestion_differentPrefix() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4579,6 +5110,7 @@
 
     @Test
     public void testSearchSuggestion_differentRankingStrategy() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4645,6 +5177,7 @@
 
     @Test
     public void testSearchSuggestion_removeDocument() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4697,6 +5230,7 @@
 
     @Test
     public void testSearchSuggestion_replacementDocument() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4747,37 +5281,8 @@
     }
 
     @Test
-    public void testSearchSuggestion_ignoreOperators() throws Exception {
-        // Schema registration
-        AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
-                        new StringPropertyConfig.Builder("body")
-                                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
-                                .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
-                                .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
-                                .build())
-                .build();
-        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get();
-
-        // Index documents
-        GenericDocument doc = new GenericDocument.Builder<>("namespace", "id", "Type")
-                .setPropertyString("body", "two original")
-                .build();
-
-        checkIsBatchResultSuccess(mDb1.putAsync(
-                new PutDocumentsRequest.Builder().addGenericDocuments(doc)
-                        .build()));
-
-        SearchSuggestionResult resultTwoOriginal =
-                new SearchSuggestionResult.Builder().setSuggestedResult("two original").build();
-
-        List<SearchSuggestionResult> suggestions = mDb1.searchSuggestionAsync(
-                /*suggestionQueryExpression=*/"two OR",
-                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
-        assertThat(suggestions).containsExactly(resultTwoOriginal);
-    }
-
-    @Test
     public void testSearchSuggestion_twoInstances() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
         // Schema registration
         AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
                         new StringPropertyConfig.Builder("body")
@@ -4817,4 +5322,120 @@
                 new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
         assertThat(suggestions).isEmpty();
     }
+
+    @Test
+    public void testSearchSuggestion_multipleTerms() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
+        // Schema registration
+        AppSearchSchema schema = new AppSearchSchema.Builder("Type").addProperty(
+                        new StringPropertyConfig.Builder("body")
+                                .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                                .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                                .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                                .build())
+                .build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get();
+
+        // Index documents
+        GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type")
+                .setPropertyString("body", "bar fo")
+                .build();
+        GenericDocument doc2 = new GenericDocument.Builder<>("namespace", "id2", "Type")
+                .setPropertyString("body", "cat foo")
+                .build();
+        GenericDocument doc3 = new GenericDocument.Builder<>("namespace", "id3", "Type")
+                .setPropertyString("body", "fool")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(doc1, doc2, doc3)
+                        .build()));
+
+        // Search "bar AND f" only document 1 should match the search.
+        List<SearchSuggestionResult> suggestions = mDb1.searchSuggestionAsync(
+                /*suggestionQueryExpression=*/"bar f",
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
+        SearchSuggestionResult barFo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("bar fo").build();
+        assertThat(suggestions).containsExactly(barFo);
+
+        // Search for "(bar OR cat) AND f" both document1 "bar fo" and document2 "cat foo" could
+        // match.
+        suggestions = mDb1.searchSuggestionAsync(
+                /*suggestionQueryExpression=*/"bar OR cat f",
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
+        SearchSuggestionResult barCatFo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("bar OR cat fo").build();
+        SearchSuggestionResult barCatFoo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("bar OR cat foo").build();
+        assertThat(suggestions).containsExactly(barCatFo, barCatFoo);
+
+        // Search for "(bar AND cat) OR f", all documents could match.
+        suggestions = mDb1.searchSuggestionAsync(
+                /*suggestionQueryExpression=*/"(bar cat) OR f",
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
+        SearchSuggestionResult barCatOrFo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("(bar cat) OR fo").build();
+        SearchSuggestionResult barCatOrFoo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("(bar cat) OR foo").build();
+        SearchSuggestionResult barCatOrFool =
+                new SearchSuggestionResult.Builder()
+                        .setSuggestedResult("(bar cat) OR fool").build();
+        assertThat(suggestions).containsExactly(barCatOrFo, barCatOrFoo, barCatOrFool);
+
+        // Search for "-bar f", document2 "cat foo" could and document3 "fool" could match.
+        suggestions = mDb1.searchSuggestionAsync(
+                /*suggestionQueryExpression=*/"-bar f",
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
+        SearchSuggestionResult noBarFoo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("-bar foo").build();
+        SearchSuggestionResult noBarFool =
+                new SearchSuggestionResult.Builder().setSuggestedResult("-bar fool").build();
+        assertThat(suggestions).containsExactly(noBarFoo, noBarFool);
+    }
+
+    @Test
+    public void testSearchSuggestion_PropertyRestriction() throws Exception {
+        assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SUGGESTION));
+        // Schema registration
+        AppSearchSchema schema = new AppSearchSchema.Builder("Type")
+                .addProperty(new StringPropertyConfig.Builder("subject")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build())
+                .addProperty(new StringPropertyConfig.Builder("body")
+                        .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+                        .setTokenizerType(StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+                        .setIndexingType(StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+                        .build())
+                .build();
+        mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get();
+
+        // Index documents
+        GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type")
+                .setPropertyString("subject", "bar fo")
+                .setPropertyString("body", "fool")
+                .build();
+        GenericDocument doc2 = new GenericDocument.Builder<>("namespace", "id2", "Type")
+                .setPropertyString("subject", "bar cat foo")
+                .setPropertyString("body", "fool")
+                .build();
+        GenericDocument doc3 = new GenericDocument.Builder<>("namespace", "ide", "Type")
+                .setPropertyString("subject", "fool")
+                .setPropertyString("body", "fool")
+                .build();
+        checkIsBatchResultSuccess(mDb1.putAsync(
+                new PutDocumentsRequest.Builder().addGenericDocuments(doc1, doc2, doc3)
+                        .build()));
+
+        // Search for "bar AND subject:f"
+        List<SearchSuggestionResult> suggestions = mDb1.searchSuggestionAsync(
+                /*suggestionQueryExpression=*/"bar subject:f",
+                new SearchSuggestionSpec.Builder(/*totalResultCount=*/10).build()).get();
+        SearchSuggestionResult barSubjectFo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("bar subject:fo").build();
+        SearchSuggestionResult barSubjectFoo =
+                new SearchSuggestionResult.Builder().setSuggestedResult("bar subject:foo").build();
+        assertThat(suggestions).containsExactly(barSubjectFo, barSubjectFoo);
+    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionGmsCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionGmsCtsTest.java
new file mode 100644
index 0000000..453d9225
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionGmsCtsTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+// @exportToFramework:skipFile()
+
+package androidx.appsearch.cts.app;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.appsearch.app.AppSearchSession;
+import androidx.appsearch.playservicesstorage.PlayServicesStorage;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import java.util.concurrent.ExecutorService;
+
+// TODO(b/237116468): Remove SdkSuppress once AppSearchAttributionSource available for lower API
+//  levels.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
+public class AppSearchSessionGmsCtsTest extends AppSearchSessionCtsTestBase {
+
+    private boolean mIsGmsAvailable;
+    @Override
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName)
+            throws Exception {
+        Context context = ApplicationProvider.getApplicationContext();
+        ListenableFuture<AppSearchSession> appSearchSessionListenableFuture =
+                PlayServicesStorage.createSearchSessionAsync(
+                        new PlayServicesStorage.SearchContext.Builder(context, dbName).build());
+        mIsGmsAvailable = GmsTestUtil.isGmsAvailable(appSearchSessionListenableFuture);
+
+        // isGmsAvailable returns false when GMSCore or GMSCore AppSearch module are unavailable on
+        // device. In this case we will not run the tests as they are expected to fail as the
+        // service they are calling is unavailable.
+        Assume.assumeTrue(mIsGmsAvailable);
+        return appSearchSessionListenableFuture;
+    }
+
+    @Override
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName,
+            @NonNull ExecutorService unused) throws Exception {
+        // Executor is not required for PlayServicesAppSearch.
+        return createSearchSessionAsync(dbName);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (mIsGmsAvailable) {
+            super.tearDown();
+        }
+    }
+
+    @Override
+    @Test
+    public void testRfc822_unsupportedFeature_throwsException() {
+        // TODO(b/280463238): // TODO(b/280463238): KNOWN_ISSUE will be fixed in next
+        //  play-services-appsearch drop.
+        // expected: tokenizerType is out of range of [0, 1] (too high)
+        // but was : tokenizerType is out of range of [%d, %d] (too high) [0, 1]
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
index 56bf168..5e3e88a 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionPlatformCtsTest.java
@@ -160,63 +160,24 @@
         // b/229770338 was fixed in Android T, this test will fail on S_V2 devices and below.
         assumeTrue(BuildCompat.isAtLeastT());
         super.testEmojiSnippet();
-    }@Override
-    @Test
-    public void testSearchSuggestion() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
     }
 
+    // TODO(b/256022027) Remove this overridden test once the change to setMaxJoinedResultCount
+    // is synced over into framework.
     @Override
     @Test
-    public void testSearchSuggestion_namespaceFilter() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
+    public void testSimpleJoin() throws Exception { }
 
+    // TODO(b/256022027) Remove this overridden test once the change to rename
+    //  `this.childrenScores()` to `this.childrenRankingSignals()` is synced to udc-dev.
     @Override
     @Test
-    public void testSearchSuggestion_documentIdFilter() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
+    public void testQuery_invalidAdvancedRankingWithChildrenRankingSignals() throws Exception { }
 
+    // TODO(b/256022027) Remove this overridden test once the change to rename
+    //  `this.childrenScores()` to `this.childrenRankingSignals()` is synced to udc-dev.
     @Override
     @Test
-    public void testSearchSuggestion_differentPrefix() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
+    public void testQuery_advancedRankingWithJoin() throws Exception { }
 
-    @Override
-    @Test
-    public void testSearchSuggestion_differentRankingStrategy() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
-
-    @Override
-    @Test
-    public void testSearchSuggestion_removeDocument() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
-
-    @Override
-    @Test
-    public void testSearchSuggestion_replacementDocument() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
-
-    @Override
-    @Test
-    public void testSearchSuggestion_ignoreOperators() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
-
-    @Override
-    @Test
-    public void testSearchSuggestion_schemaFilter() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
-
-    @Override
-    @Test
-    public void testSearchSuggestion_twoInstances() throws Exception {
-        // TODO(b/227356108) enable the test when suggestion is ready in platform.
-    }
 }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
index dd71fc5..36cfac4 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionCtsTestBase.java
@@ -84,9 +84,10 @@
     protected GlobalSearchSession mGlobalSearchSession;
 
     protected abstract ListenableFuture<AppSearchSession> createSearchSessionAsync(
-            @NonNull String dbName);
+            @NonNull String dbName) throws Exception;
 
-    protected abstract ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync();
+    protected abstract ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync()
+            throws Exception;
 
     @Before
     public void setUp() throws Exception {
@@ -1837,15 +1838,22 @@
     public void testGlobalQuery_propertyWeights() throws Exception {
         assumeTrue(mDb1.getFeatures().isFeatureSupported(Features.SEARCH_SPEC_PROPERTY_WEIGHTS));
 
-        // Schema registration
+        // RELEVANCE scoring depends on stats for the namespace+type of the scored document, namely
+        // the average document length. This average document length calculation is only updated
+        // when documents are added and when compaction runs. This means that old deleted
+        // documents of the same namespace and type combination *can* affect RELEVANCE scores
+        // through this channel.
+        // To avoid this, we use a unique namespace that will not be shared by any other test
+        // case or any other run of this test.
         mDb1.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
         mDb2.setSchemaAsync(
                 new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build()).get();
 
+        String namespace = "propertyWeightsNamespace" + System.currentTimeMillis();
         // Put two documents in separate databases.
         AppSearchEmail emailDb1 =
-                new AppSearchEmail.Builder("namespace", "id1")
+                new AppSearchEmail.Builder(namespace, "id1")
                         .setCreationTimestampMillis(1000)
                         .setSubject("foo")
                         .build();
@@ -1853,7 +1861,7 @@
                 new PutDocumentsRequest.Builder()
                         .addGenericDocuments(emailDb1).build()));
         AppSearchEmail emailDb2 =
-                new AppSearchEmail.Builder("namespace", "id2")
+                new AppSearchEmail.Builder(namespace, "id2")
                         .setCreationTimestampMillis(1000)
                         .setBody("foo")
                         .build();
@@ -1868,6 +1876,7 @@
                 .setPropertyWeights(AppSearchEmail.SCHEMA_TYPE,
                         ImmutableMap.of("subject",
                                 2.0, "body", 0.5))
+                .addFilterNamespaces(namespace)
                 .build());
         List<SearchResult> globalResults = retrieveAllSearchResults(searchResults);
 
@@ -1889,6 +1898,7 @@
                         .setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
                         .setRankingStrategy(SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE)
                         .setOrder(SearchSpec.ORDER_DESCENDING)
+                        .addFilterNamespaces(namespace)
                         .build());
         List<SearchResult> resultsWithoutWeights =
                 retrieveAllSearchResults(searchResultsWithoutWeights);
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionGmsCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionGmsCtsTest.java
new file mode 100644
index 0000000..40d97ef
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GlobalSearchSessionGmsCtsTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+// @exportToFramework:skipFile()
+
+package androidx.appsearch.cts.app;
+
+import android.content.Context;
+import android.os.Build;
+
+import androidx.annotation.NonNull;
+import androidx.appsearch.app.AppSearchSession;
+import androidx.appsearch.app.GlobalSearchSession;
+import androidx.appsearch.playservicesstorage.PlayServicesStorage;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SdkSuppress;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import org.junit.Assume;
+import org.junit.Ignore;
+
+// TODO(b/237116468): Remove SdkSuppress once AppSearchAttributionSource available for lower API
+//  levels.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
+public class GlobalSearchSessionGmsCtsTest extends GlobalSearchSessionCtsTestBase {
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private boolean mIsGmsAvailable;
+    @Override
+    protected ListenableFuture<AppSearchSession> createSearchSessionAsync(@NonNull String dbName)
+            throws Exception {
+        ListenableFuture<AppSearchSession> searchSessionAsync =
+                PlayServicesStorage.createSearchSessionAsync(
+                        new PlayServicesStorage.SearchContext.Builder(mContext, dbName).build());
+        mIsGmsAvailable = GmsTestUtil.isGmsAvailable(searchSessionAsync);
+
+        // isGmsAvailable returns false when GMSCore or GMSCore AppSearch module are unavailable on
+        // device. In this case we will not run the tests as they are expected to fail as the
+        // service they are calling is unavailable.
+        Assume.assumeTrue(mIsGmsAvailable);
+        return searchSessionAsync;
+    }
+
+    @Override
+    protected ListenableFuture<GlobalSearchSession> createGlobalSearchSessionAsync()
+            throws Exception {
+        ListenableFuture<GlobalSearchSession> globalSearchSessionAsync =
+                PlayServicesStorage.createGlobalSearchSessionAsync(
+                        new PlayServicesStorage.GlobalSearchContext.Builder(mContext).build());
+        mIsGmsAvailable = GmsTestUtil.isGmsAvailable(globalSearchSessionAsync);
+
+        // isGmsAvailable returns false when GMSCore or GMSCore AppSearch module are unavailable on
+        // device. In this case we will not run the tests as they are expected to fail as the
+        // service they are calling is unavailable.
+        Assume.assumeTrue(mIsGmsAvailable);
+        return globalSearchSessionAsync;
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        if (mIsGmsAvailable) {
+            super.tearDown();
+        }
+    }
+
+    @Override
+    @Ignore
+    public void testReportSystemUsage_ForbiddenFromNonSystem() {
+        // TODO(b/208654892) : ReportSystemUsage is not yet needed by any clients of GMSCore
+        //  AppSearch, once there is a requirement by any of the clients this will be added.
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GmsTestUtil.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GmsTestUtil.java
new file mode 100644
index 0000000..0b3b2c5
--- /dev/null
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/GmsTestUtil.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+// @exportToFramework:skipFile()
+
+package androidx.appsearch.cts.app;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.common.api.ApiException;
+import com.google.android.gms.common.api.CommonStatusCodes;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.concurrent.ExecutionException;
+
+/** Util class for GMSCore AppSearch related Cts tests. */
+public final class GmsTestUtil {
+
+    private GmsTestUtil() {}
+
+    /**
+     * This method returns false when GMSCore or GMSCore AppSearch module are unavailable on
+     * device.
+     */
+    public static boolean isGmsAvailable(
+            @NonNull ListenableFuture<?> sessionListenableFuture) throws Exception {
+        try {
+            sessionListenableFuture.get();
+        } catch (ExecutionException exception) {
+            if (exception.getCause() instanceof ApiException) {
+                ApiException apiException = (ApiException) exception.getCause();
+                if (apiException.getStatusCode() == CommonStatusCodes.API_NOT_CONNECTED) {
+                    // GMSCore or GMSCore AppSearch Module not installed on device.
+                    // TODO(b/280864281): Also handle the case when GMSCore and AppSearch
+                    //  module present but AppSearch dynamite module not present.
+                    return false;
+                }
+            }
+
+            throw exception;
+        } catch (InterruptedException exception) {
+            throw exception;
+        }
+        return true;
+    }
+}
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSpecCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSpecCtsTest.java
index 038cd56..371de2d 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSpecCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSpecCtsTest.java
@@ -202,6 +202,52 @@
     }
 
     @Test
+    public void testGetTypePropertyWeightsWithAdvancedRanking() {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                .setRankingStrategy("sum(this.propertyWeights())")
+                .setPropertyWeights("TypeA", ImmutableMap.of("property1", 1.0, "property2", 2.0))
+                .setPropertyWeights("TypeB", ImmutableMap.of("property1", 1.0, "property2"
+                        + ".nested", 2.0))
+                .build();
+
+        Map<String, Map<String, Double>> typePropertyWeightsMap = searchSpec.getPropertyWeights();
+
+        assertThat(typePropertyWeightsMap.keySet())
+                .containsExactly("TypeA", "TypeB");
+        assertThat(typePropertyWeightsMap.get("TypeA")).containsExactly("property1", 1.0,
+                "property2", 2.0);
+        assertThat(typePropertyWeightsMap.get("TypeB")).containsExactly("property1", 1.0,
+                "property2.nested", 2.0);
+    }
+
+    @Test
+    public void testGetTypePropertyWeightPathsWithAdvancedRanking() {
+        SearchSpec searchSpec = new SearchSpec.Builder()
+                .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+                .setRankingStrategy("sum(this.propertyWeights())")
+                .setPropertyWeightPaths("TypeA",
+                        ImmutableMap.of(new PropertyPath("property1"), 1.0,
+                                new PropertyPath("property2"), 2.0))
+                .setPropertyWeightPaths("TypeB",
+                        ImmutableMap.of(new PropertyPath("property1"), 1.0,
+                                new PropertyPath("property2.nested"), 2.0))
+                .build();
+
+        Map<String, Map<PropertyPath, Double>> typePropertyWeightsMap =
+                searchSpec.getPropertyWeightPaths();
+
+        assertThat(typePropertyWeightsMap.keySet())
+                .containsExactly("TypeA", "TypeB");
+        assertThat(typePropertyWeightsMap.get("TypeA"))
+                .containsExactly(new PropertyPath("property1"), 1.0,
+                        new PropertyPath("property2"), 2.0);
+        assertThat(typePropertyWeightsMap.get("TypeB"))
+                .containsExactly(new PropertyPath("property1"), 1.0,
+                        new PropertyPath("property2.nested"), 2.0);
+    }
+
+    @Test
     public void testSetPropertyWeights_nonPositiveWeight() {
         SearchSpec.Builder searchSpecBuilder = new SearchSpec.Builder();
         Map<String, Double> negativePropertyWeight = ImmutableMap.of("property", -1.0);
@@ -479,12 +525,13 @@
         assertThat(e.getMessage()).isEqualTo("Attempting to rank based on joined documents, but"
                 + " no JoinSpec provided");
 
+        JoinSpec joinSpec = new JoinSpec.Builder("childProp")
+                .setAggregationScoringStrategy(
+                        JoinSpec.AGGREGATION_SCORING_SUM_RANKING_SIGNAL)
+                .build();
         e = assertThrows(IllegalStateException.class, () -> new SearchSpec.Builder()
                 .setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
-                .setJoinSpec(new JoinSpec.Builder("childProp")
-                        .setAggregationScoringStrategy(
-                                JoinSpec.AGGREGATION_SCORING_SUM_RANKING_SIGNAL)
-                        .build())
+                .setJoinSpec(joinSpec)
                 .build());
         assertThat(e.getMessage()).isEqualTo("Aggregate scoring strategy has been set in the "
                 + "nested JoinSpec, but ranking strategy is not "
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSuggestionSpecCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSuggestionSpecCtsTest.java
index 5217017..69979c3 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSuggestionSpecCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SearchSuggestionSpecCtsTest.java
@@ -16,14 +16,11 @@
 
 package androidx.appsearch.cts.app;
 
-import static androidx.appsearch.app.AppSearchResult.RESULT_INVALID_ARGUMENT;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
 import androidx.appsearch.app.SearchSuggestionSpec;
-import androidx.appsearch.exceptions.AppSearchException;
 
 import com.google.common.collect.ImmutableList;
 
@@ -68,12 +65,11 @@
 
     @Test
     public void testDocumentIdFilterMustMatchNamespaceFilter() throws Exception {
-        AppSearchException e = assertThrows(AppSearchException.class,
+        IllegalStateException e = assertThrows(IllegalStateException.class,
                 () -> new SearchSuggestionSpec.Builder(/*totalResultCount=*/123)
                         .addFilterNamespaces("namespace1")
                         .addFilterDocumentIds("namespace2", ImmutableList.of("doc1"))
                         .build());
-        assertThat(e.getResultCode()).isEqualTo(RESULT_INVALID_ARGUMENT);
         assertThat(e).hasMessageThat().contains("The namespace: namespace2 exists in the "
                 + "document id filter but doesn't exist in the namespace filter.");
     }
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
index 004a07e..0033e71 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/SetSchemaRequestCtsTest.java
@@ -26,10 +26,12 @@
 import androidx.annotation.NonNull;
 import androidx.appsearch.annotation.Document;
 import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactoryRegistry;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.app.Migrator;
 import androidx.appsearch.app.PackageIdentifier;
 import androidx.appsearch.app.SetSchemaRequest;
+import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.testutil.AppSearchEmail;
 import androidx.collection.ArrayMap;
 
@@ -374,7 +376,7 @@
     }
 
 
-// @exportToFramework:startStrip()
+    // @exportToFramework:startStrip()
     @Document
     static class Card {
         @Document.Namespace
@@ -473,7 +475,7 @@
                 .addRequiredPermissionsForDocumentClassVisibility(Card.class,
                         ImmutableSet.of(SetSchemaRequest.READ_SMS, SetSchemaRequest.READ_CALENDAR))
                 .addRequiredPermissionsForDocumentClassVisibility(Card.class,
-                ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA));
+                        ImmutableSet.of(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA));
         request = setSchemaRequestBuilder.build();
 
         assertThat(request.getRequiredPermissionsForSchemaTypeVisibility())
@@ -833,4 +835,85 @@
         assertThat(((AppSearchSchema.StringPropertyConfig) properties.get(0)).getTokenizerType())
                 .isEqualTo(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_RFC822);
     }
+
+    // @exportToFramework:startStrip()
+    @Document
+    static class Outer {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Middle mMiddle;
+    }
+
+    @Document
+    static class Middle {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Inner mInner;
+    }
+
+    @Document
+    static class Inner {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.StringProperty String mContents;
+    }
+
+    @Test
+    public void testNestedSchemas() throws AppSearchException {
+        SetSchemaRequest request = new SetSchemaRequest.Builder().addDocumentClasses(Outer.class)
+                .setForceOverride(true).build();
+        DocumentClassFactoryRegistry registry = DocumentClassFactoryRegistry.getInstance();
+
+        Set<AppSearchSchema> schemas = request.getSchemas();
+        assertThat(schemas).hasSize(3);
+        assertThat(schemas).contains(registry.getOrCreateFactory(Outer.class).getSchema());
+        assertThat(schemas).contains(registry.getOrCreateFactory(Middle.class).getSchema());
+        assertThat(schemas).contains(registry.getOrCreateFactory(Inner.class).getSchema());
+    }
+
+    @Document
+    static class Parent {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Person mPerson;
+        @Document.DocumentProperty Organization mOrganization;
+    }
+
+    @Document
+    static class Person {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Common mCommon;
+    }
+
+    @Document
+    static class Organization {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.DocumentProperty Common mCommon;
+    }
+
+    @Document
+    static class Common {
+        @Document.Id String mId;
+        @Document.Namespace String mNamespace;
+        @Document.StringProperty String mContents;
+    }
+
+
+    @Test
+    public void testNestedSchemasMultiplePaths() throws AppSearchException {
+        SetSchemaRequest request = new SetSchemaRequest.Builder().addDocumentClasses(Parent.class)
+                .setForceOverride(true).build();
+        DocumentClassFactoryRegistry registry = DocumentClassFactoryRegistry.getInstance();
+
+        Set<AppSearchSchema> schemas = request.getSchemas();
+        assertThat(schemas).hasSize(4);
+        assertThat(schemas).contains(registry.getOrCreateFactory(Common.class).getSchema());
+        assertThat(schemas).contains(registry.getOrCreateFactory(Organization.class).getSchema());
+        assertThat(schemas).contains(registry.getOrCreateFactory(Person.class).getSchema());
+        assertThat(schemas).contains(registry.getOrCreateFactory(Parent.class).getSchema());
+    }
+
+// @exportToFramework:endStrip()
 }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/CanIgnoreReturnValue.java b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/CanIgnoreReturnValue.java
new file mode 100644
index 0000000..6f9f61e
--- /dev/null
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/CanIgnoreReturnValue.java
@@ -0,0 +1,39 @@
+/*
+ * 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.appsearch.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import androidx.annotation.RestrictTo;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that the return value of the annotated API is ignorable.
+ *
+ * @exportToFramework:hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+@Documented
+@Target({METHOD, CONSTRUCTOR, TYPE})
+@Retention(CLASS)
+public @interface CanIgnoreReturnValue {}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
index 04989eb..893a197 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/annotation/Document.java
@@ -215,6 +215,28 @@
                 default AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE;
 
         /**
+         * Configures how a property should be processed so that the document can be joined.
+         *
+         * <p>Properties configured with
+         * {@link AppSearchSchema.StringPropertyConfig#JOINABLE_VALUE_TYPE_QUALIFIED_ID} enable
+         * the documents to be joined with other documents that have the same qualified ID as the
+         * value of this field. (A qualified ID is a compact representation of the tuple <package
+         * name, database name, namespace, document ID> that uniquely identifies a document
+         * indexed in the AppSearch storage backend.) This property name can be specified as the
+         * child property expression in {@link androidx.appsearch.app.JoinSpec.Builder(String)} for
+         * join operations.
+         *
+         * <p>This attribute doesn't apply to properties of a repeated type (e.g., a list).
+         *
+         * <p>If not specified, defaults to
+         * {@link AppSearchSchema.StringPropertyConfig#JOINABLE_VALUE_TYPE_NONE}, which means the
+         * property can not be used in a child property expression to configure a
+         * {@link androidx.appsearch.app.JoinSpec.Builder(String)}.
+         */
+        @AppSearchSchema.StringPropertyConfig.JoinableValueType int joinableValueType()
+                default AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE;
+
+        /**
          * Configures whether this property must be specified for the document to be valid.
          *
          * <p>This attribute does not apply to properties of a repeated type (e.g. a list).
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
index 3cdf6ce..8263467 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchBatchResult.java
@@ -17,6 +17,8 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArrayMap;
 import androidx.core.util.Preconditions;
 
@@ -99,8 +101,9 @@
 
     /**
      * Asserts that this {@link AppSearchBatchResult} has no failures.
-     * @hide
+     * @exportToFramework:hide
      */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     public void checkSuccess() {
         if (!isSuccess()) {
             throw new IllegalStateException("AppSearchBatchResult has failures: " + this);
@@ -138,6 +141,7 @@
          * @param value An optional value to associate with the successful result of the operation
          *              being performed.
          */
+        @CanIgnoreReturnValue
         @SuppressWarnings("MissingGetterMatchingBuilder")  // See getSuccesses
         @NonNull
         public Builder<KeyType, ValueType> setSuccess(
@@ -161,6 +165,7 @@
          *                     {@link AppSearchResult#getResultCode}.
          * @param errorMessage An optional string describing the reason or nature of the failure.
          */
+        @CanIgnoreReturnValue
         @SuppressWarnings("MissingGetterMatchingBuilder")  // See getFailures
         @NonNull
         public Builder<KeyType, ValueType> setFailure(
@@ -181,6 +186,7 @@
          *               identifier from the input like an ID or name.
          * @param result The result to associate with the key.
          */
+        @CanIgnoreReturnValue
         @SuppressWarnings("MissingGetterMatchingBuilder")  // See getAll
         @NonNull
         public Builder<KeyType, ValueType> setResult(
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchResult.java
index 31b0a88..a88bfe1 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchResult.java
@@ -40,7 +40,7 @@
 
     /**
      * Result codes from {@link AppSearchSession} methods.
-     * @hide
+     * @exportToFramework:hide
      */
     @IntDef(value = {
             RESULT_OK,
@@ -52,7 +52,9 @@
             RESULT_NOT_FOUND,
             RESULT_INVALID_SCHEMA,
             RESULT_SECURITY_ERROR,
+            RESULT_DENIED,
     })
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @Retention(RetentionPolicy.SOURCE)
     public @interface ResultCode {}
 
@@ -95,6 +97,14 @@
     /** The caller requested an operation it does not have privileges for. */
     public static final int RESULT_SECURITY_ERROR = 8;
 
+    /**
+     * The requested operation is denied for the caller. This error is logged and returned for
+     * denylist rejections.
+     * <!--@exportToFramework:hide-->
+     */
+    // TODO(b/279047435): unhide this the next time we can make API changes
+    public static final int RESULT_DENIED = 9;
+
     private final @ResultCode int mResultCode;
     @Nullable private final ValueType mResultValue;
     @Nullable private final String mErrorMessage;
@@ -114,7 +124,8 @@
     }
 
     /** Returns one of the {@code RESULT} constants defined in {@link AppSearchResult}. */
-    public @ResultCode int getResultCode() {
+    @ResultCode
+    public int getResultCode() {
         return mResultCode;
     }
 
@@ -202,7 +213,7 @@
     /**
      * Creates a new failed {@link AppSearchResult} by a AppSearchResult in another type.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -214,7 +225,7 @@
                 otherFailedResult.getResultCode(), otherFailedResult.getErrorMessage());
     }
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
     public static <ValueType> AppSearchResult<ValueType> throwableToFailedResult(
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
index 8a05b92..f0d6df8 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSchema.java
@@ -23,6 +23,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.exceptions.IllegalSchemaException;
 import androidx.appsearch.util.BundleUtil;
 import androidx.appsearch.util.IndentingStringBuilder;
@@ -53,7 +54,7 @@
 
     private final Bundle mBundle;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public AppSearchSchema(@NonNull Bundle bundle) {
         Preconditions.checkNotNull(bundle);
@@ -62,7 +63,7 @@
 
     /**
      * Returns the {@link Bundle} populated by this builder.
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -112,7 +113,7 @@
         builder.append("}");
     }
 
-    /** Returns the name of this schema type, e.g. Email. */
+    /** Returns the name of this schema type, such as Email. */
     @NonNull
     public String getSchemaType() {
         return mBundle.getString(SCHEMA_TYPE_FIELD, "");
@@ -172,6 +173,7 @@
         }
 
         /** Adds a property to the given type. */
+        @CanIgnoreReturnValue
         @NonNull
         public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) {
             Preconditions.checkNotNull(propertyConfig);
@@ -215,10 +217,12 @@
 
         /**
          * Physical data-types of the contents of the property.
-         * @hide
+         *
+         * <p>NOTE: The integer values of these constants must match the proto enum constants in
+         * com.google.android.icing.proto.PropertyConfigProto.DataType.Code.
+         *
          */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.DataType.Code.
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef(value = {
                 DATA_TYPE_STRING,
                 DATA_TYPE_LONG,
@@ -230,42 +234,46 @@
         @Retention(RetentionPolicy.SOURCE)
         public @interface DataType {}
 
-        /** @hide */
+        /** @exportToFramework:hide */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_STRING = 1;
 
-        /** @hide */
+        /** @exportToFramework:hide */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_LONG = 2;
 
-        /** @hide */
+        /** @exportToFramework:hide */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_DOUBLE = 3;
 
-        /** @hide */
+        /** @exportToFramework:hide */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_BOOLEAN = 4;
 
         /**
          * Unstructured BLOB.
-         * @hide
+         * @exportToFramework:hide
          */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_BYTES = 5;
 
         /**
          * Indicates that the property is itself a {@link GenericDocument}, making it part of a
          * hierarchical schema. Any property using this DataType MUST have a valid
          * {@link PropertyConfig#getSchemaType}.
-         * @hide
+         * @exportToFramework:hide
          */
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public static final int DATA_TYPE_DOCUMENT = 6;
 
         /**
          * The cardinality of the property (whether it is required, optional or repeated).
-         * @hide
+         *
+         * <p>NOTE: The integer values of these constants must match the proto enum constants in
+         * com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code.
+         *
          */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code.
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef(value = {
                 CARDINALITY_REPEATED,
                 CARDINALITY_OPTIONAL,
@@ -371,18 +379,21 @@
         }
 
         /**
-         * Returns the type of data the property contains (e.g. string, int, bytes, etc).
+         * Returns the type of data the property contains (such as string, int, bytes, etc).
          *
-         * @hide
+         * @exportToFramework:hide
          */
-        public @DataType int getDataType() {
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @DataType
+        public int getDataType() {
             return mBundle.getInt(DATA_TYPE_FIELD, -1);
         }
 
         /**
          * Returns the cardinality of the property (whether it is optional, required or repeated).
          */
-        public @Cardinality int getCardinality() {
+        @Cardinality
+        public int getCardinality() {
             return mBundle.getInt(CARDINALITY_FIELD, CARDINALITY_OPTIONAL);
         }
 
@@ -414,7 +425,7 @@
          *
          * @throws IllegalArgumentException if the bundle does no contain a recognized
          * value in its {@code DATA_TYPE_FIELD}.
-         * @hide
+         * @exportToFramework:hide
          */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         @NonNull
@@ -446,11 +457,13 @@
         private static final String INDEXING_TYPE_FIELD = "indexingType";
         private static final String TOKENIZER_TYPE_FIELD = "tokenizerType";
         private static final String JOINABLE_VALUE_TYPE_FIELD = "joinableValueType";
+        private static final String DELETION_PROPAGATION_FIELD = "deletionPropagation";
 
         /**
          * Encapsulates the configurations on how AppSearch should query/index these terms.
-         * @hide
+         * @exportToFramework:hide
          */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef(value = {
                 INDEXING_TYPE_NONE,
                 INDEXING_TYPE_EXACT_TERMS,
@@ -466,7 +479,7 @@
          * Content in this property should only be returned for queries matching the exact tokens
          * appearing in this property.
          *
-         * <p>Ex. A property with "fool" should NOT match a query for "foo".
+         * <p>For example, a property with "fool" should NOT match a query for "foo".
          */
         public static final int INDEXING_TYPE_EXACT_TERMS = 1;
 
@@ -474,16 +487,18 @@
          * Content in this property should be returned for queries that are either exact matches or
          * query matches of the tokens appearing in this property.
          *
-         * <p>Ex. A property with "fool" <b>should</b> match a query for "foo".
+         * <p>For example, a property with "fool" <b>should</b> match a query for "foo".
          */
         public static final int INDEXING_TYPE_PREFIXES = 2;
 
         /**
          * Configures how tokens should be extracted from this property.
-         * @hide
+         *
+         * <p>NOTE: The integer values of these constants must match the proto enum constants in
+         * com.google.android.icing.proto.IndexingConfig.TokenizerType.Code.
+         *
          */
-        // NOTE: The integer values of these constants must match the proto enum constants in
-        // com.google.android.icing.proto.IndexingConfig.TokenizerType.Code.
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @IntDef(value = {
                 TOKENIZER_TYPE_NONE,
                 TOKENIZER_TYPE_PLAIN,
@@ -506,8 +521,8 @@
          * this property based on word breaks. Segments of whitespace and punctuation are not
          * considered tokens.
          *
-         * <p>Ex. A property with "foo bar. baz." will produce tokens for "foo", "bar" and "baz".
-         * The segments " " and "." will not be considered tokens.
+         * <p>For example, a property with "foo bar. baz." will produce tokens for "foo", "bar" and
+         * "baz". The segments " " and "." will not be considered tokens.
          *
          * <p>It is only valid for tokenizer_type to be 'PLAIN' if {@link #getIndexingType} is
          * {@link #INDEXING_TYPE_EXACT_TERMS} or {@link #INDEXING_TYPE_PREFIXES}.
@@ -519,7 +534,7 @@
          * values that are tokenized using this type. Therefore, the output token is equivalent
          * to the raw string value.
          *
-         * <p>Ex. A property with "Hello, world!" will produce the token "Hello, world!",
+         * <p>For example, a property with "Hello, world!" will produce the token "Hello, world!",
          * preserving punctuation and capitalization, and not creating separate tokens between the
          * space.
          *
@@ -537,8 +552,8 @@
          * Tokenization for emails. This value indicates that tokens should be extracted from
          * this property based on email structure.
          *
-         * <p>Ex. A property with "alex.sav@google.com" will produce tokens for "alex", "sav",
-         * "alex.sav", "google", "com", and "alexsav@google.com"
+         * <p>For example, a property with "alex.sav@google.com" will produce tokens for "alex",
+         * "sav", "alex.sav", "google", "com", and "alexsav@google.com"
          *
          * <p>It is only valid for tokenizer_type to be 'RFC822' if {@link #getIndexingType} is
          * {@link #INDEXING_TYPE_EXACT_TERMS} or {@link #INDEXING_TYPE_PREFIXES}.
@@ -554,7 +569,7 @@
          * The joinable value type of the property. By setting the appropriate joinable value type
          * for a property, the client can use the property for joining documents from other schema
          * types using Search API (see {@link JoinSpec}).
-         * @hide
+         * @exportToFramework:hide
          */
         // NOTE: The integer values of these constants must match the proto enum constants in
         // com.google.android.icing.proto.JoinableConfig.ValueType.Code.
@@ -562,7 +577,7 @@
                 JOINABLE_VALUE_TYPE_NONE,
                 JOINABLE_VALUE_TYPE_QUALIFIED_ID,
         })
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @Retention(RetentionPolicy.SOURCE)
         public @interface JoinableValueType {}
 
@@ -592,29 +607,44 @@
         }
 
         /** Returns how the property is indexed. */
-        public @IndexingType int getIndexingType() {
+        @IndexingType
+        public int getIndexingType() {
             return mBundle.getInt(INDEXING_TYPE_FIELD);
         }
 
         /** Returns how this property is tokenized (split into words). */
-        public @TokenizerType int getTokenizerType() {
+        @TokenizerType
+        public int getTokenizerType() {
             return mBundle.getInt(TOKENIZER_TYPE_FIELD);
         }
 
         /**
          * Returns how this property is going to be used to join documents from other schema types.
          */
-        public @JoinableValueType int getJoinableValueType() {
+        @JoinableValueType
+        public int getJoinableValueType() {
             return mBundle.getInt(JOINABLE_VALUE_TYPE_FIELD, JOINABLE_VALUE_TYPE_NONE);
         }
 
+        /**
+         * Returns whether or not documents in this schema should be deleted when the document
+         * referenced by this field is deleted.
+         *
+         * @see JoinSpec
+         * @<!--@exportToFramework:ifJetpack()--><!--@exportToFramework:else()hide-->
+         */
+        public boolean getDeletionPropagation() {
+            return mBundle.getBoolean(DELETION_PROPAGATION_FIELD, false);
+        }
+
         /** Builder for {@link StringPropertyConfig}. */
         public static final class Builder {
             private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-            private @IndexingType int mIndexingType = INDEXING_TYPE_NONE;
-            private @TokenizerType int mTokenizerType = TOKENIZER_TYPE_NONE;
-            private @JoinableValueType int mJoinableValueType = JOINABLE_VALUE_TYPE_NONE;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
+            @IndexingType private int mIndexingType = INDEXING_TYPE_NONE;
+            @TokenizerType private int mTokenizerType = TOKENIZER_TYPE_NONE;
+            @JoinableValueType private int mJoinableValueType = JOINABLE_VALUE_TYPE_NONE;
+            private boolean mDeletionPropagation = false;
 
             /** Creates a new {@link StringPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
@@ -622,11 +652,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public StringPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -643,6 +674,7 @@
              * {@link StringPropertyConfig#INDEXING_TYPE_NONE}, so that it cannot be matched by
              * queries.
              */
+            @CanIgnoreReturnValue
             @NonNull
             public StringPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
                 Preconditions.checkArgumentInRange(
@@ -658,10 +690,11 @@
              * {@link StringPropertyConfig#TOKENIZER_TYPE_NONE}, so that it is not tokenized.
              *
              * <p>This method must be called with a value other than
-             * {@link StringPropertyConfig#TOKENIZER_TYPE_NONE} if the property is indexed (i.e.
+             * {@link StringPropertyConfig#TOKENIZER_TYPE_NONE} if the property is indexed (that is,
              * if {@link #setIndexingType} has been called with a value other than
              * {@link StringPropertyConfig#INDEXING_TYPE_NONE}).
              */
+            @CanIgnoreReturnValue
             @NonNull
             public StringPropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) {
                 Preconditions.checkArgumentInRange(
@@ -675,7 +708,10 @@
              *
              * <p>If this method is not called, the default joinable value type is
              * {@link StringPropertyConfig#JOINABLE_VALUE_TYPE_NONE}, so that it is not joinable.
+             *
+             * <p>At most, 64 properties can be set as joinable per schema.
              */
+            @CanIgnoreReturnValue
             @NonNull
             public StringPropertyConfig.Builder setJoinableValueType(
                     @JoinableValueType int joinableValueType) {
@@ -689,6 +725,25 @@
             }
 
             /**
+             * Configures whether or not documents in this schema will be removed when the document
+             * referred to by this property is deleted.
+             *
+             * <p> Requires that a joinable value type is set.
+             * @<!--@exportToFramework:ifJetpack()--><!--@exportToFramework:else()hide-->
+             */
+            @SuppressWarnings("MissingGetterMatchingBuilder")  // getDeletionPropagation
+            @NonNull
+            // @exportToFramework:startStrip()
+            @RequiresFeature(
+                    enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+                    name = Features.SCHEMA_SET_DELETION_PROPAGATION)
+            // @exportToFramework:endStrip()
+            public Builder setDeletionPropagation(boolean deletionPropagation) {
+                mDeletionPropagation = deletionPropagation;
+                return this;
+            }
+
+            /**
              * Constructs a new {@link StringPropertyConfig} from the contents of this builder.
              */
             @NonNull
@@ -704,6 +759,9 @@
                 if (mJoinableValueType == JOINABLE_VALUE_TYPE_QUALIFIED_ID) {
                     Preconditions.checkState(mCardinality != CARDINALITY_REPEATED, "Cannot set "
                             + "JOINABLE_VALUE_TYPE_QUALIFIED_ID with CARDINALITY_REPEATED.");
+                } else {
+                    Preconditions.checkState(!mDeletionPropagation, "Cannot set deletion "
+                            + "propagation without setting a joinable value type");
                 }
                 Bundle bundle = new Bundle();
                 bundle.putString(NAME_FIELD, mPropertyName);
@@ -712,6 +770,7 @@
                 bundle.putInt(INDEXING_TYPE_FIELD, mIndexingType);
                 bundle.putInt(TOKENIZER_TYPE_FIELD, mTokenizerType);
                 bundle.putInt(JOINABLE_VALUE_TYPE_FIELD, mJoinableValueType);
+                bundle.putBoolean(DELETION_PROPAGATION_FIELD, mDeletionPropagation);
                 return new StringPropertyConfig(bundle);
             }
         }
@@ -776,13 +835,13 @@
         /**
          * Encapsulates the configurations on how AppSearch should query/index these 64-bit
          * integers.
-         * @hide
+         * @exportToFramework:hide
          */
         @IntDef(value = {
                 INDEXING_TYPE_NONE,
                 INDEXING_TYPE_RANGE
         })
-        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
         @Retention(RetentionPolicy.SOURCE)
         public @interface IndexingType {}
 
@@ -793,7 +852,7 @@
          * Content in this property will be indexed and can be fetched via numeric search range
          * query.
          *
-         * <p>Ex. A property with 1024 should match numeric search range query [0, 2000].
+         * <p>For example, a property with 1024 should match numeric search range query [0, 2000].
          */
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -807,15 +866,16 @@
         }
 
         /** Returns how the property is indexed. */
-        public @IndexingType int getIndexingType() {
+        @IndexingType
+        public int getIndexingType() {
             return mBundle.getInt(INDEXING_TYPE_FIELD, INDEXING_TYPE_NONE);
         }
 
         /** Builder for {@link LongPropertyConfig}. */
         public static final class Builder {
             private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
-            private @IndexingType int mIndexingType = INDEXING_TYPE_NONE;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
+            @IndexingType private int mIndexingType = INDEXING_TYPE_NONE;
 
             /** Creates a new {@link LongPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
@@ -823,11 +883,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public LongPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -844,6 +905,7 @@
              * {@link LongPropertyConfig#INDEXING_TYPE_NONE}, so that it will not be indexed
              * and cannot be matched by queries.
              */
+            @CanIgnoreReturnValue
             @NonNull
             public LongPropertyConfig.Builder setIndexingType(@IndexingType int indexingType) {
                 Preconditions.checkArgumentInRange(
@@ -895,7 +957,7 @@
         /** Builder for {@link DoublePropertyConfig}. */
         public static final class Builder {
             private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link DoublePropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
@@ -903,11 +965,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public DoublePropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -938,7 +1001,7 @@
         /** Builder for {@link BooleanPropertyConfig}. */
         public static final class Builder {
             private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link BooleanPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
@@ -946,11 +1009,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public BooleanPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -981,7 +1045,7 @@
         /** Builder for {@link BytesPropertyConfig}. */
         public static final class Builder {
             private final String mPropertyName;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
 
             /** Creates a new {@link BytesPropertyConfig.Builder}. */
             public Builder(@NonNull String propertyName) {
@@ -989,11 +1053,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public BytesPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -1047,7 +1112,7 @@
         public static final class Builder {
             private final String mPropertyName;
             private final String mSchemaType;
-            private @Cardinality int mCardinality = CARDINALITY_OPTIONAL;
+            @Cardinality private int mCardinality = CARDINALITY_OPTIONAL;
             private boolean mShouldIndexNestedProperties = false;
 
             /**
@@ -1066,11 +1131,12 @@
             }
 
             /**
-             * The cardinality of the property (whether it is optional, required or repeated).
+             * Sets the cardinality of the property (whether it is optional, required or repeated).
              *
              * <p>If this method is not called, the default cardinality is
              * {@link PropertyConfig#CARDINALITY_OPTIONAL}.
              */
+            @CanIgnoreReturnValue
             @SuppressWarnings("MissingGetterMatchingBuilder")  // getter defined in superclass
             @NonNull
             public DocumentPropertyConfig.Builder setCardinality(@Cardinality int cardinality) {
@@ -1087,6 +1153,7 @@
              * <p>If false, the nested document's properties are not indexed regardless of its own
              * schema.
              */
+            @CanIgnoreReturnValue
             @NonNull
             public DocumentPropertyConfig.Builder setShouldIndexNestedProperties(
                     boolean indexNestedProperties) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
index 16098ebc..05d1815 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/AppSearchSession.java
@@ -19,7 +19,6 @@
 import android.annotation.SuppressLint;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -162,6 +161,57 @@
      *     the "subject" property.
      * </ul>
      *
+     * <p>The above description covers the query operators that are supported on all versions of
+     * AppSearch. Additional operators and their required features are described below.
+     *
+     * <p>{@link Features#LIST_FILTER_QUERY_LANGUAGE}: This feature covers the expansion of the
+     * query language to conform to the definition of the list filters language (https://aip
+     * .dev/160). This includes:
+     * <ul>
+     *     <li>addition of explicit 'AND' and 'NOT' operators</li>
+     *     <li>property restricts are allowed with groupings (ex. "prop:(a OR b)")</li>
+     *     <li>addition of custom functions to control matching</li>
+     * </ul>
+     *
+     * <p>The newly added custom functions covered by this feature are:
+     * <ul>
+     *     <li>createList(String...)</li>
+     *     <li>search(String, List<String>)</li>
+     *     <li>propertyDefined(String)</li>
+     * </ul>
+     *
+     * <p>createList takes a variable number of strings and returns a list of strings.
+     * It is for use with search.
+     *
+     * <p>search takes a query string that will be parsed according to the supported
+     * query language and an optional list of strings that specify the properties to be
+     * restricted to. This exists as a convenience for multiple property restricts. So,
+     * for example, the query `(subject:foo OR body:foo) (subject:bar OR body:bar)`
+     * could be rewritten as `search("foo bar", createList("subject", "bar"))`.
+     *
+     * <p>propertyDefined takes a string specifying the property of interest and matches all
+     * documents of any type that defines the specified property
+     * (ex. `propertyDefined("sender.name")`). Note that propertyDefined will match so long as
+     * the document's type defines the specified property. It does NOT require that the document
+     * actually hold any values for this property.
+     *
+     * <p>{@link Features#NUMERIC_SEARCH}: This feature covers numeric search expressions. In the
+     * query language, the values of properties that have
+     * {@link AppSearchSchema.LongPropertyConfig#INDEXING_TYPE_RANGE} set can be matched with a
+     * numeric search expression (the property, a supported comparator and an integer value).
+     * Supported comparators are <, <=, ==, >= and >.
+     *
+     * <p>Ex. `price < 10` will match all documents that has a numeric value in its price
+     * property that is less than 10.
+     *
+     * <p>{@link Features#VERBATIM_SEARCH}: This feature covers the verbatim string operator
+     * (quotation marks).
+     *
+     * <p>Ex. `"foo/bar" OR baz` will ensure that 'foo/bar' is treated as a single 'verbatim' token.
+     *
+     * <p>The availability of each of these features can be checked by calling
+     * {@link Features#isFeatureSupported} with the desired feature.
+     *
      * <p>Additional search specifications, such as filtering by {@link AppSearchSchema} type or
      * adding projection, can be set by calling the corresponding {@link SearchSpec.Builder} setter.
      *
@@ -208,17 +258,14 @@
      *
      * <p>Search suggestions with the multiple term {@code suggestionQueryExpression} "org t", the
      * suggested result will be "org term1" - The last token is completed by the suggested
-     * String, even if it won't return any result.
+     * String.
      *
-     * <p>Search suggestions with operators. All operators will be considered as a normal term.
-     * <ul>
-     *     <li>Search suggestions with the {@code suggestionQueryExpression} "term1 OR", the
-     *     suggested result is "term1 org".
-     *     <li>Search suggestions with the {@code suggestionQueryExpression} "term3 OR t", the
-     *     suggested result is "term3 OR term1".
-     *     <li>Search suggestions with the {@code suggestionQueryExpression} "content:t", the
-     *     suggested result is empty. It cannot find a document that contains the term "content:t".
-     * </ul>
+     * <p>Operators in {@link #search} are supported.
+     * <p><b>NOTE:</b> Exclusion and Grouped Terms in the last term is not supported.
+     * <p>example: "apple -f": This Api will throw an
+     * {@link androidx.appsearch.exceptions.AppSearchException} with
+     * {@link AppSearchResult#RESULT_INVALID_ARGUMENT}.
+     * <p>example: "apple (f)": This Api will return an empty results.
      *
      * <p>Invalid example: All these input {@code suggestionQueryExpression} don't have a valid
      * last token, AppSearch will return an empty result list.
@@ -229,10 +276,6 @@
      *     <li>"f    " - Ending in trailing space.
      * </ul>
      *
-     * <p>Property restrict query like "subject:f" is not supported in suggestion API. It will
-     * return suggested String starting with "f" even if the term appears other than "subject"
-     * property.
-     *
      * @param suggestionQueryExpression the non empty query string to search suggestions
      * @param searchSuggestionSpec      spec for setting document filters
      * @return The pending result of performing this operation which resolves to a List of
@@ -241,15 +284,8 @@
      *         in {@link #search}.
      *
      * @see #search(String, SearchSpec)
-     * <!--@exportToFramework:ifJetpack()-->@hide<!--@exportToFramework:else()-->
      */
-    //TODO(b/227356108) Change the comment in this API after fix following issues.
-    // 1: support property restrict tokenization, Example: [subject:car] will return ["cart",
-    // "carburetor"] if AppSearch has documents contain those terms.
-    // 2: support multiple terms, Example: [bar f] will return suggestions [bar foo] that could
-    // be used to retrieve documents that contain both terms "bar" and "foo".
     @NonNull
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     ListenableFuture<List<SearchSuggestionResult>> searchSuggestionAsync(
             @NonNull String suggestionQueryExpression,
             @NonNull SearchSuggestionSpec searchSuggestionSpec);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactory.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactory.java
index bd03221..fd5987e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactory.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactory.java
@@ -19,6 +19,8 @@
 import androidx.annotation.NonNull;
 import androidx.appsearch.exceptions.AppSearchException;
 
+import java.util.List;
+
 /**
  * An interface for factories which can convert between instances of classes annotated with
  * \@{@link androidx.appsearch.annotation.Document} and instances of {@link GenericDocument}.
@@ -39,6 +41,13 @@
     AppSearchSchema getSchema() throws AppSearchException;
 
     /**
+     * Returns dependent document classes used in this document class. This is useful as we can set
+     * dependent schemas without requiring clients to explicitly set all dependent schemas.
+     */
+    @NonNull
+    List<Class<?>> getNestedDocumentClasses() throws AppSearchException;
+
+    /**
      * Converts an instance of the class annotated with
      * \@{@link androidx.appsearch.annotation.Document} into a
      * {@link androidx.appsearch.app.GenericDocument}.
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactoryRegistry.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactoryRegistry.java
index 6ce9a9b6..a057998 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactoryRegistry.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/DocumentClassFactoryRegistry.java
@@ -27,7 +27,7 @@
 
 /**
  * A registry which maintains instances of {@link DocumentClassFactory}.
- * @hide
+ * @exportToFramework:hide
  */
 @AnyThread
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/FeatureConstants.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/FeatureConstants.java
new file mode 100644
index 0000000..9fb1df0
--- /dev/null
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/FeatureConstants.java
@@ -0,0 +1,39 @@
+/*
+ * 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.appsearch.app;
+
+import androidx.annotation.RestrictTo;
+
+/**
+ * A class that encapsulates all feature constants that are accessible in AppSearch framework.
+ *
+ * <p>All fields in this class is referring in {@link Features}. If you add/remove any field in this
+ * class, you should also change {@link Features}.
+ * @see Features
+ * @exportToFramework:hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public interface FeatureConstants {
+    /** Feature constants for {@link Features#NUMERIC_SEARCH}. */
+    String NUMERIC_SEARCH = "NUMERIC_SEARCH";
+
+    /**  Feature constants for {@link Features#VERBATIM_SEARCH}.   */
+    String VERBATIM_SEARCH = "VERBATIM_SEARCH";
+
+    /**  Feature constants for {@link Features#LIST_FILTER_QUERY_LANGUAGE}.  */
+    String LIST_FILTER_QUERY_LANGUAGE = "LIST_FILTER_QUERY_LANGUAGE";
+}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
index 4a4af6c..a555b2d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/Features.java
@@ -16,6 +16,7 @@
 package androidx.appsearch.app;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
 
 /**
  * A class that encapsulates all features that are only supported in certain cases (e.g. only on
@@ -26,6 +27,8 @@
  * the feature will be available forever on that AppSearch storage implementation, at that
  * Android API level, on that device.
  */
+
+// @exportToFramework:copyToPath(testing/testutils/src/android/app/appsearch/testutil/external/Features.java)
 public interface Features {
 
     /**
@@ -77,8 +80,11 @@
      * Feature for {@link #isFeatureSupported(String)}. This feature covers
      * {@link AppSearchSchema.LongPropertyConfig#INDEXING_TYPE_RANGE} and all other numeric search
      * features.
+     *
+     * <p>For details on the numeric search expressions in the query language, see
+     * {@link AppSearchSession#search}.
      */
-    String NUMERIC_SEARCH = "NUMERIC_SEARCH";
+    String NUMERIC_SEARCH = FeatureConstants.NUMERIC_SEARCH;
 
     /**
      * Feature for {@link #isFeatureSupported(String)}. This feature covers
@@ -86,36 +92,24 @@
      * verbatim search features within the query language that allows clients to search using the
      * verbatim string operator.
      *
-     * <p>Ex. '"foo/bar" OR baz' will ensure that 'foo/bar' is treated as a single 'verbatim' token.
+     * <p>For details on the verbatim string operator, see {@link AppSearchSession#search}.
      */
-    String VERBATIM_SEARCH = "VERBATIM_SEARCH";
+    String VERBATIM_SEARCH = FeatureConstants.VERBATIM_SEARCH;
 
     /**
-     * Feature for {@link #isFeatureSupported(String)}. This feature covers the
-     * expansion of the query language to conform to the definition of the list
-     * filters language (https://aip.dev/160). This includes:
-     * <ul>
-     * <li>addition of explicit 'AND' and 'NOT' operators</li>
-     * <li>property restricts are allowed with grouping (ex. "prop:(a OR b)")</li>
-     * <li>addition of custom functions to control matching</li>
-     * </ul>
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers the expansion of the
+     * query language to conform to the definition of the list filters language
+     * (https://aip.dev/160).
      *
-     * <p>The newly added custom functions covered by this feature are:
-     * <ul>
-     * <li>createList(String...)</li>
-     * <li>termSearch(String, List<String>)</li>
-     * </ul>
-     *
-     * <p>createList takes a variable number of strings and returns a list of strings.
-     * It is for use with termSearch.
-     *
-     * <p>termSearch takes a query string that will be parsed according to the supported
-     * query language and an optional list of strings that specify the properties to be
-     * restricted to. This exists as a convenience for multiple property restricts. So,
-     * for example, the query "(subject:foo OR body:foo) (subject:bar OR body:bar)"
-     * could be rewritten as "termSearch(\"foo bar\", createList(\"subject\", \"bar\"))"
+     * <p>For more details, see {@link AppSearchSession#search}.
      */
-    String LIST_FILTER_QUERY_LANGUAGE = "LIST_FILTER_QUERY_LANGUAGE";
+    String LIST_FILTER_QUERY_LANGUAGE = FeatureConstants.LIST_FILTER_QUERY_LANGUAGE;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link SearchSpec#GROUPING_TYPE_PER_SCHEMA}
+     */
+    String SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA = "SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA";
 
     /** Feature for {@link #isFeatureSupported(String)}. This feature covers
      * {@link SearchSpec.Builder#setPropertyWeights}.
@@ -136,6 +130,28 @@
     String JOIN_SPEC_AND_QUALIFIED_ID = "JOIN_SPEC_AND_QUALIFIED_ID";
 
     /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link AppSearchSession#searchSuggestionAsync}.
+     */
+    String SEARCH_SUGGESTION = "SEARCH_SUGGESTION";
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers
+     * {@link AppSearchSchema.StringPropertyConfig.Builder#setDeletionPropagation}.
+     */
+    String SCHEMA_SET_DELETION_PROPAGATION = "SCHEMA_SET_DELETION_PROPAGATION";
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}. This feature covers setting schemas with
+     * circular references for {@link AppSearchSession#setSchemaAsync}
+     *
+     * @exportToFramework:hide
+     * TODO(b/280698121): Unhide and request jetpack API approval after this is synced to framework.
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    String SET_SCHEMA_CIRCULAR_REFERENCES = "SET_SCHEMA_CIRCULAR_REFERENCES";
+
+    /**
      * Returns whether a feature is supported at run-time. Feature support depends on the
      * feature in question, the AppSearch backend being used and the Android version of the
      * device.
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
index 5dd5a6c..6dcecce 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GenericDocument.java
@@ -25,6 +25,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.annotation.Document;
 import androidx.appsearch.app.PropertyPath.PathSegment;
 import androidx.appsearch.exceptions.AppSearchException;
@@ -136,7 +137,7 @@
      *
      * @param bundle Packaged {@link GenericDocument} data, such as the result of
      *               {@link #getBundle}.
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @SuppressWarnings("deprecation")
@@ -162,7 +163,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -426,7 +427,7 @@
                     // paths we return the bare document Bundle in this particular case.
                     Parcelable[] bundles = (Parcelable[]) currentElementValue;
                     if (index < bundles.length) {
-                        extractedValue = (Bundle) bundles[index];
+                        extractedValue = bundles[index];
                     }
                 } else {
                     throw new IllegalStateException("Unsupported value type: "
@@ -1127,6 +1128,7 @@
          * <p>The number of namespaces per app should be kept small for efficiency reasons.
          * <!--@exportToFramework:hide-->
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setNamespace(@NonNull String namespace) {
             Preconditions.checkNotNull(namespace);
@@ -1142,6 +1144,7 @@
          * <p>Document IDs are unique within a namespace.
          * <!--@exportToFramework:hide-->
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setId(@NonNull String id) {
             Preconditions.checkNotNull(id);
@@ -1157,6 +1160,7 @@
          * {@link AppSearchSchema} object previously provided to {@link AppSearchSession#setSchemaAsync}.
          * <!--@exportToFramework:hide-->
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setSchemaType(@NonNull String schemaType) {
             Preconditions.checkNotNull(schemaType);
@@ -1177,7 +1181,9 @@
          * <p>Any non-negative integer can be used a score. By default, scores are set to 0.
          *
          * @param score any non-negative {@code int} representing the document's score.
+         * @throws IllegalArgumentException if the score is negative.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) {
             if (score < 0) {
@@ -1198,6 +1204,7 @@
          *
          * @param creationTimestampMillis a creation timestamp in milliseconds.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setCreationTimestampMillis(
                 /*@exportToFramework:CurrentTimeMillisLong*/ long creationTimestampMillis) {
@@ -1219,7 +1226,9 @@
          * called.
          *
          * @param ttlMillis a non-negative duration in milliseconds.
+         * @throws IllegalArgumentException if ttlMillis is negative.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setTtlMillis(long ttlMillis) {
             if (ttlMillis < 0) {
@@ -1241,6 +1250,7 @@
          * @throws IllegalArgumentException if no values are provided, or if a passed in
          *                                  {@code String} is {@code null} or "".
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
             Preconditions.checkNotNull(name);
@@ -1260,6 +1270,7 @@
          * @param values the {@code boolean} values of the property.
          * @throws IllegalArgumentException if the name is empty or {@code null}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
             Preconditions.checkNotNull(name);
@@ -1279,6 +1290,7 @@
          * @param values the {@code long} values of the property.
          * @throws IllegalArgumentException if the name is empty or {@code null}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
             Preconditions.checkNotNull(name);
@@ -1298,6 +1310,7 @@
          * @param values the {@code double} values of the property.
          * @throws IllegalArgumentException if the name is empty or {@code null}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
             Preconditions.checkNotNull(name);
@@ -1317,6 +1330,7 @@
          * @throws IllegalArgumentException if no values are provided, or if a passed in
          *                                  {@code byte[]} is {@code null}, or if name is empty.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
             Preconditions.checkNotNull(name);
@@ -1338,6 +1352,7 @@
          *                                  {@link GenericDocument} is {@code null}, or if name
          *                                  is empty.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType setPropertyDocument(
                 @NonNull String name, @NonNull GenericDocument... values) {
@@ -1356,6 +1371,7 @@
          * @param name The name of the property to clear.
          * <!--@exportToFramework:hide-->
          */
+        @CanIgnoreReturnValue
         @NonNull
         public BuilderType clearProperty(@NonNull String name) {
             Preconditions.checkNotNull(name);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
index d7ff30b..ee59e34 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetByDocumentIdRequest.java
@@ -18,6 +18,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
@@ -113,7 +114,7 @@
      * <p>A more efficient version of {@link #getProjections}, but it returns a modifiable map.
      * This is not meant to be unhidden and should only be used by internal classes.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -134,6 +135,7 @@
         }
 
         /** Adds one or more document IDs to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIds(@NonNull String... ids) {
             Preconditions.checkNotNull(ids);
@@ -142,6 +144,7 @@
         }
 
         /** Adds a collection of IDs to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIds(@NonNull Collection<String> ids) {
             Preconditions.checkNotNull(ids);
@@ -166,6 +169,7 @@
          *
          * @see SearchSpec.Builder#addProjectionPaths
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addProjection(
                 @NonNull String schemaType, @NonNull Collection<String> propertyPaths) {
@@ -197,6 +201,7 @@
          *
          * @see SearchSpec.Builder#addProjectionPaths
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addProjectionPaths(
                 @NonNull String schemaType, @NonNull Collection<PropertyPath> propertyPaths) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
index 3475576..2f8ee27 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/GetSchemaResponse.java
@@ -24,6 +24,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
@@ -48,14 +49,14 @@
     /**
      * This Set contains all schemas that are not displayed by the system. All values in the set are
      * prefixed with the package-database prefix. We do lazy fetch, the object will be created
-     * when the user first time fetch it.
+     * when you first time fetch it.
      */
     @Nullable
     private Set<String> mSchemasNotDisplayedBySystem;
     /**
      * This map contains all schemas and {@link PackageIdentifier} that has access to the schema.
      * All keys in the map are prefixed with the package-database prefix. We do lazy fetch, the
-     * object will be created when the user first time fetch it.
+     * object will be created when you first time fetch it.
      */
     @Nullable
     private Map<String, Set<PackageIdentifier>> mSchemasVisibleToPackages;
@@ -63,7 +64,7 @@
     /**
      * This map contains all schemas and Android Permissions combinations that are required to
      * access the schema. All keys in the map are prefixed with the package-database prefix. We
-     * do lazy fetch, the object will be created when the user first time fetch it.
+     * do lazy fetch, the object will be created when you first time fetch it.
      * The Map is constructed in ANY-ALL cases. The querier could read the {@link GenericDocument}
      * objects under the {@code schemaType} if they holds ALL required permissions of ANY
      * combinations.
@@ -81,7 +82,7 @@
 
     /**
      * Returns the {@link Bundle} populated by this builder.
-     * @hide
+     * @exportToFramework:hide
      */
     @NonNull
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -260,7 +261,7 @@
          * @param getVisibilitySettingSupported whether supported
          * {@link Features#ADD_PERMISSIONS_AND_GET_VISIBILITY} by this
          *                                      backend/Android API level.
-         * @hide
+         * @exportToFramework:hide
          */
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
         public Builder(boolean getVisibilitySettingSupported) {
@@ -276,6 +277,7 @@
          *
          * <p>Default version is 0
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVersion(@IntRange(from = 0) int version) {
             resetIfBuilt();
@@ -284,6 +286,7 @@
         }
 
         /**  Adds one {@link AppSearchSchema} to the schema list.  */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addSchema(@NonNull AppSearchSchema schema) {
             Preconditions.checkNotNull(schema);
@@ -300,6 +303,7 @@
          *                   {@link GetSchemaResponse}, which won't be displayed by system.
          */
         // Getter getSchemaTypesNotDisplayedBySystem returns plural objects.
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder addSchemaTypeNotDisplayedBySystem(@NonNull String schemaType) {
@@ -331,6 +335,7 @@
          *                                 schema type.
          */
         // Getter getSchemaTypesVisibleToPackages returns a map contains all schema types.
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setSchemaTypeVisibleToPackages(
@@ -378,6 +383,7 @@
          *                               the given schema.
          */
         // Getter getRequiredPermissionsForSchemaTypeVisibility returns a map for all schemaTypes.
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setRequiredPermissionsForSchemaTypeVisibility(
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java
index 42aecce..3a1da37 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/InternalSetSchemaResponse.java
@@ -31,7 +31,7 @@
  * incompatible changes form other call flows. This class adds a {@link #isSuccess()} to indicate
  * if the call fails because of incompatible change.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class InternalSetSchemaResponse {
@@ -58,7 +58,7 @@
 
     /**
      * Returns the {@link Bundle} populated by this builder.
-     * @hide
+     * @exportToFramework:hide
      */
     @NonNull
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/JoinSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/JoinSpec.java
index b5dcd55..40b0353 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/JoinSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/JoinSpec.java
@@ -21,6 +21,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.core.util.Preconditions;
 
 import java.lang.annotation.Retention;
@@ -32,9 +33,15 @@
  * <p> Joins are only possible for matching on the qualified id of an outer document and a
  * property value within a subquery document. In the subquery documents, these values may be
  * referred to with a property path such as "email.recipient.id" or "entityId" or a property
- * expression. One such property expression is {@link #QUALIFIED_ID}, which refers to the
+ * expression. One such property expression is "this.qualifiedId()", which refers to the
  * document's combined package, database, namespace, and id.
  *
+ * <p>Note that in order for perform the join, the property referred to by
+ * {@link #getChildPropertyExpression} has to be a property with
+ * {@link AppSearchSchema.StringPropertyConfig#getJoinableValueType} set to
+ * {@link AppSearchSchema.StringPropertyConfig#JOINABLE_VALUE_TYPE_QUALIFIED_ID}. Otherwise no
+ * documents will be joined to any {@link SearchResult}.
+ *
  * <p> Take these outer query and subquery results for example:
  *
  * <pre>{@code
@@ -69,19 +76,47 @@
  * does not equal the qualified id of the outer query result. As such, subquery result 1 will not be
  * joined to the outer query result.
  *
+ * <p> It's possible to define an advanced ranking strategy in the nested {@link SearchSpec} and
+ * also use {@link SearchSpec#RANKING_STRATEGY_JOIN_AGGREGATE_SCORE} in the outer
+ * {@link SearchSpec}. In this case, the parents will be ranked based on an aggregation, such as
+ * the sum, of the signals calculated by scoring the joined documents with the advanced ranking
+ * strategy.
+ *
  * <p> In terms of scoring, if {@link SearchSpec#RANKING_STRATEGY_JOIN_AGGREGATE_SCORE} is set in
  * {@link SearchSpec#getRankingStrategy}, the scores of the outer SearchResults can be influenced
  * by the ranking signals of the subquery results. For example, if the
- * {@link JoinSpec#getAggregationScoringStrategy} is set to
+ * {@link JoinSpec#getAggregationScoringStrategy} is set to:
+ * <ul><li>
  * {@link JoinSpec#AGGREGATION_SCORING_MIN_RANKING_SIGNAL}, the ranking signal of the outer
  * {@link SearchResult} will be set to the minimum of the ranking signals of the subquery results.
- * In this case, it will be the minimum of 2 and 3, which is 2. If the
- * {@link JoinSpec#getAggregationScoringStrategy} is set to
+ * In this case, it will be the minimum of 2 and 3, which is 2.
+ * </li>
+ * <li>
+ * {@link JoinSpec#AGGREGATION_SCORING_MAX_RANKING_SIGNAL}, the ranking signal of the outer
+ * {@link SearchResult} will be 3.
+ * </li>
+ * <li>
+ * {@link JoinSpec#AGGREGATION_SCORING_AVG_RANKING_SIGNAL}, the ranking signal of the outer
+ * {@link SearchResult} will be 2.5.
+ * </li>
+ * <li>
+ * {@link JoinSpec#AGGREGATION_SCORING_RESULT_COUNT}, the ranking signal of the outer
+ * {@link SearchResult} will be 2 as there are two joined results.
+ * </li>
+ * <li>
+ * {@link JoinSpec#AGGREGATION_SCORING_SUM_RANKING_SIGNAL}, the ranking signal of the outer
+ * {@link SearchResult} will be 5, the sum of 2 and 3.
+ * </li>
+ * <li>
  * {@link JoinSpec#AGGREGATION_SCORING_OUTER_RESULT_RANKING_SIGNAL}, the ranking signal of the outer
  * {@link SearchResult} will stay as it is.
+ * </li>
+ * </ul>
+ *
+ * <p> Referring to "this.childrenRankingSignals()" in the ranking signal of the outer query will
+ * return the signals calculated by scoring the joined documents using the scoring strategy in the
+ * nested {@link SearchSpec}, as in {@link SearchResult#getRankingSignal}.
  */
-// TODO(b/256022027): Update javadoc once "Joinable"/"qualifiedId" type is added to reflect the
-//  fact that childPropertyExpression has to point to property of that type.
 public final class JoinSpec {
     static final String NESTED_QUERY = "nestedQuery";
     static final String NESTED_SEARCH_SPEC = "nestedSearchSpec";
@@ -97,13 +132,16 @@
      *
      * <p> For instance, if a document with an id of "id1" exists in the namespace "ns" within
      * the database "db" created by package "pkg", this would evaluate to "pkg$db/ns#id1".
+     *
+     * <!--@exportToFramework:hide-->
      */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public static final String QUALIFIED_ID = "this.qualifiedId()";
 
     /**
      * Aggregation scoring strategy for join spec.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
     // {@link JoinSpecProto.AggregationScoreStrategy.Code}
@@ -136,7 +174,7 @@
 
     private final Bundle mBundle;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public JoinSpec(@NonNull Bundle bundle) {
         Preconditions.checkNotNull(bundle);
@@ -146,7 +184,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -177,8 +215,8 @@
     }
 
     /**
-     * Returns the max amount of {@link SearchResult} objects that will be joined to the parent
-     * document, with a default of 10 SearchResults.
+     * Returns the max amount of {@link SearchResult} objects to return with the parent document,
+     * with a default of 10 SearchResults.
      */
     public int getMaxJoinedResultCount() {
         return mBundle.getInt(MAX_JOINED_RESULT_COUNT);
@@ -204,7 +242,8 @@
      *
      * @see SearchSpec#RANKING_STRATEGY_JOIN_AGGREGATE_SCORE
      */
-    public @AggregationScoringStrategy int getAggregationScoringStrategy() {
+    @AggregationScoringStrategy
+    public int getAggregationScoringStrategy() {
         return mBundle.getInt(AGGREGATION_SCORING_STRATEGY);
     }
 
@@ -218,7 +257,7 @@
         private SearchSpec mNestedSearchSpec = EMPTY_SEARCH_SPEC;
         private final String mChildPropertyExpression;
         private int mMaxJoinedResultCount = DEFAULT_MAX_JOINED_RESULT_COUNT;
-        private @AggregationScoringStrategy int mAggregationScoringStrategy =
+        @AggregationScoringStrategy private int mAggregationScoringStrategy =
                 AGGREGATION_SCORING_OUTER_RESULT_RANKING_SIGNAL;
 
         /**
@@ -251,7 +290,15 @@
         }
 
         /**
-         * Further filters the documents being joined.
+         * Sets the query and the SearchSpec for the documents being joined. This will score and
+         * rank the joined documents as well as filter the joined documents.
+         *
+         * <p>If {@link SearchSpec.RankingStrategy#RANKING_STRATEGY_JOIN_AGGREGATE_SCORE} is set in
+         * the outer {@link SearchSpec}, the resulting signals will be used to rank the parent
+         * documents. Note that the aggregation strategy also needs to be set with
+         * {@link JoinSpec.Builder#setAggregationScoringStrategy}, otherwise the default will be
+         * {@link JoinSpec#AGGREGATION_SCORING_OUTER_RESULT_RANKING_SIGNAL}, which will just use
+         * the parent documents ranking signal.
          *
          * <p> If this method is never called, {@link JoinSpec#getNestedQuery} will return an empty
          * string, meaning we will join with every possible document that matches the equality
@@ -262,6 +309,7 @@
          */
         @SuppressWarnings("MissingGetterMatchingBuilder")
         // See getNestedQuery & getNestedSearchSpec
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNestedSearch(@NonNull String nestedQuery,
                 @NonNull SearchSpec nestedSearchSpec) {
@@ -274,9 +322,15 @@
         }
 
         /**
-         * Sets the max amount of {@link SearchResults} to join to the parent document, with a
+         * Sets the max amount of {@link SearchResults} to return with the parent document, with a
          * default of 10 SearchResults.
+         *
+         * <p>This does NOT limit the number of results that are joined with the parent
+         * document for scoring. This means that, when set, only a maximum of
+         * {@code maxJoinedResultCount} results will be returned with each parent document, but
+         * all results that are joined with a parent will factor into the score.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setMaxJoinedResultCount(int maxJoinedResultCount) {
             mMaxJoinedResultCount = maxJoinedResultCount;
@@ -292,6 +346,7 @@
          *
          * @see SearchSpec#RANKING_STRATEGY_JOIN_AGGREGATE_SCORE
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setAggregationScoringStrategy(
                 @AggregationScoringStrategy int aggregationScoringStrategy) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PackageIdentifier.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PackageIdentifier.java
index a7301f5..6c4bc59 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PackageIdentifier.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PackageIdentifier.java
@@ -52,13 +52,13 @@
         mBundle.putByteArray(SHA256_CERTIFICATE_FIELD, sha256Certificate);
     }
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public PackageIdentifier(@NonNull Bundle bundle) {
         mBundle = Preconditions.checkNotNull(bundle);
     }
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
     public Bundle getBundle() {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
index dff69b2..6edf85e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/PutDocumentsRequest.java
@@ -19,6 +19,7 @@
 import android.annotation.SuppressLint;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.core.util.Preconditions;
 
@@ -58,6 +59,7 @@
         private boolean mBuilt = false;
 
         /** Adds one or more {@link GenericDocument} objects to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addGenericDocuments(@NonNull GenericDocument... documents) {
             Preconditions.checkNotNull(documents);
@@ -66,6 +68,7 @@
         }
 
         /** Adds a collection of {@link GenericDocument} objects to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addGenericDocuments(
                 @NonNull Collection<? extends GenericDocument> documents) {
@@ -87,6 +90,7 @@
          */
         // Merged list available from getGenericDocuments()
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addDocuments(@NonNull Object... documents) throws AppSearchException {
             Preconditions.checkNotNull(documents);
@@ -105,6 +109,7 @@
          */
         // Merged list available from getGenericDocuments()
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addDocuments(@NonNull Collection<?> documents) throws AppSearchException {
             Preconditions.checkNotNull(documents);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
index 38be17a..40cd591 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/RemoveByDocumentIdRequest.java
@@ -17,6 +17,7 @@
 package androidx.appsearch.app;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
@@ -64,6 +65,7 @@
         }
 
         /** Adds one or more document IDs to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIds(@NonNull String... ids) {
             Preconditions.checkNotNull(ids);
@@ -72,6 +74,7 @@
         }
 
         /** Adds a collection of IDs to the request. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIds(@NonNull Collection<String> ids) {
             Preconditions.checkNotNull(ids);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
index 12422eb..67550eb 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportSystemUsageRequest.java
@@ -17,6 +17,7 @@
 package androidx.appsearch.app;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.core.util.Preconditions;
 
 /**
@@ -95,12 +96,12 @@
          * Creates a {@link ReportSystemUsageRequest.Builder} instance.
          *
          * @param packageName  The package name of the app which owns the document that was used
-         *                     (e.g. from {@link SearchResult#getPackageName}).
-         * @param databaseName The database in which the document that was used resides (e.g. from
-         *                     {@link SearchResult#getDatabaseName}).
-         * @param namespace    The namespace of the document that was used (e.g. from
+         *                     (such as from {@link SearchResult#getPackageName}).
+         * @param databaseName The database in which the document that was used resides (such as
+         *                     from {@link SearchResult#getDatabaseName}).
+         * @param namespace    The namespace of the document that was used (such as from
          *                     {@link GenericDocument#getNamespace}.
-         * @param documentId   The ID of document that was used (e.g. from
+         * @param documentId   The ID of document that was used (such as from
          *                     {@link GenericDocument#getId}.
          */
         public Builder(
@@ -123,6 +124,7 @@
          * <p>If unset, this defaults to the current timestamp at the time that the
          * {@link ReportSystemUsageRequest} is constructed.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public ReportSystemUsageRequest.Builder setUsageTimestampMillis(
                 /*@exportToFramework:CurrentTimeMillisLong*/ long usageTimestampMillis) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
index 14b70c7..58e7d9b 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/ReportUsageRequest.java
@@ -17,6 +17,7 @@
 package androidx.appsearch.app;
 
 import androidx.annotation.NonNull;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.core.util.Preconditions;
 
 /**
@@ -70,9 +71,9 @@
         /**
          * Creates a new {@link ReportUsageRequest.Builder} instance.
          *
-         * @param namespace    The namespace of the document that was used (e.g. from
+         * @param namespace    The namespace of the document that was used (such as from
          *                     {@link GenericDocument#getNamespace}.
-         * @param documentId   The ID of document that was used (e.g. from
+         * @param documentId   The ID of document that was used (such as from
          *                     {@link GenericDocument#getId}.
          */
         public Builder(@NonNull String namespace, @NonNull String documentId) {
@@ -89,6 +90,7 @@
          * <p>If unset, this defaults to the current timestamp at the time that the
          * {@link ReportUsageRequest} is constructed.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public ReportUsageRequest.Builder setUsageTimestampMillis(
                 /*@exportToFramework:CurrentTimeMillisLong*/ long usageTimestampMillis) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
index 32e4507..37d922e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResult.java
@@ -22,6 +22,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.core.util.ObjectsCompat;
 import androidx.core.util.Preconditions;
@@ -63,13 +64,13 @@
     @Nullable
     private List<MatchInfo> mMatchInfos;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public SearchResult(@NonNull Bundle bundle) {
         mBundle = Preconditions.checkNotNull(bundle);
     }
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
     public Bundle getBundle() {
@@ -244,6 +245,7 @@
          * @throws AppSearchException if an error occurs converting a document class into a
          *                            {@link GenericDocument}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setDocument(@NonNull Object document) throws AppSearchException {
             Preconditions.checkNotNull(document);
@@ -253,6 +255,7 @@
 // @exportToFramework:endStrip()
 
         /** Sets the document which matched. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setGenericDocument(@NonNull GenericDocument document) {
             Preconditions.checkNotNull(document);
@@ -262,6 +265,7 @@
         }
 
         /** Adds another match to this SearchResult. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addMatchInfo(@NonNull MatchInfo matchInfo) {
             Preconditions.checkState(
@@ -274,6 +278,7 @@
         }
 
         /** Sets the ranking signal of the matched document in this SearchResult. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRankingSignal(double rankingSignal) {
             resetIfBuilt();
@@ -285,6 +290,7 @@
          * Adds a {@link SearchResult} that was joined by the {@link JoinSpec}.
          * @param joinedResult The joined SearchResult to add.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addJoinedResult(@NonNull SearchResult joinedResult) {
             resetIfBuilt();
@@ -316,8 +322,8 @@
     }
 
     /**
-     * This class represents match objects for any Snippets that might be present in
-     * {@link SearchResults} from a query. Using this class, the user can get:
+     * This class represents match objects for any snippets that might be present in
+     * {@link SearchResults} from a query. Using this class, you can get:
      * <ul>
      *     <li>the full text - all of the text in that String property</li>
      *     <li>the exact term match - the 'term' (full word) that matched the query</li>
@@ -635,7 +641,7 @@
              * property in the document these snippets correspond to.
              *
              * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc.
-             * For class example 1 this returns "subject".
+             * For class example 1, this returns "subject".
              *
              * @param propertyPath A dot-delimited sequence of property names indicating which
              *                     property in the document these snippets correspond to.
@@ -645,6 +651,7 @@
             }
 
             /** Sets the exact {@link MatchRange} corresponding to the given entry. */
+            @CanIgnoreReturnValue
             @NonNull
             public Builder setExactMatchRange(@NonNull MatchRange matchRange) {
                 mExactMatchRange = Preconditions.checkNotNull(matchRange);
@@ -653,6 +660,7 @@
 
 
             /** Sets the submatch {@link MatchRange} corresponding to the given entry. */
+            @CanIgnoreReturnValue
             @NonNull
             public Builder setSubmatchRange(@NonNull MatchRange matchRange) {
                 mSubmatchRange = Preconditions.checkNotNull(matchRange);
@@ -660,6 +668,7 @@
             }
 
             /** Sets the snippet {@link MatchRange} corresponding to the given entry. */
+            @CanIgnoreReturnValue
             @NonNull
             public Builder setSnippetRange(@NonNull MatchRange matchRange) {
                 mSnippetRange = Preconditions.checkNotNull(matchRange);
@@ -697,7 +706,7 @@
      * <p> All ranges are finite, and the left side of the range is always {@code <=} the right
      * side of the range.
      *
-     * <p> Example: MatchRange(0, 100) represent a hundred ints from 0 to 99."
+     * <p> Example: MatchRange(0, 100) represents hundred ints from 0 to 99."
      */
     public static final class MatchRange {
         private final int mEnd;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResultPage.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResultPage.java
index 4f19b74..568c2b6 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResultPage.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchResultPage.java
@@ -29,7 +29,7 @@
 
 /**
  * This class represents a page of {@link SearchResult}s
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class SearchResultPage {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
index 9f951fd..919cf29 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSpec.java
@@ -25,6 +25,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.annotation.Document;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.util.BundleUtil;
@@ -72,7 +73,7 @@
     static final String ADVANCED_RANKING_EXPRESSION = "advancedRankingExpression";
     static final String ENABLED_FEATURES_FIELD = "enabledFeatures";
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public static final int DEFAULT_NUM_PER_PAGE = 10;
 
@@ -86,10 +87,11 @@
     /**
      * Term Match Type for the query.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
     // {@link com.google.android.icing.proto.SearchSpecProto.termMatchType}
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef(value = {
             TERM_MATCH_EXACT_ONLY,
             TERM_MATCH_PREFIX
@@ -100,22 +102,25 @@
 
     /**
      * Query terms will only match exact tokens in the index.
-     * <p>Ex. A query term "foo" will only match indexed token "foo", and not "foot" or "football".
+     * <p>For example, a query term "foo" will only match indexed token "foo", and not "foot" or
+     * "football".
      */
     public static final int TERM_MATCH_EXACT_ONLY = 1;
     /**
      * Query terms will match indexed tokens when the query term is a prefix of the token.
-     * <p>Ex. A query term "foo" will match indexed tokens like "foo", "foot", and "football".
+     * <p>For example, a query term "foo" will match indexed tokens like "foo", "foot", and
+     * "football".
      */
     public static final int TERM_MATCH_PREFIX = 2;
 
     /**
      * Ranking Strategy for query result.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
     // {@link ScoringSpecProto.RankingStrategy.Code}
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef(value = {
             RANKING_STRATEGY_NONE,
             RANKING_STRATEGY_DOCUMENT_SCORE,
@@ -164,10 +169,11 @@
     /**
      * Order for query result.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     // NOTE: The integer values of these constants must match the proto enum constants in
     // {@link ScoringSpecProto.Order.Code}
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef(value = {
             ORDER_DESCENDING,
             ORDER_ASCENDING
@@ -184,31 +190,43 @@
     /**
      * Grouping type for result limits.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @IntDef(flag = true, value = {
             GROUPING_TYPE_PER_PACKAGE,
-            GROUPING_TYPE_PER_NAMESPACE
+            GROUPING_TYPE_PER_NAMESPACE,
+            GROUPING_TYPE_PER_SCHEMA
     })
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @Retention(RetentionPolicy.SOURCE)
     public @interface GroupingType {
     }
-
     /**
      * Results should be grouped together by package for the purpose of enforcing a limit on the
      * number of results returned per package.
      */
-    public static final int GROUPING_TYPE_PER_PACKAGE = 0b01;
+    public static final int GROUPING_TYPE_PER_PACKAGE = 1 << 0;
     /**
      * Results should be grouped together by namespace for the purpose of enforcing a limit on the
      * number of results returned per namespace.
      */
-    public static final int GROUPING_TYPE_PER_NAMESPACE = 0b10;
+    public static final int GROUPING_TYPE_PER_NAMESPACE = 1 << 1;
+    /**
+     * Results should be grouped together by schema type for the purpose of enforcing a limit on the
+     * number of results returned per schema type.
+     * <!--@exportToFramework:hide-->
+     */
+    // @exportToFramework:startStrip()
+    // TODO(b/258715421) start exporting this when it is unhidden in framework
+    @RequiresFeature(
+            enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
+            name = Features.SEARCH_SPEC_GROUPING_TYPE_PER_SCHEMA)
+    // @exportToFramework:endStrip()
+    public static final int GROUPING_TYPE_PER_SCHEMA = 1 << 2;
 
     private final Bundle mBundle;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public SearchSpec(@NonNull Bundle bundle) {
         Preconditions.checkNotNull(bundle);
@@ -218,7 +236,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -227,7 +245,8 @@
     }
 
     /** Returns how the query terms should match terms in the index. */
-    public @TermMatch int getTermMatch() {
+    @TermMatch
+    public int getTermMatch() {
         return mBundle.getInt(TERM_MATCH_TYPE_FIELD, -1);
     }
 
@@ -281,12 +300,14 @@
     }
 
     /** Returns the ranking strategy. */
-    public @RankingStrategy int getRankingStrategy() {
+    @RankingStrategy
+    public int getRankingStrategy() {
         return mBundle.getInt(RANKING_STRATEGY_FIELD);
     }
 
     /** Returns the order of returned search results (descending or ascending). */
-    public @Order int getOrder() {
+    @Order
+    public int getOrder() {
         return mBundle.getInt(ORDER_FIELD);
     }
 
@@ -415,7 +436,8 @@
      * Get the type of grouping limit to apply, or 0 if {@link Builder#setResultGrouping} was not
      * called.
      */
-    public @GroupingType int getResultGroupingTypeFlags() {
+    @GroupingType
+    public int getResultGroupingTypeFlags() {
         return mBundle.getInt(RESULT_GROUPING_TYPE_FLAGS);
     }
 
@@ -454,28 +476,28 @@
      * Returns whether the {@link Features#NUMERIC_SEARCH} feature is enabled.
      */
     public boolean isNumericSearchEnabled() {
-        return getEnabledFeatures().contains(Features.NUMERIC_SEARCH);
+        return getEnabledFeatures().contains(FeatureConstants.NUMERIC_SEARCH);
     }
 
     /**
      * Returns whether the {@link Features#VERBATIM_SEARCH} feature is enabled.
      */
     public boolean isVerbatimSearchEnabled() {
-        return getEnabledFeatures().contains(Features.VERBATIM_SEARCH);
+        return getEnabledFeatures().contains(FeatureConstants.VERBATIM_SEARCH);
     }
 
     /**
      * Returns whether the {@link Features#LIST_FILTER_QUERY_LANGUAGE} feature is enabled.
      */
     public boolean isListFilterQueryLanguageEnabled() {
-        return getEnabledFeatures().contains(Features.LIST_FILTER_QUERY_LANGUAGE);
+        return getEnabledFeatures().contains(FeatureConstants.LIST_FILTER_QUERY_LANGUAGE);
     }
 
     /**
      * Get the list of enabled features that the caller is intending to use in this search call.
      *
      * @return the set of {@link Features} enabled in this {@link SearchSpec} Entry.
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -493,24 +515,25 @@
         private Bundle mTypePropertyWeights = new Bundle();
 
         private int mResultCountPerPage = DEFAULT_NUM_PER_PAGE;
-        private @TermMatch int mTermMatchType = TERM_MATCH_PREFIX;
+        @TermMatch private int mTermMatchType = TERM_MATCH_PREFIX;
         private int mSnippetCount = 0;
         private int mSnippetCountPerProperty = MAX_SNIPPET_PER_PROPERTY_COUNT;
         private int mMaxSnippetSize = 0;
-        private @RankingStrategy int mRankingStrategy = RANKING_STRATEGY_NONE;
-        private @Order int mOrder = ORDER_DESCENDING;
-        private @GroupingType int mGroupingTypeFlags = 0;
+        @RankingStrategy private int mRankingStrategy = RANKING_STRATEGY_NONE;
+        @Order private int mOrder = ORDER_DESCENDING;
+        @GroupingType private int mGroupingTypeFlags = 0;
         private int mGroupingLimit = 0;
         private JoinSpec mJoinSpec;
         private String mAdvancedRankingExpression = "";
         private boolean mBuilt = false;
 
         /**
-         * Indicates how the query terms should match {@code TermMatchCode} in the index.
+         * Sets how the query terms should match {@code TermMatchCode} in the index.
          *
          * <p>If this method is not called, the default term match type is
          * {@link SearchSpec#TERM_MATCH_PREFIX}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTermMatch(@TermMatch int termMatchType) {
             Preconditions.checkArgumentInRange(termMatchType, TERM_MATCH_EXACT_ONLY,
@@ -526,6 +549,7 @@
          *
          * <p>If unset, the query will search over all schema types.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull String... schemas) {
             Preconditions.checkNotNull(schemas);
@@ -539,6 +563,7 @@
          *
          * <p>If unset, the query will search over all schema types.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull Collection<String> schemas) {
             Preconditions.checkNotNull(schemas);
@@ -555,9 +580,11 @@
          *
          * <p>If unset, the query will search over all schema types.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder addFilterDocumentClasses(
@@ -583,9 +610,11 @@
          *
          * <p>If unset, the query will search over all schema types.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas()
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder addFilterDocumentClasses(@NonNull Class<?>... documentClasses)
@@ -601,6 +630,7 @@
          * have the specified namespaces.
          * <p>If unset, the query will search over all namespaces.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterNamespaces(@NonNull String... namespaces) {
             Preconditions.checkNotNull(namespaces);
@@ -613,6 +643,7 @@
          * have the specified namespaces.
          * <p>If unset, the query will search over all namespaces.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterNamespaces(@NonNull Collection<String> namespaces) {
             Preconditions.checkNotNull(namespaces);
@@ -629,6 +660,7 @@
          * If package names are specified which caller doesn't have access to, then those package
          * names will be ignored.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterPackageNames(@NonNull String... packageNames) {
             Preconditions.checkNotNull(packageNames);
@@ -644,6 +676,7 @@
          * If package names are specified which caller doesn't have access to, then those package
          * names will be ignored.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterPackageNames(@NonNull Collection<String> packageNames) {
             Preconditions.checkNotNull(packageNames);
@@ -657,6 +690,7 @@
          *
          * <p>The default number of results per page is 10.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder setResultCountPerPage(
                 @IntRange(from = 0, to = MAX_NUM_PER_PAGE) int resultCountPerPage) {
@@ -668,6 +702,7 @@
         }
 
         /** Sets ranking strategy for AppSearch results. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRankingStrategy(@RankingStrategy int rankingStrategy) {
             Preconditions.checkArgumentInRange(rankingStrategy, RANKING_STRATEGY_NONE,
@@ -690,52 +725,41 @@
          * <p>Numeric literals, arithmetic operators, mathematical functions, and document-based
          * functions are supported to build expressions.
          *
-         * <p>The following are examples of numeric literals:
-         * <ul>
-         *     <li>Integer
-         *     <p>Example: 0, 1, 2, 13
-         *     <li>Floating-point number
-         *     <p>Example: 0.333, 0.5, 123.456
-         *     <li>Negative number
-         *     <p>Example: -5, -10.5, -100.123
-         * </ul>
-         *
          * <p>The following are supported arithmetic operators:
          * <ul>
          *     <li>Addition(+)
-         *     <p>Example: "1 + 1" will be evaluated to 2.
          *     <li>Subtraction(-)
-         *     <p>Example: "2 - 1.5" will be evaluated to 0.5.
          *     <li>Multiplication(*)
-         *     <p>Example: "2 * -2" will be evaluated to -4.
-         *     <li>Division(/)
-         *     <p>Example: "5 / 2" will be evaluated to 2.5.
+         *     <li>Floating Point Division(/)
          * </ul>
          *
-         * <p>Multiplication and division have higher precedences than addition and subtraction,
-         * but multiplication has the same precedence as division, and addition has the same
-         * precedence as subtraction. Parentheses are supported to change precedences.
+         * <p>Operator precedences are compliant with the Java Language, and parentheses are
+         * supported. For example, "2.2 + (3 - 4) / 2" evaluates to 1.7.
          *
-         * <p>For example:
-         * <ul>
-         *     <li>"2 + 3 - 4 * 5" will be evaluated to -15
-         *     <li>"(2 + 3) - (4 * 5)" will be evaluated to -15
-         *     <li>"2 + (3 - 4) * 5" will be evaluated to -3
-         * </ul>
-         *
-         * <p>The following are supported mathematical functions:
+         * <p>The following are supported basic mathematical functions:
          * <ul>
          *     <li>log(x) - the natural log of x
          *     <li>log(x, y) - the log of y with base x
          *     <li>pow(x, y) - x to the power of y
-         *     <li>max(v1, v2, ..., vn) with n > 0 - the maximum value among v1, ..., vn
-         *     <li>min(v1, v2, ..., vn) with n > 0 - the minimum value among v1, ..., vn
-         *     <li>sqrt(x) - the square root of x
-         *     <li>abs(x) - the absolute value of x
-         *     <li>sin(x), cos(x), tan(x) - trigonometric functions of x
+         *     <li>sqrt(x)
+         *     <li>abs(x)
+         *     <li>sin(x), cos(x), tan(x)
          *     <li>Example: "max(abs(-100), 10) + pow(2, 10)" will be evaluated to 1124
          * </ul>
          *
+         * <p>The following variadic mathematical functions are supported, with n > 0. They also
+         * accept list value parameters. For example, if V is a value of list type, we can call
+         * sum(V) to get the sum of all the values in V. List literals are not supported, so a
+         * value of list type can only be constructed as a return value of some particular
+         * document-based functions.
+         * <ul>
+         *     <li>max(v1, v2, ..., vn) or max(V)
+         *     <li>min(v1, v2, ..., vn) or min(V)
+         *     <li>len(v1, v2, ..., vn) or len(V)
+         *     <li>sum(v1, v2, ..., vn) or sum(V)
+         *     <li>avg(v1, v2, ..., vn) or avg(V)
+         * </ul>
+         *
          * <p>Document-based functions must be called via "this", which represents the current
          * document being scored. The following are supported document-based functions:
          * <ul>
@@ -754,27 +778,61 @@
          *     document, where type must be evaluated to an integer from 1 to 2. Type 1 refers to
          *     usages reported by {@link AppSearchSession#reportUsageAsync}, and type 2 refers to
          *     usages reported by {@link GlobalSearchSession#reportSystemUsageAsync}.
+         *     <li>this.childrenRankingSignals()
+         *     <p>Returns a list of children ranking signals calculated by scoring the joined
+         *     documents using the ranking strategy specified in the nested {@link SearchSpec}.
+         *     Currently, a document can only be a child of another document in the context of
+         *     joins. If this function is called without the Join API enabled, a type error will
+         *     be raised.
+         *     <li>this.propertyWeights()
+         *     <p>Returns a list of the normalized weights of the matched properties for the
+         *     current document being scored. Property weights come from what's specified in
+         *     {@link SearchSpec}. After normalizing, each provided weight will be divided by the
+         *     maximum weight, so that each of them will be <= 1.
          * </ul>
          *
          * <p>Some errors may occur when using advanced ranking.
+         *
+         * <p>Syntax Error: the expression violates the syntax of the advanced ranking language.
+         * Below are some examples.
          * <ul>
-         *     <li>Syntax Error: the expression violates the syntax of the advanced ranking
-         *     language, such as unbalanced parenthesis.
-         *     <li>Type Error: the expression fails a static type check, such as getting the wrong
-         *     number of arguments for a function.
-         *     <li>Evaluation Error: an error occurred while evaluating the value of the
-         *     expression, such as getting a non-finite value in the middle of evaluation.
-         *     Expressions like "1 / 0" and "log(0) fall into this category.
+         *     <li>"1 + " - missing operand
+         *     <li>"2 * (1 + 2))" - unbalanced parenthesis
+         *     <li>"2 ^ 3" - unknown operator
+         * </ul>
+         *
+         * <p>Type Error: the expression fails a static type check. Below are some examples.
+         * <ul>
+         *     <li>"sin(2, 3)" - wrong number of arguments for the sin function
+         *     <li>"this.childrenRankingSignals() + 1" - cannot add a list with a number
+         *     <li>"this.propertyWeights()" - the final type of the overall expression cannot be
+         *     a list, which can be fixed by "max(this.propertyWeights())"
+         *     <li>"abs(this.propertyWeights())" - the abs function does not support list type
+         *     arguments
+         *     <li>"print(2)" - unknown function
+         * </ul>
+         *
+         * <p>Evaluation Error: an error occurred while evaluating the value of the expression.
+         * Below are some examples.
+         * <ul>
+         *     <li>"1 / 0", "log(0)", "1 + sqrt(-1)" - getting a non-finite value in the middle
+         *     of evaluation
+         *     <li>"this.usageCount(1 + 0.5)" - expect the argument to be an integer. Note that
+         *     this is not a type error and "this.usageCount(1.5 + 1/2)" can succeed without any
+         *     issues
+         *     <li>"this.documentScore()" - in case of an IO error, this will be an evaluation error
          * </ul>
          *
          * <p>Syntax errors and type errors will fail the entire search and will cause
-         * {@link SearchResults#getNextPageAsync()} to throw an {@link AppSearchException}.
+         * {@link SearchResults#getNextPageAsync} to throw an {@link AppSearchException} with the
+         * result code of {@link AppSearchResult#RESULT_INVALID_ARGUMENT}.
          * <p>Evaluation errors will result in the offending documents receiving the default score.
          * For {@link #ORDER_DESCENDING}, the default score will be 0, for
          * {@link #ORDER_ASCENDING} the default score will be infinity.
          *
          * @param advancedRankingExpression a non-empty string representing the ranking expression.
          */
+        @CanIgnoreReturnValue
         @NonNull
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -790,11 +848,12 @@
         }
 
         /**
-         * Indicates the order of returned search results, the default is
+         * Sets the order of returned search results, the default is
          * {@link #ORDER_DESCENDING}, meaning that results with higher scores come first.
          *
          * <p>This order field will be ignored if RankingStrategy = {@code RANKING_STRATEGY_NONE}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setOrder(@Order int order) {
             Preconditions.checkArgumentInRange(order, ORDER_DESCENDING, ORDER_ASCENDING,
@@ -805,8 +864,8 @@
         }
 
         /**
-         * Only the first {@code snippetCount} documents based on the ranking strategy
-         * will have snippet information provided.
+         * Sets the {@code snippetCount} such that the first {@code snippetCount} documents based
+         * on the ranking strategy will have snippet information provided.
          *
          * <p>The list returned from {@link SearchResult#getMatchInfos} will contain at most this
          * many entries.
@@ -814,6 +873,7 @@
          * <p>If set to 0 (default), snippeting is disabled and the list returned from
          * {@link SearchResult#getMatchInfos} will be empty.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder setSnippetCount(
                 @IntRange(from = 0, to = MAX_SNIPPET_COUNT) int snippetCount) {
@@ -834,6 +894,7 @@
          * <p>The default behavior is to snippet all matches a property contains, up to the maximum
          * value of 10,000.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder setSnippetCountPerProperty(
                 @IntRange(from = 0, to = MAX_SNIPPET_PER_PROPERTY_COUNT)
@@ -851,12 +912,13 @@
          * {@code maxSnippetSize/2} bytes after the middle of the matching token. It respects
          * token boundaries, therefore the returned window may be smaller than requested.
          *
-         * <p> Setting {@code maxSnippetSize} to 0 will disable windowing and an empty string will
+         * <p> Setting {@code maxSnippetSize} to 0 will disable windowing and an empty String will
          * be returned. If matches enabled is also set to false, then snippeting is disabled.
          *
-         * <p>Ex. {@code maxSnippetSize} = 16. "foo bar baz bat rat" with a query of "baz" will
-         * return a window of "bar baz bat" which is only 11 bytes long.
+         * <p>For example, {@code maxSnippetSize} = 16. "foo bar baz bat rat" with a query of "baz"
+         * will return a window of "bar baz bat" which is only 11 bytes long.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder setMaxSnippetSize(
                 @IntRange(from = 0, to = MAX_SNIPPET_SIZE_LIMIT) int maxSnippetSize) {
@@ -878,6 +940,7 @@
          * @param schema a string corresponding to the schema to add projections to.
          * @param propertyPaths the projections to add.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder addProjection(
                 @NonNull String schema, @NonNull Collection<String> propertyPaths) {
@@ -956,6 +1019,7 @@
          * @param schema a string corresponding to the schema to add projections to.
          * @param propertyPaths the projections to add.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public SearchSpec.Builder addProjectionPaths(
                 @NonNull String schema, @NonNull Collection<PropertyPath> propertyPaths) {
@@ -981,6 +1045,7 @@
          *                      add projections to.
          * @param propertyPaths the projections to add.
          */
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")  // Projections available from getProjections
         @NonNull
         public SearchSpec.Builder addProjectionsForDocumentClass(
@@ -1001,6 +1066,7 @@
          *                      add projections to.
          * @param propertyPaths the projections to add.
          */
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")  // Projections available from getProjections
         @NonNull
         public SearchSpec.Builder addProjectionPathsForDocumentClass(
@@ -1020,13 +1086,13 @@
          * Sets the maximum number of results to return for each group, where groups are defined
          * by grouping type.
          *
-         * <p>Calling this method will override any previous calls. So calling
-         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 7) and then calling
-         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 2) will result in only the latter, a
-         * limit of two results per package, being applied. Or calling setResultGrouping
-         * (GROUPING_TYPE_PER_PACKAGE, 1) and then calling setResultGrouping
-         * (GROUPING_TYPE_PER_PACKAGE | GROUPING_PER_NAMESPACE, 5) will result in five results
-         * per package per namespace.
+         * <p>Calling this method will override any previous calls. So calling {@code
+         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 7)} and then calling {@code
+         * setResultGrouping(GROUPING_TYPE_PER_PACKAGE, 2)} will result in only the latter, a limit
+         * of two results per package, being applied. Or calling {@code setResultGrouping
+         * (GROUPING_TYPE_PER_PACKAGE, 1)} and then calling {@code setResultGrouping
+         * (GROUPING_TYPE_PER_PACKAGE | GROUPING_PER_NAMESPACE, 5)} will result in five results per
+         * package per namespace.
          *
          * @param groupingTypeFlags One or more combination of grouping types.
          * @param limit             Number of results to return per {@code groupingTypeFlags}.
@@ -1034,6 +1100,7 @@
          */
         // Individual parameters available from getResultGroupingTypeFlags and
         // getResultGroupingLimit
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setResultGrouping(@GroupingType int groupingTypeFlags, int limit) {
@@ -1076,6 +1143,7 @@
          * @throws IllegalArgumentException if a weight is equal to or less than 0.0.
          */
         // @exportToFramework:startStrip()
+        @CanIgnoreReturnValue
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
                 name = Features.SEARCH_SPEC_PROPERTY_WEIGHTS)
@@ -1110,6 +1178,7 @@
          * @param joinSpec a specification on how to perform the Join operation.
          */
         // @exportToFramework:startStrip()
+        @CanIgnoreReturnValue
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
                 name = Features.JOIN_SPEC_AND_QUALIFIED_ID)
@@ -1152,6 +1221,7 @@
          * @throws IllegalArgumentException if a weight is equal to or less than 0.0.
          */
         // @exportToFramework:startStrip()
+        @CanIgnoreReturnValue
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
                 name = Features.SEARCH_SPEC_PROPERTY_WEIGHTS)
@@ -1206,6 +1276,7 @@
          *                            classpath
          * @throws IllegalArgumentException if a weight is equal to or less than 0.0.
          */
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
@@ -1253,6 +1324,7 @@
          *                            classpath
          * @throws IllegalArgumentException if a weight is equal to or less than 0.0.
          */
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
@@ -1285,7 +1357,7 @@
         // @exportToFramework:endStrip()
         @NonNull
         public Builder setNumericSearchEnabled(boolean enabled) {
-            modifyEnabledFeature(Features.NUMERIC_SEARCH, enabled);
+            modifyEnabledFeature(FeatureConstants.NUMERIC_SEARCH, enabled);
             return this;
         }
 
@@ -1300,8 +1372,8 @@
          * verbatim search features within the query language that allows clients to search
          * using the verbatim string operator.
          *
-         * <p>Ex. The verbatim string operator '"foo/bar" OR baz' will ensure that 'foo/bar' is
-         * treated as a single 'verbatim' token.
+         * <p>For example, The verbatim string operator '"foo/bar" OR baz' will ensure that
+         * 'foo/bar' is treated as a single 'verbatim' token.
          */
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -1310,7 +1382,7 @@
         // @exportToFramework:endStrip()
         @NonNull
         public Builder setVerbatimSearchEnabled(boolean enabled) {
-            modifyEnabledFeature(Features.VERBATIM_SEARCH, enabled);
+            modifyEnabledFeature(FeatureConstants.VERBATIM_SEARCH, enabled);
             return this;
         }
 
@@ -1350,7 +1422,7 @@
         // @exportToFramework:endStrip()
         @NonNull
         public Builder setListFilterQueryLanguageEnabled(boolean enabled) {
-            modifyEnabledFeature(Features.LIST_FILTER_QUERY_LANGUAGE, enabled);
+            modifyEnabledFeature(FeatureConstants.LIST_FILTER_QUERY_LANGUAGE, enabled);
             return this;
         }
 
@@ -1399,9 +1471,11 @@
             bundle.putInt(RESULT_GROUPING_TYPE_FLAGS, mGroupingTypeFlags);
             bundle.putInt(RESULT_GROUPING_LIMIT, mGroupingLimit);
             if (!mTypePropertyWeights.isEmpty()
-                    && RANKING_STRATEGY_RELEVANCE_SCORE != mRankingStrategy) {
+                    && RANKING_STRATEGY_RELEVANCE_SCORE != mRankingStrategy
+                    && RANKING_STRATEGY_ADVANCED_RANKING_EXPRESSION != mRankingStrategy) {
                 throw new IllegalArgumentException("Property weights are only compatible with the "
-                        + "RANKING_STRATEGY_RELEVANCE_SCORE ranking strategy.");
+                        + "RANKING_STRATEGY_RELEVANCE_SCORE and "
+                        + "RANKING_STRATEGY_ADVANCED_RANKING_EXPRESSION ranking strategies.");
             }
             bundle.putBundle(TYPE_PROPERTY_WEIGHTS_FIELD, mTypePropertyWeights);
             bundle.putString(ADVANCED_RANKING_EXPRESSION, mAdvancedRankingExpression);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionResult.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionResult.java
index 2fea497..63fd696 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionResult.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionResult.java
@@ -21,13 +21,14 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.util.BundleUtil;
 import androidx.core.util.Preconditions;
 
 /**
  * The result class of the {@link AppSearchSession#searchSuggestionAsync}.
  */
-public class SearchSuggestionResult {
+public final class SearchSuggestionResult {
 
     private static final String SUGGESTED_RESULT_FIELD = "suggestedResult";
     private final Bundle mBundle;
@@ -41,7 +42,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -92,6 +93,7 @@
          *
          * <p>The suggested result should only contain lowercase or special characters.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSuggestedResult(@NonNull String suggestedResult) {
             Preconditions.checkNotNull(suggestedResult);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java
index b195591..4b87f9c 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SearchSuggestionSpec.java
@@ -15,7 +15,6 @@
  */
 
 package androidx.appsearch.app;
-import static androidx.appsearch.app.AppSearchResult.RESULT_INVALID_ARGUMENT;
 
 import android.annotation.SuppressLint;
 import android.os.Bundle;
@@ -24,6 +23,7 @@
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.annotation.Document;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.appsearch.util.BundleUtil;
@@ -45,9 +45,9 @@
  * This class represents the specification logic for AppSearch. It can be used to set the filter
  * and settings of search a suggestions.
  *
- * @see AppSearchSession#searchSuggestionAsync(String, SearchSuggestionSpec)
+ * @see AppSearchSession#searchSuggestionAsync
  */
-public class SearchSuggestionSpec {
+public final class SearchSuggestionSpec {
     static final String NAMESPACE_FIELD = "namespace";
     static final String SCHEMA_FIELD = "schema";
     static final String PROPERTY_FIELD = "property";
@@ -57,7 +57,7 @@
     private final Bundle mBundle;
     private final int mMaximumResultCount;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public SearchSuggestionSpec(@NonNull Bundle bundle) {
         Preconditions.checkNotNull(bundle);
@@ -70,7 +70,7 @@
     /**
      * Ranking Strategy for {@link SearchSuggestionResult}.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @IntDef(value = {
             SUGGESTION_RANKING_STRATEGY_NONE,
@@ -113,7 +113,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -143,7 +143,8 @@
     }
 
     /** Returns the ranking strategy. */
-    public @SuggestionRankingStrategy int getRankingStrategy() {
+    @SuggestionRankingStrategy
+    public int getRankingStrategy() {
         return mBundle.getInt(RANKING_STRATEGY_FIELD);
     }
 
@@ -173,7 +174,7 @@
      * <p>Calling this function repeatedly is inefficient. Prefer to retain the Map returned
      * by this function, rather than calling it multiple times.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     // TODO(b/228240987) migrate this API when we support property restrict for multiple terms
     @NonNull
@@ -222,7 +223,7 @@
         private Bundle mTypePropertyFilters = new Bundle();
         private Bundle mDocumentIds = new Bundle();
         private final int mTotalResultCount;
-        private @SuggestionRankingStrategy int mRankingStrategy =
+        @SuggestionRankingStrategy private int mRankingStrategy =
                 SUGGESTION_RANKING_STRATEGY_DOCUMENT_COUNT;
         private boolean mBuilt = false;
 
@@ -243,6 +244,7 @@
          *
          * <p>If unset, the query will search over all namespaces.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterNamespaces(@NonNull String... namespaces) {
             Preconditions.checkNotNull(namespaces);
@@ -256,6 +258,7 @@
          *
          * <p>If unset, the query will search over all namespaces.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterNamespaces(@NonNull Collection<String> namespaces) {
             Preconditions.checkNotNull(namespaces);
@@ -270,6 +273,7 @@
          * <p>The default value {@link #SUGGESTION_RANKING_STRATEGY_DOCUMENT_COUNT} will be used if
          * this method is never called.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setRankingStrategy(@SuggestionRankingStrategy int rankingStrategy) {
             Preconditions.checkArgumentInRange(rankingStrategy,
@@ -286,6 +290,7 @@
          *
          * <p>If unset, the query will search over all schema.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull String... schemaTypes) {
             Preconditions.checkNotNull(schemaTypes);
@@ -299,6 +304,7 @@
          *
          * <p>If unset, the query will search over all schema.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull Collection<String> schemaTypes) {
             Preconditions.checkNotNull(schemaTypes);
@@ -315,10 +321,12 @@
          *
          * <p>If unset, the query will search over all schema.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas()
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentClasses(@NonNull Class<?>... documentClasses)
                 throws AppSearchException {
@@ -337,10 +345,12 @@
          *
          * <p>If unset, the query will search over all schema.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentClasses(
                 @NonNull Collection<? extends Class<?>> documentClasses) throws AppSearchException {
@@ -375,7 +385,7 @@
          * @param propertyPaths The String version of {@link PropertyPath}. A dot-delimited
          *                      sequence of property names indicating which property in the
          *                      document these snippets correspond to.
-         * @hide
+         * @exportToFramework:hide
          */
         // TODO(b/228240987) migrate this API when we support property restrict for multiple terms
         @NonNull
@@ -409,7 +419,7 @@
          * @param schema the {@link AppSearchSchema} that contains the target properties
          * @param propertyPaths The {@link PropertyPath} to search suggestion over
          *
-         * @hide
+         * @exportToFramework:hide
          */
         // TODO(b/228240987) migrate this API when we support property restrict for multiple terms
         @NonNull
@@ -443,7 +453,7 @@
          * @param propertyPaths The String version of {@link PropertyPath}. A
          * {@code dot-delimited sequence of property names indicating which property in the
          * document these snippets correspond to.
-         * @hide
+         * @exportToFramework:hide
          */
         // TODO(b/228240987) migrate this API when we support property restrict for multiple terms
         @NonNull
@@ -474,7 +484,7 @@
          *
          * @param documentClass class annotated with {@link Document}.
          * @param propertyPaths The {@link PropertyPath} to search suggestion over
-         * @hide
+         * @exportToFramework:hide
          */
         // TODO(b/228240987) migrate this API when we support property restrict for multiple terms
         @NonNull
@@ -496,6 +506,7 @@
          *
          * <p>If unset, the query will search over all documents.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentIds(@NonNull String namespace,
                 @NonNull String... documentIds) {
@@ -511,6 +522,7 @@
          *
          * <p>If unset, the query will search over all documents.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentIds(@NonNull String namespace,
                 @NonNull Collection<String> documentIds) {
@@ -527,13 +539,13 @@
 
         /** Constructs a new {@link SearchSpec} from the contents of this builder. */
         @NonNull
-        public SearchSuggestionSpec build() throws AppSearchException {
+        public SearchSuggestionSpec build() {
             Bundle bundle = new Bundle();
             if (!mSchemas.isEmpty()) {
                 Set<String> schemaFilter = new ArraySet<>(mSchemas);
                 for (String schema : mTypePropertyFilters.keySet()) {
                     if (!schemaFilter.contains(schema)) {
-                        throw new AppSearchException(RESULT_INVALID_ARGUMENT,
+                        throw new IllegalStateException(
                                 "The schema: " + schema + " exists in the property filter but "
                                         + "doesn't exist in the schema filter.");
                     }
@@ -543,7 +555,7 @@
                 Set<String> namespaceFilter = new ArraySet<>(mNamespaces);
                 for (String namespace : mDocumentIds.keySet()) {
                     if (!namespaceFilter.contains(namespace)) {
-                        throw new AppSearchException(RESULT_INVALID_ARGUMENT,
+                        throw new IllegalStateException(
                                 "The namespace: " + namespace + " exists in the document id "
                                         + "filter but doesn't exist in the namespace filter.");
                     }
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
index 52e953a..e85171a 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaRequest.java
@@ -23,6 +23,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresFeature;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.exceptions.AppSearchException;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
@@ -76,7 +77,7 @@
  *         This deletes all documents that are incompatible with the new schema. The new schema is
  *         then saved and persisted to disk.
  *     <li>Add a {@link Migrator} for each incompatible type and make no deletion. The migrator
- *         will migrate documents from it's old schema version to the new version. Migrated types
+ *         will migrate documents from its old schema version to the new version. Migrated types
  *         will be set into both {@link SetSchemaResponse#getIncompatibleTypes()} and
  *         {@link SetSchemaResponse#getMigratedTypes()}. See the migration section below.
  * </ul>
@@ -90,7 +91,7 @@
      * {@link SetSchemaRequest.Builder#addRequiredPermissionsForSchemaTypeVisibility}
      *
      * @see android.Manifest.permission
-     * @hide
+     * @exportToFramework:hide
      */
     @IntDef(value = {
             READ_SMS,
@@ -279,7 +280,7 @@
      * modifiable map. This is not meant to be unhidden and should only be used by internal
      * classes.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -318,6 +319,7 @@
          *
          * <p>Any documents of these types will be displayed on system UI surfaces by default.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addSchemas(@NonNull AppSearchSchema... schemas) {
             Preconditions.checkNotNull(schemas);
@@ -330,6 +332,7 @@
          *
          * <p>An {@link AppSearchSchema} object represents one type of structured data.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addSchemas(@NonNull Collection<AppSearchSchema> schemas) {
             Preconditions.checkNotNull(schemas);
@@ -343,12 +346,15 @@
          * Adds one or more {@link androidx.appsearch.annotation.Document} annotated classes to the
          * schema.
          *
+         * <p>Merged list available from {@link #getSchemas()}.
+         *
          * @param documentClasses classes annotated with
          *                        {@link androidx.appsearch.annotation.Document}.
          * @throws AppSearchException if {@code androidx.appsearch.compiler.AppSearchCompiler}
          *                            has not generated a schema for the given document classes.
          */
-        @SuppressLint("MissingGetterMatchingBuilder")  // Merged list available from getSchemas()
+        @CanIgnoreReturnValue
+        @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder addDocumentClasses(@NonNull Class<?>... documentClasses)
                 throws AppSearchException {
@@ -361,12 +367,18 @@
          * Adds a collection of {@link androidx.appsearch.annotation.Document} annotated classes to
          * the schema.
          *
+         * <p>This will also add all {@link androidx.appsearch.annotation.Document} classes
+         * referenced by the schema via document properties.
+         *
+         * <p>Merged list available from {@link #getSchemas()}.
+         *
          * @param documentClasses classes annotated with
          *                        {@link androidx.appsearch.annotation.Document}.
          * @throws AppSearchException if {@code androidx.appsearch.compiler.AppSearchCompiler}
          *                            has not generated a schema for the given document classes.
          */
-        @SuppressLint("MissingGetterMatchingBuilder")  // Merged list available from getSchemas()
+        @CanIgnoreReturnValue
+        @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder addDocumentClasses(@NonNull Collection<? extends Class<?>> documentClasses)
                 throws AppSearchException {
@@ -377,6 +389,7 @@
             for (Class<?> documentClass : documentClasses) {
                 DocumentClassFactory<?> factory = registry.getOrCreateFactory(documentClass);
                 schemas.add(factory.getSchema());
+                addDocumentClasses(factory.getNestedDocumentClasses());
             }
             return addSchemas(schemas);
         }
@@ -397,6 +410,7 @@
          * @param displayed  Whether documents of this type will be displayed on system UI surfaces.
          */
         // Merged list available from getSchemasNotDisplayedBySystem
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setSchemaTypeDisplayedBySystem(
@@ -438,6 +452,7 @@
          * @throws IllegalArgumentException – if input unsupported permission.
          */
         // Merged list available from getRequiredPermissionsForSchemaTypeVisibility
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         // @exportToFramework:startStrip()
         @RequiresFeature(
@@ -465,6 +480,7 @@
 
         /**  Clears all required permissions combinations for the given schema type.  */
         // @exportToFramework:startStrip()
+        @CanIgnoreReturnValue
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
                 name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
@@ -498,6 +514,7 @@
          * @param packageIdentifier Represents the package that will be granted visibility.
          */
         // Merged list available from getSchemasVisibleToPackages
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setSchemaTypeVisibilityForPackage(
@@ -553,6 +570,7 @@
          * @see SetSchemaRequest.Builder#addSchemas
          * @see AppSearchSession#setSchemaAsync
          */
+        @CanIgnoreReturnValue
         @NonNull
         @SuppressLint("MissingGetterMatchingBuilder")        // Getter return plural objects.
         public Builder setMigrator(@NonNull String schemaType, @NonNull Migrator migrator) {
@@ -580,7 +598,7 @@
          * {@link Migrator#onUpgrade} or {@link Migrator#onDowngrade} must exist in this
          * {@link SetSchemaRequest}.
          *
-         * @param migrators  A {@link Map} of migrators that translate a document from it's current
+         * @param migrators  A {@link Map} of migrators that translate a document from its current
          *                   version to the final version set via {@link #setVersion}. The key of
          *                   the map is the schema type that the {@link Migrator} value applies to.
          *
@@ -588,6 +606,7 @@
          * @see SetSchemaRequest.Builder#addSchemas
          * @see AppSearchSession#setSchemaAsync
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setMigrators(@NonNull Map<String, Migrator> migrators) {
             Preconditions.checkNotNull(migrators);
@@ -610,6 +629,8 @@
          * <p>The default behavior, if this method is not called, is to allow types to be
          * displayed on system UI surfaces.
          *
+         * <p> Merged list available from {@link #getSchemasNotDisplayedBySystem()}.
+         *
          * @param documentClass A class annotated with
          *                      {@link androidx.appsearch.annotation.Document}, the visibility of
          *                      which will be configured
@@ -618,7 +639,7 @@
          * @throws AppSearchException if {@code androidx.appsearch.compiler.AppSearchCompiler}
          *                            has not generated a schema for the given document class.
          */
-        // Merged list available from getSchemasNotDisplayedBySystem
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setDocumentClassDisplayedBySystem(@NonNull Class<?> documentClass,
@@ -647,6 +668,8 @@
          *
          * <p>By default, app data sharing between applications is disabled.
          *
+         * <p>Merged list available from {@link #getSchemasVisibleToPackages()}.
+         *
          * @param documentClass     The {@link androidx.appsearch.annotation.Document} class to set
          *                          visibility on.
          * @param visible           Whether the {@code documentClass} will be visible or not.
@@ -654,7 +677,7 @@
          * @throws AppSearchException if {@code androidx.appsearch.compiler.AppSearchCompiler}
          *                            has not generated a schema for the given document class.
          */
-        // Merged list available from getSchemasVisibleToPackages
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @NonNull
         public Builder setDocumentClassVisibilityForPackage(@NonNull Class<?> documentClass,
@@ -682,6 +705,7 @@
          * {@link #READ_CONTACTS}, {@link #READ_EXTERNAL_STORAGE},
          * {@link #READ_HOME_APP_SEARCH_DATA} and {@link #READ_ASSISTANT_APP_SEARCH_DATA}.
          *
+         * <p>Merged map available from {@link #getRequiredPermissionsForSchemaTypeVisibility()}.
          * @see android.Manifest.permission#READ_SMS
          * @see android.Manifest.permission#READ_CALENDAR
          * @see android.Manifest.permission#READ_CONTACTS
@@ -695,7 +719,7 @@
          *                         schema.
          * @throws IllegalArgumentException – if input unsupported permission.
          */
-        // Merged map available from getRequiredPermissionsForSchemaTypeVisibility
+        @CanIgnoreReturnValue
         @SuppressLint("MissingGetterMatchingBuilder")
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
@@ -714,6 +738,7 @@
         }
 
         /**  Clears all required permissions combinations for the given schema type.  */
+        @CanIgnoreReturnValue
         @RequiresFeature(
                 enforcement = "androidx.appsearch.app.Features#isFeatureSupported",
                 name = Features.ADD_PERMISSIONS_AND_GET_VISIBILITY)
@@ -740,6 +765,7 @@
          *
          * <p>By default, this is {@code false}.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setForceOverride(boolean forceOverride) {
             resetIfBuilt();
@@ -775,6 +801,7 @@
          * @see Migrator
          * @see SetSchemaRequest.Builder#setMigrator
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVersion(@IntRange(from = 1) int version) {
             Preconditions.checkArgument(version >= 1, "Version must be a positive number.");
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
index 3f8ce5e..07d087a 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/SetSchemaResponse.java
@@ -21,6 +21,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
@@ -74,7 +75,7 @@
 
     /**
      * Returns the {@link Bundle} populated by this builder.
-     * @hide
+     * @exportToFramework:hide
      */
     @NonNull
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -160,7 +161,7 @@
 
     /**
      * Translates the {@link SetSchemaResponse}'s bundle to {@link Builder}.
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -182,6 +183,7 @@
         private boolean mBuilt = false;
 
         /**  Adds {@link MigrationFailure}s to the list of migration failures. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addMigrationFailures(
                 @NonNull Collection<MigrationFailure> migrationFailures) {
@@ -192,6 +194,7 @@
         }
 
         /**  Adds a {@link MigrationFailure} to the list of migration failures. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addMigrationFailure(@NonNull MigrationFailure migrationFailure) {
             Preconditions.checkNotNull(migrationFailure);
@@ -200,7 +203,8 @@
             return this;
         }
 
-        /**  Adds deletedTypes to the list of deleted schema types. */
+        /**  Adds {@code deletedTypes} to the list of deleted schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addDeletedTypes(@NonNull Collection<String> deletedTypes) {
             Preconditions.checkNotNull(deletedTypes);
@@ -209,7 +213,8 @@
             return this;
         }
 
-        /**  Adds one deletedType to the list of deleted schema types. */
+        /**  Adds one {@code deletedType} to the list of deleted schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addDeletedType(@NonNull String deletedType) {
             Preconditions.checkNotNull(deletedType);
@@ -218,7 +223,8 @@
             return this;
         }
 
-        /**  Adds incompatibleTypes to the list of incompatible schema types. */
+        /**  Adds {@code incompatibleTypes} to the list of incompatible schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIncompatibleTypes(@NonNull Collection<String> incompatibleTypes) {
             Preconditions.checkNotNull(incompatibleTypes);
@@ -227,7 +233,8 @@
             return this;
         }
 
-        /**  Adds one incompatibleType to the list of incompatible schema types. */
+        /**  Adds one {@code incompatibleType} to the list of incompatible schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addIncompatibleType(@NonNull String incompatibleType) {
             Preconditions.checkNotNull(incompatibleType);
@@ -236,7 +243,8 @@
             return this;
         }
 
-        /**  Adds migratedTypes to the list of migrated schema types. */
+        /**  Adds {@code migratedTypes} to the list of migrated schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addMigratedTypes(@NonNull Collection<String> migratedTypes) {
             Preconditions.checkNotNull(migratedTypes);
@@ -245,7 +253,8 @@
             return this;
         }
 
-        /**  Adds one migratedType to the list of migrated schema types. */
+        /**  Adds one {@code migratedType} to the list of migrated schema types. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addMigratedType(@NonNull String migratedType) {
             Preconditions.checkNotNull(migratedType);
@@ -325,7 +334,7 @@
         /**
          * Returns the Bundle of the {@link MigrationFailure}.
          *
-         * @hide
+         * @exportToFramework:hide
          */
         @NonNull
         @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/StorageInfo.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/StorageInfo.java
index 0d7901d..d95eff6 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/StorageInfo.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/StorageInfo.java
@@ -20,6 +20,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.core.util.Preconditions;
 
 /** The response class of {@code AppSearchSession#getStorageInfo}. */
@@ -37,7 +38,7 @@
 
     /**
      * Returns the {@link Bundle} populated by this builder.
-     * @hide
+     * @exportToFramework:hide
      */
     @NonNull
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -78,6 +79,7 @@
         private int mAliveNamespacesCount;
 
         /** Sets the size in bytes. */
+        @CanIgnoreReturnValue
         @NonNull
         public StorageInfo.Builder setSizeBytes(long sizeBytes) {
             mSizeBytes = sizeBytes;
@@ -85,6 +87,7 @@
         }
 
         /** Sets the number of alive documents. */
+        @CanIgnoreReturnValue
         @NonNull
         public StorageInfo.Builder setAliveDocumentsCount(int aliveDocumentsCount) {
             mAliveDocumentsCount = aliveDocumentsCount;
@@ -92,6 +95,7 @@
         }
 
         /** Sets the number of alive namespaces. */
+        @CanIgnoreReturnValue
         @NonNull
         public StorageInfo.Builder setAliveNamespacesCount(int aliveNamespacesCount) {
             mAliveNamespacesCount = aliveNamespacesCount;
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
index fd79bd6..f794752 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
@@ -20,6 +20,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArraySet;
 import androidx.core.util.Preconditions;
 
@@ -31,12 +32,12 @@
 
 /**
  * Holds the visibility settings that apply to a schema type.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityDocument extends GenericDocument {
     /**
-     * The Schema type for documents that hold AppSearch's metadata, e.g. visibility settings.
+     * The Schema type for documents that hold AppSearch's metadata, such as visibility settings.
      */
     public static final String SCHEMA_TYPE = "VisibilityType";
     /** Namespace of documents that contain visibility settings */
@@ -162,6 +163,7 @@
         }
 
         /** Sets whether this schema has opted out of platform surfacing. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setNotDisplayedBySystem(boolean notDisplayedBySystem) {
             return setPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY,
@@ -169,6 +171,7 @@
         }
 
         /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addVisibleToPackages(@NonNull Set<PackageIdentifier> packageIdentifiers) {
             Preconditions.checkNotNull(packageIdentifiers);
@@ -177,6 +180,7 @@
         }
 
         /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addVisibleToPackage(@NonNull PackageIdentifier packageIdentifier) {
             Preconditions.checkNotNull(packageIdentifier);
@@ -185,12 +189,13 @@
         }
 
         /**
-         * Set required permission sets for a package needs to hold to the schema this
+         * Sets required permission sets for a package needs to hold to the schema this
          * {@link VisibilityDocument} represents.
          *
          * <p> The querier could have access if they holds ALL required permissions of ANY of the
          * individual value sets.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVisibleToPermissions(@NonNull Set<Set<Integer>> visibleToPermissions) {
             Preconditions.checkNotNull(visibleToPermissions);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
index e859cb9..80a6a2e 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
@@ -19,6 +19,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.collection.ArraySet;
 
 import java.util.Set;
@@ -26,13 +27,13 @@
 /**
  * The nested document that holds all required permissions for a caller need to hold to access the
  * schema which the outer {@link VisibilityDocument} represents.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class VisibilityPermissionDocument extends GenericDocument {
 
     /**
-     * The Schema type for documents that hold AppSearch's metadata, e.g. visibility settings.
+     * The Schema type for documents that hold AppSearch's metadata, such as visibility settings.
      */
     public static final String SCHEMA_TYPE = "VisibilityPermissionType";
 
@@ -76,6 +77,7 @@
         }
 
         /** Sets whether this schema has opted out of platform surfacing. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setVisibleToAllRequiredPermissions(
                 @NonNull Set<Integer> allRequiredPermissions) {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/AppSearchException.java b/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/AppSearchException.java
index 98689f5..2930d2d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/AppSearchException.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/AppSearchException.java
@@ -73,7 +73,8 @@
      *
      * @return One of the constants documented in {@link AppSearchResult#getResultCode}.
      */
-    public @AppSearchResult.ResultCode int getResultCode() {
+    @AppSearchResult.ResultCode
+    public int getResultCode() {
         return mResultCode;
     }
 
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/IllegalSchemaException.java b/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/IllegalSchemaException.java
index 7aeb861..e73d0d0 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/IllegalSchemaException.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/exceptions/IllegalSchemaException.java
@@ -23,7 +23,7 @@
  * Indicates that a {@link androidx.appsearch.app.AppSearchSchema} has logical inconsistencies such
  * as unpopulated mandatory fields or illegal combinations of parameters.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class IllegalSchemaException extends IllegalArgumentException {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java
deleted file mode 100644
index c01917e..0000000
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/AppSearchObserverCallback.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.appsearch.observer;
-
-import androidx.annotation.RestrictTo;
-
-/**
- * @deprecated use {@link ObserverCallback} instead.
- * @hide
- */
-// TODO(b/209734214): Remove this after dogfooders and devices have migrated away from this class.
-@Deprecated
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public interface AppSearchObserverCallback extends ObserverCallback {}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
index 1fc52a0..8aede0f 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/DocumentChangeInfo.java
@@ -27,8 +27,8 @@
 /**
  * Contains information about an individual change detected by an {@link ObserverCallback}.
  *
- * <p>This class reports information about document changes, i.e. when documents were added, updated
- * or removed.
+ * <p>This class reports information about document changes, that is, when documents were added,
+ * updated or removed.
  *
  * <p>Changes are grouped by package, database, schema type and namespace. Each unique
  * combination of these items will generate a unique {@link DocumentChangeInfo}.
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
index 6e3705e..903929b 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/observer/ObserverSpec.java
@@ -22,6 +22,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.annotation.Document;
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.DocumentClassFactoryRegistry;
@@ -49,7 +50,7 @@
     @Nullable
     private volatile Set<String> mFilterSchemas;
 
-    /** @hide */
+    /** @exportToFramework:hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     public ObserverSpec(@NonNull Bundle bundle) {
         Preconditions.checkNotNull(bundle);
@@ -59,7 +60,7 @@
     /**
      * Returns the {@link Bundle} backing this spec.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -85,7 +86,7 @@
         return mFilterSchemas;
     }
 
-    /** Builder for ObserverSpec instances. */
+    /** Builder for {@link ObserverSpec} instances. */
     public static final class Builder {
         private ArrayList<String> mFilterSchemas = new ArrayList<>();
         private boolean mBuilt = false;
@@ -96,6 +97,7 @@
          *
          * <p>If unset, the observer will match documents of all types.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull String... schemas) {
             Preconditions.checkNotNull(schemas);
@@ -109,6 +111,7 @@
          *
          * <p>If unset, the observer will match documents of all types.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterSchemas(@NonNull Collection<String> schemas) {
             Preconditions.checkNotNull(schemas);
@@ -124,10 +127,12 @@
          *
          * <p>If unset, the observer will match documents of all types.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas()
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentClasses(@NonNull Class<?>... documentClasses)
                 throws AppSearchException {
@@ -142,10 +147,12 @@
          *
          * <p>If unset, the observer will match documents of all types.
          *
+         * <p>Merged list available from {@link #getFilterSchemas()}.
+         *
          * @param documentClasses classes annotated with {@link Document}.
          */
-        // Merged list available from getFilterSchemas
         @SuppressLint("MissingGetterMatchingBuilder")
+        @CanIgnoreReturnValue
         @NonNull
         public Builder addFilterDocumentClasses(
                 @NonNull Collection<? extends Class<?>> documentClasses) throws AppSearchException {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java b/appsearch/appsearch/src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java
index 3cff1133..5c3a226 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/stats/SchemaMigrationStats.java
@@ -21,6 +21,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 import androidx.appsearch.app.AppSearchResult;
 import androidx.appsearch.app.SetSchemaRequest;
 import androidx.appsearch.util.BundleUtil;
@@ -32,7 +33,7 @@
 /**
  * Class holds detailed stats for Schema migration.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SchemaMigrationStats {
@@ -91,7 +92,7 @@
     /**
      * Returns the {@link Bundle} populated by this builder.
      *
-     * @hide
+     * @exportToFramework:hide
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @NonNull
@@ -220,6 +221,7 @@
         }
 
         /** Sets status code for the schema migration action. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
             mBundle.putInt(STATUS_CODE_FIELD, statusCode);
@@ -227,6 +229,7 @@
         }
 
         /** Sets the latency for waiting the executor. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setExecutorAcquisitionLatencyMillis(int executorAcquisitionLatencyMillis) {
             mBundle.putInt(EXECUTOR_ACQUISITION_MILLIS_FIELD, executorAcquisitionLatencyMillis);
@@ -235,6 +238,7 @@
 
 
         /** Sets total latency for the schema migration action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalLatencyMillis(int totalLatencyMillis) {
             mBundle.putInt(TOTAL_LATENCY_MILLIS_FIELD, totalLatencyMillis);
@@ -242,6 +246,7 @@
         }
 
         /** Sets latency for the GetSchema action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setGetSchemaLatencyMillis(int getSchemaLatencyMillis) {
             mBundle.putInt(GET_SCHEMA_LATENCY_MILLIS_FIELD, getSchemaLatencyMillis);
@@ -252,6 +257,7 @@
          * Sets latency for querying all documents that need to be migrated to new version and
          * transforming documents to new version in milliseconds.
          */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setQueryAndTransformLatencyMillis(
                 int queryAndTransformLatencyMillis) {
@@ -261,6 +267,7 @@
         }
 
         /** Sets latency of first SetSchema action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setFirstSetSchemaLatencyMillis(
                 int firstSetSchemaLatencyMillis) {
@@ -269,6 +276,7 @@
         }
 
         /** Returns status of the first SetSchema action. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setIsFirstSetSchemaSuccess(boolean isFirstSetSchemaSuccess) {
             mBundle.putBoolean(IS_FIRST_SET_SCHEMA_SUCCESS_FIELD, isFirstSetSchemaSuccess);
@@ -276,6 +284,7 @@
         }
 
         /** Sets latency of second SetSchema action in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSecondSetSchemaLatencyMillis(
                 int secondSetSchemaLatencyMillis) {
@@ -284,6 +293,7 @@
         }
 
         /** Sets latency for putting migrated document to Icing lib in milliseconds. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setSaveDocumentLatencyMillis(
                 int saveDocumentLatencyMillis) {
@@ -292,6 +302,7 @@
         }
 
         /** Sets number of document that need to be migrated to another version. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalNeedMigratedDocumentCount(int migratedDocumentCount) {
             mBundle.putInt(TOTAL_NEED_MIGRATED_DOCUMENT_COUNT_FIELD, migratedDocumentCount);
@@ -299,6 +310,7 @@
         }
 
         /** Sets total document count of successfully migrated and saved in Icing. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setTotalSuccessMigratedDocumentCount(
                 int totalSuccessMigratedDocumentCount) {
@@ -308,6 +320,7 @@
         }
 
         /** Sets number of {@link androidx.appsearch.app.SetSchemaResponse.MigrationFailure}. */
+        @CanIgnoreReturnValue
         @NonNull
         public Builder setMigrationFailureCount(int migrationFailureCount) {
             mBundle.putInt(MIGRATION_FAILURE_COUNT_FIELD, migrationFailureCount);
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/util/BundleUtil.java b/appsearch/appsearch/src/main/java/androidx/appsearch/util/BundleUtil.java
index 1f8ad68b..573ae7d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/util/BundleUtil.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/util/BundleUtil.java
@@ -29,7 +29,7 @@
 
 /**
  * Utilities for working with {@link android.os.Bundle}.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class BundleUtil {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/util/IndentingStringBuilder.java b/appsearch/appsearch/src/main/java/androidx/appsearch/util/IndentingStringBuilder.java
index ea5717e..58fc75b 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/util/IndentingStringBuilder.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/util/IndentingStringBuilder.java
@@ -18,6 +18,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
+import androidx.appsearch.annotation.CanIgnoreReturnValue;
 
 /**
  * Utility for building indented strings.
@@ -28,7 +29,7 @@
  *
  * <p>Indentation is applied after each newline character for the given indent level.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public class IndentingStringBuilder {
@@ -41,6 +42,7 @@
     /**
      * Increases the indent level by one for appended strings.
      */
+    @CanIgnoreReturnValue
     @NonNull
     public IndentingStringBuilder increaseIndentLevel() {
         mIndentLevel++;
@@ -50,6 +52,7 @@
     /**
      * Decreases the indent level by one for appended strings.
      */
+    @CanIgnoreReturnValue
     @NonNull
     public IndentingStringBuilder decreaseIndentLevel() throws IllegalStateException {
         if (mIndentLevel == 0) {
@@ -64,6 +67,7 @@
      *
      * <p>Indentation is applied after each newline character.
      */
+    @CanIgnoreReturnValue
     @NonNull
     public IndentingStringBuilder append(@NonNull String str) {
         applyIndentToString(str);
@@ -76,6 +80,7 @@
      *
      * <p>Indentation is applied after each newline character.
      */
+    @CanIgnoreReturnValue
     @NonNull
     public IndentingStringBuilder append(@NonNull Object obj) {
         applyIndentToString(obj.toString());
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/util/LogUtil.java b/appsearch/appsearch/src/main/java/androidx/appsearch/util/LogUtil.java
index 2392374..cc52cdd 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/util/LogUtil.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/util/LogUtil.java
@@ -25,7 +25,7 @@
 
 /**
  * Utilities for logging to logcat.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class LogUtil {
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/util/SchemaMigrationUtil.java b/appsearch/appsearch/src/main/java/androidx/appsearch/util/SchemaMigrationUtil.java
index 8fbbd61..b157c6d 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/util/SchemaMigrationUtil.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/util/SchemaMigrationUtil.java
@@ -34,7 +34,7 @@
 
 /**
  * Utilities for schema migration.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 public final class SchemaMigrationUtil {
diff --git a/appsearch/compiler/lint-baseline.xml b/appsearch/compiler/lint-baseline.xml
deleted file mode 100644
index 6b8f42c..0000000
--- a/appsearch/compiler/lint-baseline.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class DocumentModel {"
-        errorLine2="      ~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/compiler/DocumentModel.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class IntrospectionHelper {"
-        errorLine2="      ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="final class MissingTypeException extends Exception {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/compiler/MissingTypeException.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="final class ProcessingException extends Exception {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/appsearch/compiler/ProcessingException.java"/>
-    </issue>
-
-</issues>
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
index 2b6ebcc..9e0cd1bc 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/DocumentModel.java
@@ -52,7 +52,7 @@
 /**
  * Processes @Document annotations.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 class DocumentModel {
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
index 31d5e55..5d08981 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/IntrospectionHelper.java
@@ -50,7 +50,7 @@
 /**
  * Utilities for working with data structures representing parsed Java code.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 class IntrospectionHelper {
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/MissingTypeException.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/MissingTypeException.java
index 918038f..bf13716 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/MissingTypeException.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/MissingTypeException.java
@@ -25,7 +25,7 @@
  * An exception thrown from the appsearch annotation processor to indicate a type element is not
  * found due to it being possibly generated at a later annotation processing round.
  *
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 final class MissingTypeException extends Exception {
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/ProcessingException.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/ProcessingException.java
index 0e5bfd4..d1bd836 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/ProcessingException.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/ProcessingException.java
@@ -28,7 +28,7 @@
 
 /**
  * An exception thrown from the appsearch annotation processor to indicate something went wrong.
- * @hide
+ * @exportToFramework:hide
  */
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 final class ProcessingException extends Exception {
diff --git a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
index a80f718..5adef09 100644
--- a/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
+++ b/appsearch/compiler/src/main/java/androidx/appsearch/compiler/SchemaCodeGenerator.java
@@ -22,11 +22,15 @@
 import com.squareup.javapoet.CodeBlock;
 import com.squareup.javapoet.FieldSpec;
 import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
 import com.squareup.javapoet.TypeName;
 import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.WildcardTypeName;
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.AnnotationMirror;
@@ -43,6 +47,7 @@
     private final ProcessingEnvironment mEnv;
     private final IntrospectionHelper mHelper;
     private final DocumentModel mModel;
+    private final Set<ClassName> mDocumentTypesAccumulator = new HashSet<>();
 
     public static void generate(
             @NonNull ProcessingEnvironment env,
@@ -73,17 +78,55 @@
                         .addStatement("return SCHEMA_NAME")
                         .build());
 
+        CodeBlock schemaInitializer = createSchemaInitializerGetDocumentTypes();
+
         classBuilder.addMethod(
                 MethodSpec.methodBuilder("getSchema")
                         .addModifiers(Modifier.PUBLIC)
                         .returns(mHelper.getAppSearchClass("AppSearchSchema"))
                         .addAnnotation(Override.class)
                         .addException(mHelper.getAppSearchExceptionClass())
-                        .addStatement("return $L", createSchemaInitializer())
+                        .addStatement("return $L", schemaInitializer)
                         .build());
+
+        classBuilder.addMethod(createNestedClassesMethod());
     }
 
-    private CodeBlock createSchemaInitializer() throws ProcessingException {
+    @NonNull
+    private MethodSpec createNestedClassesMethod() {
+        TypeName setOfClasses = ParameterizedTypeName.get(ClassName.get("java.util", "List"),
+                ParameterizedTypeName.get(ClassName.get(Class.class),
+                        WildcardTypeName.subtypeOf(Object.class)));
+
+        TypeName arraySetOfClasses =
+                ParameterizedTypeName.get(ClassName.get("java.util", "ArrayList"),
+                        ParameterizedTypeName.get(ClassName.get(Class.class),
+                                WildcardTypeName.subtypeOf(Object.class)));
+
+        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("getNestedDocumentClasses")
+                .addModifiers(Modifier.PUBLIC)
+                .returns(setOfClasses)
+                .addAnnotation(Override.class)
+                .addException(mHelper.getAppSearchExceptionClass());
+
+        if (mDocumentTypesAccumulator.isEmpty()) {
+            methodBuilder.addStatement("return $T.emptyList()",
+                    ClassName.get("java.util", "Collections"));
+        } else {
+            methodBuilder.addStatement("$T classSet = new $T()", setOfClasses, arraySetOfClasses);
+            for (ClassName className : mDocumentTypesAccumulator) {
+                methodBuilder.addStatement("classSet.add($T.class)", className);
+            }
+            methodBuilder.addStatement("return classSet").build();
+        }
+        return methodBuilder.build();
+    }
+
+    /**
+     * This method accumulates Document-type properties in mDocumentTypesAccumulator by calling
+     * {@link #createPropertySchema}.
+     */
+    private CodeBlock createSchemaInitializerGetDocumentTypes() throws ProcessingException {
         CodeBlock.Builder codeBlock = CodeBlock.builder()
                 .add("new $T(SCHEMA_NAME)", mHelper.getAppSearchClass("AppSearchSchema", "Builder"))
                 .indent();
@@ -94,6 +137,7 @@
         return codeBlock.build();
     }
 
+    /** This method accumulates Document-type properties in mDocumentTypesAccumulator. */
     private CodeBlock createPropertySchema(@NonNull VariableElement property)
             throws ProcessingException {
         AnnotationMirror annotation = mModel.getPropertyAnnotation(property);
@@ -166,6 +210,7 @@
                     propertyClass.nestedClass("Builder"),
                     propertyName,
                     documentFactoryClass);
+            mDocumentTypesAccumulator.add(documentClass);
         } else {
             codeBlock.add("new $T($S)", propertyClass.nestedClass("Builder"), propertyName);
         }
@@ -227,6 +272,28 @@
             }
             codeBlock.add("\n.setIndexingType($T)", indexingEnum);
 
+            int joinableValueType = Integer.parseInt(params.get("joinableValueType").toString());
+            ClassName joinableEnum;
+            if (joinableValueType == 0) { // JOINABLE_VALUE_TYPE_NONE
+                joinableEnum = mHelper.getAppSearchClass(
+                        "AppSearchSchema", "StringPropertyConfig", "JOINABLE_VALUE_TYPE_NONE");
+
+            } else if (joinableValueType == 1) { // JOINABLE_VALUE_TYPE_QUALIFIED_ID
+                if (repeated) {
+                    throw new ProcessingException(
+                            "Joinable value type " + joinableValueType + " not allowed on repeated "
+                                    + "properties.", property);
+
+                }
+                joinableEnum = mHelper.getAppSearchClass(
+                        "AppSearchSchema", "StringPropertyConfig",
+                        "JOINABLE_VALUE_TYPE_QUALIFIED_ID");
+            } else {
+                throw new ProcessingException(
+                        "Unknown joinable value type " + joinableValueType, property);
+            }
+            codeBlock.add("\n.setJoinableValueType($T)", joinableEnum);
+
         } else if (isPropertyDocument) {
             if (params.containsKey("indexNestedProperties")) {
                 boolean indexNestedProperties = Boolean.parseBoolean(
diff --git a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
index b36c5877..43e24214 100644
--- a/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
+++ b/appsearch/compiler/src/test/java/androidx/appsearch/compiler/AppSearchCompilerTest.java
@@ -1190,6 +1190,38 @@
     }
 
     @Test
+    public void testStringPropertyJoinableType() throws Exception {
+        Compilation compilation = compile(
+                "import java.util.*;\n"
+                        + "@Document\n"
+                        + "public class Gift {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty(joinableValueType=1)\n"
+                        + "  String object;\n"
+                        + "}\n");
+
+        assertThat(compilation).succeededWithoutWarnings();
+        checkEqualsGolden("Gift.java");
+    }
+
+    @Test
+    public void testRepeatedPropertyJoinableType_throwsError() throws Exception {
+        Compilation compilation = compile(
+                "import java.util.*;\n"
+                        + "@Document\n"
+                        + "public class Gift {\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.StringProperty(joinableValueType=1)\n"
+                        + "  List<String> object;\n"
+                        + "}\n");
+
+        assertThat(compilation).hadErrorContaining(
+                "Joinable value type 1 not allowed on repeated properties.");
+    }
+
+    @Test
     public void testPropertyName() throws Exception {
         Compilation compilation = compile(
                 "import java.util.*;\n"
@@ -1504,6 +1536,44 @@
         checkEqualsGolden("Gift.java");
     }
 
+    @Test
+    public void testMultipleNesting() throws Exception {
+        Compilation compilation = compile(
+                "import java.util.*;\n"
+                        + "@Document\n"
+                        + "public class Gift {\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.DocumentProperty Middle middleContentA;\n"
+                        + "  @Document.DocumentProperty Middle middleContentB;\n"
+                        + "}\n"
+                        + "\n"
+                        + "@Document\n"
+                        + "class Middle {\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.DocumentProperty Inner innerContentA;\n"
+                        + "  @Document.DocumentProperty Inner innerContentB;\n"
+                        + "}\n"
+                        + "@Document\n"
+                        + "class Inner {\n"
+                        + "  @Document.Id String id;\n"
+                        + "  @Document.Namespace String namespace;\n"
+                        + "  @Document.StringProperty String contents;\n"
+                        + "}\n");
+
+        assertThat(compilation).succeededWithoutWarnings();
+        checkEqualsGolden("Gift.java");
+
+        // Check that Gift contains Middle, Middle contains Inner, and Inner returns empty
+        checkResultContains(/* className= */ "Gift.java",
+                /* content= */ "classSet.add(Middle.class);\n    return classSet;");
+        checkResultContains(/* className= */ "Middle.java",
+                /* content= */ "classSet.add(Inner.class);\n    return classSet;");
+        checkResultContains(/* className= */ "Inner.java",
+                /* content= */ "return Collections.emptyList();");
+    }
+
     private Compilation compile(String classBody) {
         return compile("Gift", classBody);
     }
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSingleTypes.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSingleTypes.JAVA
index 094d178..a49931b 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSingleTypes.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSingleTypes.JAVA
@@ -5,12 +5,15 @@
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
 import java.lang.Boolean;
+import java.lang.Class;
 import java.lang.Double;
 import java.lang.Float;
 import java.lang.Integer;
 import java.lang.Long;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -29,6 +32,7 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.LongPropertyConfig.Builder("integerProp")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -54,6 +58,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_field.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_field.JAVA
index 36930bc1..3f9ad76 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_field.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_field.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_getter.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_getter.JAVA
index 35fdea2..1d97d08 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_getter.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAllSpecialFields_getter.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.getId(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
index ab783ed..fc27579 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testAutoValueDocument.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,17 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace(), document.id(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testCardinality.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testCardinality.JAVA
index 0f275a7..d7954e1 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testCardinality.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testCardinality.JAVA
@@ -4,10 +4,12 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Float;
 import java.lang.Override;
 import java.lang.String;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.processing.Generated;
 
@@ -27,11 +29,13 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("repeatNoReq")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.DoublePropertyConfig.Builder("req")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
@@ -43,6 +47,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testDifferentTypeName.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testDifferentTypeName.JAVA
index 7a7bca6..eb8b33b 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testDifferentTypeName.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testDifferentTypeName.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,6 +27,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testGetterAndSetterFunctions_withFieldName.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testGetterAndSetterFunctions_withFieldName.JAVA
index aa566b3..3096bdc 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testGetterAndSetterFunctions_withFieldName.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testGetterAndSetterFunctions_withFieldName.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexingType.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexingType.JAVA
index 810a16f..acad761 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexingType.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testIndexingType.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,21 +27,29 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("indexExact")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("indexPrefix")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testInnerClass.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testInnerClass.JAVA
index ac333bc..d55520d 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testInnerClass.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testInnerClass.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,17 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift.InnerGift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testLongPropertyIndexingType.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testLongPropertyIndexingType.JAVA
index c754aef..abe3acb 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testLongPropertyIndexingType.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testLongPropertyIndexingType.JAVA
@@ -4,10 +4,13 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Integer;
 import java.lang.Long;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -66,6 +69,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA
index 31c563e..856821f 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNestedAutoValueDocument.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,6 +27,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift.A document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace(), document.id(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNesting.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNesting.JAVA
new file mode 100644
index 0000000..7d8acd0
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testMultipleNesting.JAVA
@@ -0,0 +1,82 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Gift implements DocumentClassFactory<Gift> {
+  public static final String SCHEMA_NAME = "Gift";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("middleContentA", $$__AppSearch__Middle.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .build())
+          .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("middleContentB", $$__AppSearch__Middle.SCHEMA_NAME)
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setShouldIndexNestedProperties(false)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Middle.class);
+    return classSet;
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    Middle middleContentACopy = document.middleContentA;
+    if (middleContentACopy != null) {
+      GenericDocument middleContentAConv = GenericDocument.fromDocumentClass(middleContentACopy);
+      builder.setPropertyDocument("middleContentA", middleContentAConv);
+    }
+    Middle middleContentBCopy = document.middleContentB;
+    if (middleContentBCopy != null) {
+      GenericDocument middleContentBConv = GenericDocument.fromDocumentClass(middleContentBCopy);
+      builder.setPropertyDocument("middleContentB", middleContentBConv);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Gift fromGenericDocument(GenericDocument genericDoc) throws AppSearchException {
+    String idConv = genericDoc.getId();
+    String namespaceConv = genericDoc.getNamespace();
+    GenericDocument middleContentACopy = genericDoc.getPropertyDocument("middleContentA");
+    Middle middleContentAConv = null;
+    if (middleContentACopy != null) {
+      middleContentAConv = middleContentACopy.toDocumentClass(Middle.class);
+    }
+    GenericDocument middleContentBCopy = genericDoc.getPropertyDocument("middleContentB");
+    Middle middleContentBConv = null;
+    if (middleContentBCopy != null) {
+      middleContentBConv = middleContentBCopy.toDocumentClass(Middle.class);
+    }
+    Gift document = new Gift();
+    document.id = idConv;
+    document.namespace = namespaceConv;
+    document.middleContentA = middleContentAConv;
+    document.middleContentB = middleContentBConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testNestedDocumentsIndexing.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testNestedDocumentsIndexing.JAVA
index c31f620..b24a19b 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testNestedDocumentsIndexing.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testNestedDocumentsIndexing.JAVA
@@ -4,6 +4,7 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
 import java.util.ArrayList;
@@ -51,6 +52,13 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(GiftContent.class);
+    return classSet;
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testOneBadConstructor.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testOneBadConstructor.JAVA
index f0d8cb5..f3cca50 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testOneBadConstructor.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testOneBadConstructor.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,6 +27,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.getNamespace(), document.getId(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testPropertyName.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testPropertyName.JAVA
index f6672c0..2a730d5 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testPropertyName.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testPropertyName.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,17 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_MultipleGetters.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_MultipleGetters.JAVA
index f07c03b..44d3db6 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_MultipleGetters.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_MultipleGetters.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_isGetterForBoolean.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_isGetterForBoolean.JAVA
index 9e828fd..a676f5c 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_isGetterForBoolean.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRead_isGetterForBoolean.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -27,6 +30,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRepeatedFields.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRepeatedFields.JAVA
index f46d524..89b7dbb 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRepeatedFields.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testRepeatedFields.JAVA
@@ -4,12 +4,14 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Integer;
 import java.lang.Override;
 import java.lang.String;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import javax.annotation.processing.Generated;
 
@@ -29,6 +31,7 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.LongPropertyConfig.Builder("setOfInt")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
@@ -44,6 +47,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testStringPropertyJoinableType.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testStringPropertyJoinableType.JAVA
new file mode 100644
index 0000000..722ebf59
--- /dev/null
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testStringPropertyJoinableType.JAVA
@@ -0,0 +1,66 @@
+package com.example.appsearch;
+
+import androidx.appsearch.app.AppSearchSchema;
+import androidx.appsearch.app.DocumentClassFactory;
+import androidx.appsearch.app.GenericDocument;
+import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
+import java.lang.Override;
+import java.lang.String;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.processing.Generated;
+
+@Generated("androidx.appsearch.compiler.AppSearchCompiler")
+public final class $$__AppSearch__Gift implements DocumentClassFactory<Gift> {
+  public static final String SCHEMA_NAME = "Gift";
+
+  @Override
+  public String getSchemaName() {
+    return SCHEMA_NAME;
+  }
+
+  @Override
+  public AppSearchSchema getSchema() throws AppSearchException {
+    return new AppSearchSchema.Builder(SCHEMA_NAME)
+          .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("object")
+            .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+            .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
+            .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID)
+            .build())
+          .build();
+  }
+
+  @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
+  public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
+    GenericDocument.Builder<?> builder =
+        new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
+    String objectCopy = document.object;
+    if (objectCopy != null) {
+      builder.setPropertyString("object", objectCopy);
+    }
+    return builder.build();
+  }
+
+  @Override
+  public Gift fromGenericDocument(GenericDocument genericDoc) throws AppSearchException {
+    String idConv = genericDoc.getId();
+    String namespaceConv = genericDoc.getNamespace();
+    String[] objectCopy = genericDoc.getPropertyStringArray("object");
+    String objectConv = null;
+    if (objectCopy != null && objectCopy.length != 0) {
+      objectConv = objectCopy[0];
+    }
+    Gift document = new Gift();
+    document.namespace = namespaceConv;
+    document.id = idConv;
+    document.object = objectConv;
+    return document;
+  }
+}
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuccessSimple.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuccessSimple.JAVA
index de3177f..c30c660 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuccessSimple.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuccessSimple.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -34,6 +37,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass.JAVA
index ef1410d..9694ee2 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,13 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("sender")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder("foo")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -37,6 +42,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift.FooGift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassPojoAncestor.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassPojoAncestor.JAVA
index f51fa57..8f600f6 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassPojoAncestor.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassPojoAncestor.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,13 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("sender")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder("foo")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -37,6 +42,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift.FooGift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassWithPrivateFields.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassWithPrivateFields.JAVA
index 3fed9e3..d7feadb 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassWithPrivateFields.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClassWithPrivateFields.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,21 +27,29 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("receiver")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("sender")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.getNamespace(), document.getId(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_changeSchemaName.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_changeSchemaName.JAVA
index 812463a..08e306c 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_changeSchemaName.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_changeSchemaName.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,16 +27,23 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("sender")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_multipleChangedSchemaNames.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_multipleChangedSchemaNames.JAVA
index b77c03b..ac5dcb2 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_multipleChangedSchemaNames.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testSuperClass_multipleChangedSchemaNames.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,11 +27,13 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("sender")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.BooleanPropertyConfig.Builder("foo")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -37,6 +42,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(FooGift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testToGenericDocument_allSupportedTypes.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testToGenericDocument_allSupportedTypes.JAVA
index d7e9290..0643cf9 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testToGenericDocument_allSupportedTypes.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testToGenericDocument_allSupportedTypes.JAVA
@@ -6,6 +6,7 @@
 import androidx.appsearch.exceptions.AppSearchException;
 import java.lang.Boolean;
 import java.lang.Byte;
+import java.lang.Class;
 import java.lang.Double;
 import java.lang.Float;
 import java.lang.Integer;
@@ -54,6 +55,7 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("collectGift", $$__AppSearch__Gift.SCHEMA_NAME)
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
@@ -103,6 +105,7 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder("arrGift", $$__AppSearch__Gift.SCHEMA_NAME)
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
@@ -112,6 +115,7 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.LongPropertyConfig.Builder("boxLong")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -158,6 +162,13 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    List<Class<?>> classSet = new ArrayList<Class<?>>();
+    classSet.add(Gift.class);
+    return classSet;
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testTokenizerType.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testTokenizerType.JAVA
index 678c212..15e72e7 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testTokenizerType.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testTokenizerType.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -24,66 +27,83 @@
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokPlainInvalid")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokVerbatimInvalid")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokRfc822Invalid")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokNone")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokPlain")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokVerbatim")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_VERBATIM)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokRfc822")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_RFC822)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokNonePrefix")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokPlainPrefix")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokVerbatimPrefix")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_VERBATIM)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .addProperty(new AppSearchSchema.StringPropertyConfig.Builder("tokRfc822Prefix")
             .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
             .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_RFC822)
             .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+            .setJoinableValueType(AppSearchSchema.StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE)
             .build())
           .build();
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleConventions.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleConventions.JAVA
index b7f69fc..cea4e5d 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleConventions.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleConventions.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -40,6 +43,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.getId(), SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleSetters.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleSetters.JAVA
index f07c03b..44d3db6 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleSetters.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_multipleSetters.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_usableFactoryMethod_unusableConstructor.JAVA b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_usableFactoryMethod_unusableConstructor.JAVA
index 34c2b72..e356243 100644
--- a/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_usableFactoryMethod_unusableConstructor.JAVA
+++ b/appsearch/compiler/src/test/resources/androidx/appsearch/compiler/goldens/testWrite_usableFactoryMethod_unusableConstructor.JAVA
@@ -4,8 +4,11 @@
 import androidx.appsearch.app.DocumentClassFactory;
 import androidx.appsearch.app.GenericDocument;
 import androidx.appsearch.exceptions.AppSearchException;
+import java.lang.Class;
 import java.lang.Override;
 import java.lang.String;
+import java.util.Collections;
+import java.util.List;
 import javax.annotation.processing.Generated;
 
 @Generated("androidx.appsearch.compiler.AppSearchCompiler")
@@ -28,6 +31,11 @@
   }
 
   @Override
+  public List<Class<?>> getNestedDocumentClasses() throws AppSearchException {
+    return Collections.emptyList();
+  }
+
+  @Override
   public GenericDocument toGenericDocument(Gift document) throws AppSearchException {
     GenericDocument.Builder<?> builder =
         new GenericDocument.Builder<>(document.namespace, document.id, SCHEMA_NAME);
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/apptarget/BaselineProfileAppTargetPlugin.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/apptarget/BaselineProfileAppTargetPlugin.kt
index 7a257dd..d3327bb 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/apptarget/BaselineProfileAppTargetPlugin.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/apptarget/BaselineProfileAppTargetPlugin.kt
@@ -22,8 +22,10 @@
 import androidx.baselineprofile.gradle.utils.AgpPluginId
 import androidx.baselineprofile.gradle.utils.BUILD_TYPE_BASELINE_PROFILE_PREFIX
 import androidx.baselineprofile.gradle.utils.BUILD_TYPE_BENCHMARK_PREFIX
+import androidx.baselineprofile.gradle.utils.Dependencies
 import androidx.baselineprofile.gradle.utils.MAX_AGP_VERSION_REQUIRED
 import androidx.baselineprofile.gradle.utils.MIN_AGP_VERSION_REQUIRED
+import androidx.baselineprofile.gradle.utils.camelCase
 import androidx.baselineprofile.gradle.utils.copyBuildTypeSources
 import androidx.baselineprofile.gradle.utils.createExtendedBuildTypes
 import com.android.build.api.AndroidPluginVersion
@@ -53,12 +55,27 @@
     maxAgpVersion = MAX_AGP_VERSION_REQUIRED
 ) {
 
-    private val benchmarkExtendedToOriginalTypeMap = mutableMapOf<String, String>()
-    private val baselineProfileExtendedToOriginalTypeMap = mutableMapOf<String, String>()
-
     private val ApplicationExtension.debugSigningConfig
         get() = buildTypes.getByName("debug").signingConfig
 
+    private val dependencies = Dependencies(project)
+
+    // Benchmark build type to the original ones. Ex: benchmarkRelease -> release
+    private val benchmarkExtendedToOriginalTypeMap = mutableMapOf<String, String>()
+
+    // This is the opposite. Ex: release -> benchmarkRelease
+    private val benchmarkOriginalToExtendedTypeMap by lazy {
+        benchmarkExtendedToOriginalTypeMap.toList().associate { Pair(it.second, it.first) }
+    }
+
+    // Baseline Profile build type to the original ones. Ex: nonMinifiedRelease -> release
+    private val baselineProfileExtendedToOriginalTypeMap = mutableMapOf<String, String>()
+
+    // This is the opposite. Ex: release -> nonMinifiedRelease
+    private val baselineProfileOriginalToExtendedTypeMap by lazy {
+        baselineProfileExtendedToOriginalTypeMap.toList().associate { Pair(it.second, it.first) }
+    }
+
     override fun onAgpPluginNotFound(pluginIds: Set<AgpPluginId>) {
 
         // If no supported plugin was found throw an exception.
@@ -109,6 +126,55 @@
 
     override fun onApplicationVariants(variant: ApplicationVariant) {
 
+        // Extending the build type won't also copy the build type specific dependencies, that
+        // need to be copied separately for both baseline profile and benchmark variants.
+        // Note that the maps used here are organized like: `release` -> `nonMinifiedRelease` and
+        // `release` -> `benchmark`.
+        data class MappingAndPrefix(val mapping: Map<String, String>, val prefix: String)
+        listOf(
+            MappingAndPrefix(
+                baselineProfileOriginalToExtendedTypeMap,
+                BUILD_TYPE_BASELINE_PROFILE_PREFIX
+            ),
+            MappingAndPrefix(
+                benchmarkOriginalToExtendedTypeMap,
+                BUILD_TYPE_BENCHMARK_PREFIX
+            ),
+        ).forEach {
+            if (variant.buildType !in it.mapping.keys) {
+                return@forEach
+            }
+
+            // This would be, for example, `release`.
+            val originalBuildTypeName = variant.buildType
+                ?: throw IllegalStateException(
+                    // Note that this exception cannot happen due to user configuration.
+                    "Variant `${variant.name}` does not have a build type."
+                )
+
+            // This would be, for example, `nonMinifiedRelease`.
+            val extendedBuildTypeName = it.mapping[originalBuildTypeName]
+                ?: throw IllegalStateException(
+                    // Note that this exception cannot happen due to user configuration.
+                    "Build type `${variant.buildType}` was not extended."
+                )
+
+            // Copy build type specific dependencies
+            dependencies.copy(
+                fromPrefix = originalBuildTypeName,
+                toPrefix = extendedBuildTypeName
+            )
+
+            // Copy variant specific dependencies
+            dependencies.copy(
+                fromPrefix = variant.name,
+                toPrefix = camelCase(variant.flavorName ?: "", extendedBuildTypeName)
+            )
+
+            // Note that we don't need to copy flavor specific dependencies because they're applied
+            // to all the build types, including the extended ones.
+        }
+
         // This behavior is only for AGP 8.0: since we cannot support multiple build types in the
         // same gradle invocation (including `assemble` or `build` due to b/265438201), we use a
         // single build type for both benchmark and baseline profile in the producer module.
@@ -119,10 +185,10 @@
             variant.buildType in baselineProfileExtendedToOriginalTypeMap.keys
         ) {
             variant.proguardFiles.add(
-                GenerateKeepRulesForBaselineProfilesTask.maybeRegister(project)
+                GenerateKeepRulesForBaselineProfilesTask
+                    .maybeRegister(project)
                     .flatMap { it.keepRuleFile }
             )
-            return
         }
     }
 
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/Dependencies.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/Dependencies.kt
new file mode 100644
index 0000000..963770b
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/Dependencies.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.baselineprofile.gradle.utils
+
+import org.gradle.api.Project
+
+internal class Dependencies(private val project: Project) {
+
+    private val defaultConfigurationsToCopy = listOf(
+        "implementation",
+        "api",
+        "kapt",
+        "annotationProcessor",
+        "compile",
+        "compileOnly"
+    )
+
+    fun copy(
+        fromPrefix: String,
+        toPrefix: String,
+        configurationsToCopy: List<String> = defaultConfigurationsToCopy
+    ) {
+        configurationsToCopy.forEach { configurationName ->
+
+            val fromVariantConfigurationName = camelCase(fromPrefix, configurationName)
+            val fromVariantDependencies = project
+                .configurations
+                .findByName(fromVariantConfigurationName)
+                ?.dependencies
+                ?: return@forEach
+
+            val toVariantConfigurationName = camelCase(toPrefix, configurationName)
+            val toVariantDependencies = project
+                .configurations
+                .findByName(toVariantConfigurationName)
+                ?.dependencies
+                ?: return@forEach
+
+            toVariantDependencies.addAll(fromVariantDependencies)
+        }
+    }
+}
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
index a6d70de..c015ad6 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
@@ -1020,6 +1020,9 @@
             """.trimIndent(),
             buildTypesBlock = "",
             dependencyOnProducerProject = false,
+            dependenciesBlock = """
+                implementation(project(":${projectSetup.dependency.name}"))
+            """.trimIndent(),
             baselineProfileBlock = """
                 variants {
                     free { from(project(":${projectSetup.producer.name}")) }
@@ -1129,6 +1132,131 @@
                 )
         }
     }
+
+    @Test
+    fun testVariantSpecificDependencies() {
+        projectSetup.producer.setupWithoutFlavors(
+            releaseProfileLines = listOf(
+                Fixtures.CLASS_1_METHOD_1,
+                Fixtures.CLASS_1
+            )
+        )
+        projectSetup.consumer.setup(
+            androidPlugin = ANDROID_APPLICATION_PLUGIN,
+            dependenciesBlock = """
+               releaseImplementation(project(":${projectSetup.dependency.name}"))
+            """.trimIndent()
+        )
+        gradleRunner.build("generateReleaseBaselineProfile", "--stacktrace") {
+            assertThat(readBaselineProfileFileContent("release"))
+                .containsExactly(
+                    Fixtures.CLASS_1_METHOD_1,
+                    Fixtures.CLASS_1
+                )
+        }
+    }
+
+    @Test
+    fun testVariantSpecificDependenciesWithFlavorsAndMultipleBuildTypes() {
+        projectSetup.consumer.setupWithBlocks(
+            androidPlugin = ANDROID_APPLICATION_PLUGIN,
+            flavorsBlock = """
+                flavorDimensions = ["tier"]
+                free { dimension "tier" }
+                paid { dimension "tier" }
+            """.trimIndent(),
+            buildTypesBlock = """
+                anotherRelease { initWith(release) }
+            """.trimIndent(),
+            dependencyOnProducerProject = true,
+            dependenciesBlock = """
+                releaseImplementation(project(":${projectSetup.dependency.name}"))
+                anotherReleaseImplementation(project(":${projectSetup.dependency.name}"))
+            """.trimIndent(),
+        )
+        projectSetup.producer.setup(
+            variantProfiles = listOf(
+                VariantProfile(
+                    flavorDimensions = mapOf("tier" to "free"),
+                    buildType = "release",
+                    profileFileLines = mapOf(
+                        "test-output-baseline-free-release" to listOf(
+                            Fixtures.CLASS_1_METHOD_1,
+                            Fixtures.CLASS_1
+                        )
+                    ),
+                    startupFileLines = mapOf()
+                ),
+                VariantProfile(
+                    flavorDimensions = mapOf("tier" to "paid"),
+                    buildType = "release",
+                    profileFileLines = mapOf(
+                        "test-output-baseline-paid-release" to listOf(
+                            Fixtures.CLASS_2_METHOD_1,
+                            Fixtures.CLASS_2
+                        )
+                    ),
+                    startupFileLines = mapOf()
+                ),
+                VariantProfile(
+                    flavorDimensions = mapOf("tier" to "free"),
+                    buildType = "anotherRelease",
+                    profileFileLines = mapOf(
+                        "test-output-baseline-free-anotherRelease" to listOf(
+                            Fixtures.CLASS_3_METHOD_1,
+                            Fixtures.CLASS_3
+                        )
+                    ),
+                    startupFileLines = mapOf()
+                ),
+                VariantProfile(
+                    flavorDimensions = mapOf("tier" to "paid"),
+                    buildType = "anotherRelease",
+                    profileFileLines = mapOf(
+                        "test-output-baseline-paid-anotherRelease" to listOf(
+                            Fixtures.CLASS_4_METHOD_1,
+                            Fixtures.CLASS_4
+                        )
+                    ),
+                    startupFileLines = mapOf()
+                ),
+            )
+        )
+
+        data class Expected(val variantName: String, val profileLines: List<String>)
+        arrayOf(
+            Expected(
+                variantName = "freeRelease",
+                profileLines = listOf(
+                    Fixtures.CLASS_1_METHOD_1,
+                    Fixtures.CLASS_1
+                )
+            ),
+            Expected(
+                variantName = "paidRelease", profileLines = listOf(
+                    Fixtures.CLASS_2_METHOD_1,
+                    Fixtures.CLASS_2
+                )
+            ),
+            Expected(
+                variantName = "freeAnotherRelease", profileLines = listOf(
+                    Fixtures.CLASS_3_METHOD_1,
+                    Fixtures.CLASS_3
+                )
+            ),
+            Expected(
+                variantName = "paidAnotherRelease", profileLines = listOf(
+                    Fixtures.CLASS_4_METHOD_1,
+                    Fixtures.CLASS_4
+                )
+            ),
+        ).forEach { expected ->
+            gradleRunner.build(camelCase("generate", expected.variantName, "baselineProfile")) {
+                assertThat(readBaselineProfileFileContent(expected.variantName))
+                    .containsExactlyElementsIn(expected.profileLines)
+            }
+        }
+    }
 }
 
 @RunWith(JUnit4::class)
@@ -1535,6 +1663,9 @@
             otherPluginsBlock = """
                 id("org.jetbrains.kotlin.multiplatform")
             """.trimIndent(),
+            dependenciesBlock = """
+                implementation(project(":${projectSetup.dependency.name}"))
+            """.trimIndent(),
             additionalGradleCodeBlock = """
                 kotlin {
                     jvm { }
@@ -1580,6 +1711,9 @@
             otherPluginsBlock = """
                 id("org.jetbrains.kotlin.multiplatform")
             """.trimIndent(),
+            dependenciesBlock = """
+                implementation(project(":${projectSetup.dependency.name}"))
+            """.trimIndent(),
             additionalGradleCodeBlock = """
                 kotlin {
                     jvm { }
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
index 2994b57..7900dc7 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/utils/BaselineProfileProjectSetupRule.kt
@@ -64,7 +64,8 @@
         ConsumerModule(
             rule = consumerSetupRule,
             name = consumerName,
-            producerName = producerName
+            producerName = producerName,
+            dependencyName = dependencyName
         )
     }
 
@@ -80,6 +81,15 @@
         )
     }
 
+    /**
+     * Represents a simple java library dependency module.
+     */
+    val dependency by lazy {
+        DependencyModule(
+            name = dependencyName
+        )
+    }
+
     // Temp folder for temp generated files that need to be referenced by a module.
     private val tempFolder by lazy { File(rootFolder.root, "temp").apply { mkdirs() } }
 
@@ -87,6 +97,7 @@
     private val appTargetSetupRule by lazy { ProjectSetupRule(rootFolder.root) }
     private val consumerSetupRule by lazy { ProjectSetupRule(rootFolder.root) }
     private val producerSetupRule by lazy { ProjectSetupRule(rootFolder.root) }
+    private val dependencySetupRule by lazy { ProjectSetupRule(rootFolder.root) }
 
     // Module names (generated automatically)
     private val appTargetName: String by lazy {
@@ -98,11 +109,15 @@
     private val producerName: String by lazy {
         producerSetupRule.rootDir.relativeTo(rootFolder.root).name
     }
+    private val dependencyName: String by lazy {
+        dependencySetupRule.rootDir.relativeTo(rootFolder.root).name
+    }
 
     override fun apply(base: Statement, description: Description): Statement {
         return RuleChain
             .outerRule(appTargetSetupRule)
             .around(producerSetupRule)
+            .around(dependencySetupRule)
             .around(consumerSetupRule)
             .around { b, _ -> applyInternal(b) }
             .apply(base, description)
@@ -130,6 +145,7 @@
                 """
                 include '$appTargetName'
                 include '$producerName'
+                include '$dependencyName'
                 include '$consumerName'
             """.trimIndent()
             )
@@ -188,11 +204,12 @@
             mapOf(
                 "app-target" to appTargetSetupRule,
                 "consumer" to consumerSetupRule,
-                "producer" to producerSetupRule
+                "producer" to producerSetupRule,
+                "dependency" to dependencySetupRule,
             ).forEach { (folder, project) ->
                 File("src/test/test-data", folder)
                     .apply { deleteOnExit() }
-                    .copyRecursively(project.rootDir)
+                    .copyRecursively(project.rootDir, overwrite = true)
             }
 
             base.evaluate()
@@ -244,6 +261,10 @@
         )
 }
 
+class DependencyModule(
+    val name: String,
+)
+
 class AppTargetModule(
     override val rule: ProjectSetupRule,
     override val name: String,
@@ -539,12 +560,16 @@
 class ConsumerModule(
     override val rule: ProjectSetupRule,
     override val name: String,
-    private val producerName: String
+    private val producerName: String,
+    private val dependencyName: String,
 ) : Module {
 
     fun setup(
         androidPlugin: String,
         flavors: Boolean = false,
+        dependenciesBlock: String = """
+            implementation(project(":$dependencyName"))
+        """.trimIndent(),
         dependencyOnProducerProject: Boolean = true,
         buildTypeAnotherRelease: Boolean = false,
         addAppTargetPlugin: Boolean = androidPlugin == ANDROID_APPLICATION_PLUGIN,
@@ -559,6 +584,7 @@
                 paid { dimension "version" }
             """.trimIndent() else "",
         dependencyOnProducerProject = dependencyOnProducerProject,
+        dependenciesBlock = dependenciesBlock,
         buildTypesBlock = if (buildTypeAnotherRelease) """
                 anotherRelease { initWith(release) }
         """.trimIndent() else "",
@@ -572,18 +598,12 @@
         otherPluginsBlock: String = "",
         flavorsBlock: String = "",
         buildTypesBlock: String = "",
+        dependenciesBlock: String = "",
         dependencyOnProducerProject: Boolean = true,
         addAppTargetPlugin: Boolean = androidPlugin == ANDROID_APPLICATION_PLUGIN,
         baselineProfileBlock: String = "",
         additionalGradleCodeBlock: String = "",
     ) {
-        val dependencyOnProducerProjectBlock = """
-            dependencies {
-                baselineProfile(project(":$producerName"))
-            }
-
-        """.trimIndent()
-
         setBuildGradle(
             """
                 plugins {
@@ -610,7 +630,11 @@
             }
                 }
 
-               ${if (dependencyOnProducerProject) dependencyOnProducerProjectBlock else ""}
+                dependencies {
+                    ${if (dependencyOnProducerProject) """baselineProfile(project(":$producerName"))""" else ""}
+                    $dependenciesBlock
+
+                }
 
                 baselineProfile {
                     $baselineProfileBlock
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/resources/robolectric.properties b/benchmark/baseline-profile-gradle-plugin/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/test-data/consumer/src/main/java/com/test/consumer/SomeCode.java b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/consumer/src/main/java/com/test/consumer/SomeCode.java
new file mode 100644
index 0000000..abcd20e
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/consumer/src/main/java/com/test/consumer/SomeCode.java
@@ -0,0 +1,8 @@
+package com.test.consumer;
+
+public class SomeCode {
+
+    public void doSomething() {
+        com.test.dependency.SomeObject.doSomething();
+    }
+}
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/build.gradle b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/build.gradle
new file mode 100644
index 0000000..b600092
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/build.gradle
@@ -0,0 +1,3 @@
+plugins {
+    id("java-library")
+}
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/AndroidManifest.xml b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..337cbe4
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  Copyright 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/java/com/test/dependency/SomeObject.java b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/java/com/test/dependency/SomeObject.java
new file mode 100644
index 0000000..8cf0d1f
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/test-data/dependency/src/main/java/com/test/dependency/SomeObject.java
@@ -0,0 +1,5 @@
+package com.test.dependency;
+
+public class SomeObject {
+    public static void doSomething() { }
+}
diff --git a/benchmark/benchmark-common/build.gradle b/benchmark/benchmark-common/build.gradle
index 3c5a408..5a8f737 100644
--- a/benchmark/benchmark-common/build.gradle
+++ b/benchmark/benchmark-common/build.gradle
@@ -37,6 +37,19 @@
         )
     }
     namespace "androidx.benchmark"
+    defaultConfig {
+        externalNativeBuild {
+            cmake {
+                cppFlags ''
+            }
+        }
+    }
+    externalNativeBuild {
+        cmake {
+            path file('src/main/cpp/CMakeLists.txt')
+            version libs.versions.cmake.get()
+        }
+    }
 }
 
 wire {
@@ -56,7 +69,7 @@
     api("androidx.annotation:annotation:1.1.0")
     api("androidx.annotation:annotation-experimental:1.0.0")
     implementation("androidx.tracing:tracing-ktx:1.0.0")
-    implementation(project(":tracing:tracing-perfetto-common"))
+    implementation(project(":tracing:tracing-perfetto-handshake"))
     implementation(libs.testMonitor)
     implementation(libs.wireRuntime)
 
diff --git a/benchmark/benchmark-common/lint-baseline.xml b/benchmark/benchmark-common/lint-baseline.xml
deleted file mode 100644
index cf93700..0000000
--- a/benchmark/benchmark-common/lint-baseline.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="            Thread.sleep(TimeUnit.SECONDS.toMillis(sleepSeconds))"
-        errorLine2="                   ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/BenchmarkState.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(CONNECTED_PROFILING_SLEEP_MS)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/Profiler.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(CONNECTED_PROFILING_SLEEP_MS)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/Profiler.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(CONNECTED_PROFILING_SLEEP_MS)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/Profiler.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(CONNECTED_PROFILING_SLEEP_MS)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/Profiler.kt"/>
-    </issue>
-
-</issues>
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/CpuCounterTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/CpuCounterTest.kt
new file mode 100644
index 0000000..61f29ec
--- /dev/null
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/CpuCounterTest.kt
@@ -0,0 +1,183 @@
+/*
+ * 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.benchmark
+
+import android.os.Build
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import kotlin.test.assertFailsWith
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
+class CpuCounterTest {
+    private val perfHardenProp = PropOverride("security.perf_harden", "0")
+    private var shouldResetEnforce1 = false
+
+    @Before
+    fun before() {
+        // TODO: make this automatic
+        if (Build.VERSION.SDK_INT > 29) {
+            val blockedBySelinux = Shell.isSELinuxEnforced()
+            assumeTrue(
+                "blocked by selinux = $blockedBySelinux, rooted = ${DeviceInfo.isRooted}",
+                !blockedBySelinux || DeviceInfo.isRooted
+            )
+            if (blockedBySelinux && DeviceInfo.isRooted) {
+                Shell.executeScriptSilent("setenforce 0")
+                shouldResetEnforce1 = true
+            }
+            perfHardenProp.forceValue()
+        }
+        val error = CpuCounter.checkPerfEventSupport()
+        assumeTrue(error, error == null)
+    }
+
+    @After
+    fun after() {
+        perfHardenProp.resetIfOverridden()
+        if (shouldResetEnforce1) {
+            Shell.executeScriptSilent("setenforce 1")
+        }
+    }
+
+    /**
+     * Extremely basic validation of CPU counters.
+     *
+     * Note that we don't try and do more advanced validation (e.g. ensuring
+     * instructions != cycles != l1 misses), since this may be brittle.
+     */
+    @Test
+    fun basic() = CpuCounter().use { counter ->
+        val values = CpuCounter.Values()
+
+        counter.resetEvents(
+            listOf(
+                CpuCounter.Event.Instructions,
+                CpuCounter.Event.CpuCycles,
+                CpuCounter.Event.L1IReferences,
+            )
+        )
+        counter.reset()
+        counter.start()
+        repeat(100) {
+            System.nanoTime() // just something to do
+        }
+        counter.stop()
+
+        counter.read(values)
+
+        // NOTE: these expected number of counters may not be safe, will adjust as
+        // needed based on CI results
+        if (DeviceInfo.isEmulator) {
+            assertTrue(
+                values.numberOfCounters >= 1,
+                "expect at least one counter enabled on emulator," +
+                    " saw ${values.numberOfCounters}"
+            )
+        } else {
+            assertTrue(
+                values.numberOfCounters >= 3,
+                "expect at least three counters on physical device," +
+                    " saw ${values.numberOfCounters}"
+            )
+        }
+        assertNotEquals(0, values.timeEnabled)
+        assertNotEquals(0, values.timeRunning)
+        assertTrue(values.timeEnabled >= values.timeRunning)
+
+        // As counters are enabled in order of ID, these are in order of ID as well
+        if (values.numberOfCounters >= 1) {
+            assertNotEquals(0, values.getValue(CpuCounter.Event.Instructions))
+        }
+        if (values.numberOfCounters >= 2) {
+            assertNotEquals(0, values.getValue(CpuCounter.Event.CpuCycles))
+        }
+        if (values.numberOfCounters >= 3) {
+            assertNotEquals(0, values.getValue(CpuCounter.Event.L1IMisses))
+        }
+    }
+
+    @Test
+    fun instructions() = CpuCounter().use { counter ->
+        val values = CpuCounter.Values()
+
+        counter.resetEvents(
+            listOf(
+                CpuCounter.Event.Instructions,
+                CpuCounter.Event.CpuCycles,
+                CpuCounter.Event.L1IReferences
+            )
+        )
+
+        val instructions = List(4) {
+            counter.reset()
+            counter.start()
+
+            // factor chosen because small numbers will cause test to fail on an emulator,
+            // likely due to warmup
+            repeat(it * 100) {
+                // Simple work designed to have minimum amount of Java code
+                System.nanoTime()
+            }
+            counter.stop()
+            counter.read(values)
+            values.getValue(CpuCounter.Event.Instructions)
+        }
+
+        assertTrue(instructions.all { it != 0L })
+
+        // note, we don't validate 1st, in case there's some amount of warmup happening
+        assertTrue(
+            instructions[3] > instructions[2] && instructions[2] > instructions[1],
+            "expected increasing instruction counts (ignoring 1st): ${instructions.joinToString()}"
+        )
+    }
+
+    @Test
+    fun read_withoutReset(): Unit = CpuCounter().use { counter ->
+        val values = CpuCounter.Values()
+
+        // not yet reset, should fail...
+        assertFailsWith<IllegalStateException> {
+            counter.read(values)
+        }.also { ise ->
+            assertTrue(ise.message!!.contains("read counters without reset"))
+        }
+    }
+
+    @Test
+    fun read_afterClose(): Unit = CpuCounter().use { counter ->
+        val values = CpuCounter.Values()
+        // reset, but closed / deleted, should fail...
+        counter.resetEvents(listOf(CpuCounter.Event.Instructions))
+        counter.close()
+        assertFailsWith<IllegalStateException> {
+            counter.read(values)
+        }.also { ise ->
+            assertTrue(ise.message!!.contains("read counters after close"))
+        }
+    }
+}
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricCaptureTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricCaptureTest.kt
index ddf728b..7fa4f14 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricCaptureTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricCaptureTest.kt
@@ -18,21 +18,22 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import kotlin.test.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-public class AllocationCountCaptureTest {
+class MetricCaptureTest {
     @Test
-    public fun simple() {
+    fun allocationCountCapture_simple() {
         AllocationCountCapture().verifyMedian(100..110) {
             allocate(100)
         }
     }
 
     @Test
-    public fun pauseResume() {
+    fun allocationCountCapture_pauseResume() {
         AllocationCountCapture().verifyMedian(100..110) {
             allocate(100)
 
@@ -50,12 +51,15 @@
  * This is done to reduce variance, e.g. from random background allocations
  */
 private fun MetricCapture.verifyMedian(expected: IntRange, block: MetricCapture.() -> Unit) {
+    assertEquals(1, names.size)
+    val longArray = longArrayOf(0L)
     val results = List(200) {
         captureStart(System.nanoTime())
         block()
-        captureStop(System.nanoTime()) * 1.0
+        captureStop(System.nanoTime(), longArray, 0)
+        longArray[0] * 1.0
     }
-    val median = MetricResult(name, results).median.toInt()
+    val median = MetricResult(names[0], results).median.toInt()
     if (median !in expected) {
         throw AssertionError(
             "observed median $median, expected $expected, saw: " + results.joinToString()
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricsContainerTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricsContainerTest.kt
new file mode 100644
index 0000000..81efcfa
--- /dev/null
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/MetricsContainerTest.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.benchmark
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import kotlin.test.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MetricsContainerTest {
+    internal class TestMetricCapture(
+        names: List<String>,
+        private val data: List<LongArray>
+    ) : MetricCapture(names) {
+        private var repeatIndex = 0
+
+        override fun captureStart(timeNs: Long) {}
+        override fun capturePaused() {}
+        override fun captureResumed() {}
+
+        override fun captureStop(timeNs: Long, output: LongArray, offset: Int) {
+            data[repeatIndex].copyInto(output, offset)
+            repeatIndex++
+        }
+    }
+
+    @Test
+    fun basic() {
+        val container = MetricsContainer(
+            arrayOf(
+                TestMetricCapture(
+                    names = listOf("foo", "bar"), data = listOf(
+                        longArrayOf(0, 6),
+                        longArrayOf(2, 8),
+                        longArrayOf(4, 10)
+                    )
+                )
+            ),
+            repeatCount = 3
+        )
+        container.captureInit()
+        repeat(3) {
+            container.captureStart()
+            container.captureStop()
+        }
+        assertEquals(
+            listOf(
+                MetricResult("foo", listOf(0.0, 1.0, 2.0)),
+                MetricResult("bar", listOf(3.0, 4.0, 5.0))
+            ),
+            container.captureFinished(2) // divide measurements by 2
+        )
+    }
+
+    @Test
+    fun multiMetricCapture() {
+        val container = MetricsContainer(
+            arrayOf(
+                TestMetricCapture(
+                    names = listOf("foo", "bar"), data = listOf(
+                        longArrayOf(0, 6),
+                        longArrayOf(2, 8),
+                        longArrayOf(4, 10)
+                    )
+                ),
+                TestMetricCapture(
+                    names = listOf("baz"), data = listOf(
+                        longArrayOf(12),
+                        longArrayOf(14),
+                        longArrayOf(16)
+                    )
+                ),
+            ),
+            repeatCount = 3
+        )
+        container.captureInit()
+        repeat(3) {
+            container.captureStart()
+            container.captureStop()
+        }
+        assertEquals(
+            listOf(
+                MetricResult("foo", listOf(0.0, 1.0, 2.0)),
+                MetricResult("bar", listOf(3.0, 4.0, 5.0)),
+                MetricResult("baz", listOf(6.0, 7.0, 8.0))
+            ),
+            container.captureFinished(2) // divide measurements by 2
+        )
+    }
+}
\ No newline at end of file
diff --git a/benchmark/benchmark-common/src/main/cpp/CMakeLists.txt b/benchmark/benchmark-common/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..f61a216
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,37 @@
+
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html.
+# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
+
+# Sets the minimum CMake version required for this project.
+cmake_minimum_required(VERSION 3.22.1)
+
+# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
+# Since this is the top level CMakeLists.txt, the project name is also accessible
+# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
+# build script scope).
+project("benchmarkNative")
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+#
+# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
+# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
+# is preferred for the same purpose.
+#
+# In order to load a library into your app from Java/Kotlin, you must call
+# System.loadLibrary() and pass the name of the library defined here;
+# for GameActivity/NativeActivity derived applications, the same library name must be
+# used in the AndroidManifest.xml file.
+add_library(${CMAKE_PROJECT_NAME} SHARED
+    # List C/C++ source files with relative paths to this CMakeLists.txt.
+        androidx_benchmark_CpuCounter.cpp Profiler.cpp)
+
+# Specifies libraries CMake should link to your target library. You
+# can link libraries from various origins, such as libraries defined in this
+# build script, prebuilt third-party libraries, or Android system libraries.
+target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC log)
+target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE dl)
+target_link_libraries(${CMAKE_PROJECT_NAME} PUBLIC android)
diff --git a/benchmark/benchmark-common/src/main/cpp/Profiler.cpp b/benchmark/benchmark-common/src/main/cpp/Profiler.cpp
new file mode 100644
index 0000000..4db3859
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/cpp/Profiler.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "Profiler.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(WIN32)
+
+#include <unistd.h>
+
+#else
+#   include <io.h>
+#   define close _close
+#endif
+
+#include <algorithm>
+#include <iterator>
+#include <memory>
+
+#if defined(__linux__)
+
+#include <sys/syscall.h>
+
+#ifdef __ARM_ARCH
+enum ARMv8PmuPerfTypes{
+    // Common micro-architecture events
+    ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL    = 0x01,
+    ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS    = 0x14,
+    ARMV8_PMUV3_PERFCTR_L2_CACHE_ACCESS     = 0x16,
+    ARMV8_PMUV3_PERFCTR_L2_CACHE_REFILL     = 0x17,
+    ARMV8_PMUV3_PERFCTR_L2_CACHE_WB         = 0x18,
+};
+#endif
+
+#include <android/log.h>
+#include <errno.h>
+
+#define LOG_TAG "Benchmark"
+
+extern int    errno;
+
+static int perf_event_open(perf_event_attr *hw_event, pid_t pid,
+                           int cpu, int group_fd, unsigned long flags) {
+    return (int) syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+}
+
+#endif // __linux__
+
+namespace utils {
+
+    Profiler::Profiler() noexcept {
+        std::uninitialized_fill(std::begin(mCountersFd), std::end(mCountersFd), -1);
+    }
+
+    Profiler::Profiler(uint32_t eventMask) noexcept: Profiler() {
+        Profiler::resetEvents(eventMask);
+    }
+
+    Profiler::~Profiler() noexcept {
+#pragma nounroll
+        for (int fd: mCountersFd) {
+            if (fd >= 0) {
+                close(fd);
+            }
+        }
+    }
+
+    uint32_t Profiler::resetEvents(uint32_t eventMask) noexcept {
+// close all counters
+#pragma nounroll
+        for (int &fd: mCountersFd) {
+            if (fd >= 0) {
+                close(fd);
+                fd = -1;
+            }
+        }
+        mEnabledEvents = 0;
+
+#if defined(__linux__)
+
+        perf_event_attr pe{};
+        pe.type = PERF_TYPE_HARDWARE;
+        pe.size = sizeof(perf_event_attr);
+        pe.config = PERF_COUNT_HW_INSTRUCTIONS;
+        pe.disabled = 1;
+        pe.exclude_kernel = 1;
+        pe.exclude_hv = 1;
+        pe.read_format = PERF_FORMAT_GROUP |
+                         PERF_FORMAT_ID |
+                         PERF_FORMAT_TOTAL_TIME_ENABLED |
+                         PERF_FORMAT_TOTAL_TIME_RUNNING;
+
+        int fd = perf_event_open(&pe, 0, -1, -1, 0);
+        if (fd == -1) {
+            __android_log_print(
+                    ANDROID_LOG_ERROR,
+                    LOG_TAG,
+                    "perf_event_open failed: [%d]%s",
+                    errno,
+                    strerror(errno)
+            );
+            exit(EXIT_FAILURE);
+        }
+
+        uint8_t count = 0;
+        if (fd >= 0) {
+            const int groupFd = fd;
+            mIds[INSTRUCTIONS] = count++;
+            mCountersFd[INSTRUCTIONS] = fd;
+
+            pe.read_format = PERF_FORMAT_GROUP | PERF_FORMAT_ID;
+
+            if (eventMask & EV_CPU_CYCLES) {
+                pe.type = PERF_TYPE_HARDWARE;
+                pe.config = PERF_COUNT_HW_CPU_CYCLES;
+                mCountersFd[CPU_CYCLES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[CPU_CYCLES] > 0) {
+                    mIds[CPU_CYCLES] = count++;
+                    mEnabledEvents |= EV_CPU_CYCLES;
+                }
+            }
+
+            if (eventMask & EV_L1D_REFS) {
+                pe.type = PERF_TYPE_HARDWARE;
+                pe.config = PERF_COUNT_HW_CACHE_REFERENCES;
+                mCountersFd[DCACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[DCACHE_REFS] > 0) {
+                    mIds[DCACHE_REFS] = count++;
+                    mEnabledEvents |= EV_L1D_REFS;
+                }
+            }
+
+            if (eventMask & EV_L1D_MISSES) {
+                pe.type = PERF_TYPE_HARDWARE;
+                pe.config = PERF_COUNT_HW_CACHE_MISSES;
+                mCountersFd[DCACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[DCACHE_MISSES] > 0) {
+                    mIds[DCACHE_MISSES] = count++;
+                    mEnabledEvents |= EV_L1D_MISSES;
+                }
+            }
+
+            if (eventMask & EV_BPU_REFS) {
+                pe.type = PERF_TYPE_HARDWARE;
+                pe.config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
+                mCountersFd[BRANCHES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[BRANCHES] > 0) {
+                    mIds[BRANCHES] = count++;
+                    mEnabledEvents |= EV_BPU_REFS;
+                }
+            }
+
+            if (eventMask & EV_BPU_MISSES) {
+                pe.type = PERF_TYPE_HARDWARE;
+                pe.config = PERF_COUNT_HW_BRANCH_MISSES;
+                mCountersFd[BRANCH_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[BRANCH_MISSES] > 0) {
+                    mIds[BRANCH_MISSES] = count++;
+                    mEnabledEvents |= EV_BPU_MISSES;
+                }
+            }
+
+#ifdef __ARM_ARCH
+            if (eventMask & EV_L1I_REFS) {
+                pe.type = PERF_TYPE_RAW;
+                pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS;
+                mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[ICACHE_REFS] > 0) {
+                    mIds[ICACHE_REFS] = count++;
+                    mEnabledEvents |= EV_L1I_REFS;
+                }
+            }
+
+            if (eventMask & EV_L1I_MISSES) {
+                pe.type = PERF_TYPE_RAW;
+                pe.config = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL;
+                mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[ICACHE_MISSES] > 0) {
+                    mIds[ICACHE_MISSES] = count++;
+                    mEnabledEvents |= EV_L1I_MISSES;
+                }
+            }
+#else
+            if (eventMask & EV_L1I_REFS) {
+                pe.type = PERF_TYPE_HW_CACHE;
+                pe.config = PERF_COUNT_HW_CACHE_L1I |
+                            (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+                            (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16);
+                mCountersFd[ICACHE_REFS] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[ICACHE_REFS] > 0) {
+                    mIds[ICACHE_REFS] = count++;
+                    mEnabledEvents |= EV_L1I_REFS;
+                }
+            }
+
+            if (eventMask & EV_L1I_MISSES) {
+                pe.type = PERF_TYPE_HW_CACHE;
+                pe.config = PERF_COUNT_HW_CACHE_L1I |
+                            (PERF_COUNT_HW_CACHE_OP_READ << 8) |
+                            (PERF_COUNT_HW_CACHE_RESULT_MISS << 16);
+                mCountersFd[ICACHE_MISSES] = perf_event_open(&pe, 0, -1, groupFd, 0);
+                if (mCountersFd[ICACHE_MISSES] > 0) {
+                    mIds[ICACHE_MISSES] = count++;
+                    mEnabledEvents |= EV_L1I_MISSES;
+                }
+            }
+#endif
+        }
+#endif // __linux__
+        return mEnabledEvents;
+    }
+
+#if defined(__linux__)
+
+    Profiler::Counters Profiler::readCounters() noexcept {
+        Counters outCounters{};
+        Counters counters; // NOLINT
+        ssize_t n = read(mCountersFd[0], &counters, sizeof(Counters));
+        if (n == -1) {
+            __android_log_print(
+                    ANDROID_LOG_ERROR,
+                    LOG_TAG,
+                    "read failed: [%d]%s",
+                    errno,
+                    strerror(errno)
+            );
+            exit(EXIT_FAILURE);
+        }
+        if (n > 0) {
+            outCounters.nr = counters.nr;
+            outCounters.time_enabled = counters.time_enabled;
+            outCounters.time_running = counters.time_running;
+            for (size_t i = 0; i < size_t(EVENT_COUNT); i++) {
+                // in theory we should check that mCountersFd[i] >= 0, but we don't to avoid
+                // a branch, mIds[] is initialized such we won't access past the counters array.
+                outCounters.counters[i] = counters.counters[mIds[i]];
+            }
+        }
+        return outCounters;
+    }
+
+#endif // __linux__
+
+} // namespace utils
diff --git a/benchmark/benchmark-common/src/main/cpp/Profiler.h b/benchmark/benchmark-common/src/main/cpp/Profiler.h
new file mode 100644
index 0000000..fdbf390
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/cpp/Profiler.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef TNT_UTILS_PROFILER_H
+#define TNT_UTILS_PROFILER_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <chrono>   // note: This is safe (only used inline)
+
+#if defined(__linux__)
+#   include <unistd.h>
+#   include <sys/ioctl.h>
+#   include <linux/perf_event.h>
+#endif
+
+#include "compiler.h"
+
+namespace utils {
+
+    class Profiler {
+    public:
+        enum {
+            INSTRUCTIONS    = 0,   // must be zero
+            CPU_CYCLES      = 1,
+            DCACHE_REFS     = 2,
+            DCACHE_MISSES   = 3,
+            BRANCHES        = 4,
+            BRANCH_MISSES   = 5,
+            ICACHE_REFS     = 6,
+            ICACHE_MISSES   = 7,
+
+            // Must be last one
+            EVENT_COUNT
+        };
+
+        enum {
+            EV_CPU_CYCLES = 1u << CPU_CYCLES,
+            EV_L1D_REFS   = 1u << DCACHE_REFS,
+            EV_L1D_MISSES = 1u << DCACHE_MISSES,
+            EV_BPU_REFS   = 1u << BRANCHES,
+            EV_BPU_MISSES = 1u << BRANCH_MISSES,
+            EV_L1I_REFS   = 1u << ICACHE_REFS,
+            EV_L1I_MISSES = 1u << ICACHE_MISSES,
+            // helpers
+            EV_L1D_RATES = EV_L1D_REFS | EV_L1D_MISSES,
+            EV_L1I_RATES = EV_L1I_REFS | EV_L1I_MISSES,
+            EV_BPU_RATES = EV_BPU_REFS | EV_BPU_MISSES,
+        };
+
+        Profiler() noexcept; // must call resetEvents()
+        explicit Profiler(uint32_t eventMask) noexcept;
+        ~Profiler() noexcept;
+
+        Profiler(const Profiler& rhs) = delete;
+        Profiler(Profiler&& rhs) = delete;
+        Profiler& operator=(const Profiler& rhs) = delete;
+        Profiler& operator=(Profiler&& rhs) = delete;
+
+        // selects which events are enabled.
+        uint32_t resetEvents(uint32_t eventMask) noexcept;
+
+        uint32_t getEnabledEvents() const noexcept { return mEnabledEvents; }
+
+        // could return false if performance counters are not supported/enabled
+        bool isValid() const { return mCountersFd[0] >= 0; }
+
+        class Counters {
+            friend class Profiler;
+            uint64_t nr;
+            uint64_t time_enabled;
+            uint64_t time_running;
+            struct {
+                uint64_t value;
+                uint64_t id;
+            } counters[Profiler::EVENT_COUNT];
+
+            friend Counters operator-(Counters lhs, const Counters& rhs) noexcept {
+                lhs.nr -= rhs.nr;
+                lhs.time_enabled -= rhs.time_enabled;
+                lhs.time_running -= rhs.time_running;
+                for (size_t i = 0; i < EVENT_COUNT; ++i) {
+                    lhs.counters[i].value -= rhs.counters[i].value;
+                }
+                return lhs;
+            }
+
+        public:
+            uint64_t getInstructions() const        { return counters[INSTRUCTIONS].value; }
+            uint64_t getCpuCycles() const           { return counters[CPU_CYCLES].value; }
+            uint64_t getL1DReferences() const       { return counters[DCACHE_REFS].value; }
+            uint64_t getL1DMisses() const           { return counters[DCACHE_MISSES].value; }
+            uint64_t getL1IReferences() const       { return counters[ICACHE_REFS].value; }
+            uint64_t getL1IMisses() const           { return counters[ICACHE_MISSES].value; }
+            uint64_t getBranchInstructions() const  { return counters[BRANCHES].value; }
+            uint64_t getBranchMisses() const        { return counters[BRANCH_MISSES].value; }
+
+            std::chrono::duration<uint64_t, std::nano> getWallTime() const {
+                return std::chrono::duration<uint64_t, std::nano>(time_enabled);
+            }
+
+            std::chrono::duration<uint64_t, std::nano> getRunningTime() const {
+                return std::chrono::duration<uint64_t, std::nano>(time_running);
+            }
+
+            double getIPC() const noexcept {
+                uint64_t cpuCycles = getCpuCycles();
+                uint64_t instructions = getInstructions();
+                return double(instructions) / double(cpuCycles);
+            }
+
+            double getCPI() const noexcept {
+                uint64_t cpuCycles = getCpuCycles();
+                uint64_t instructions = getInstructions();
+                return double(cpuCycles) / double(instructions);
+            }
+
+            double getL1DMissRate() const noexcept {
+                uint64_t cacheReferences = getL1DReferences();
+                uint64_t cacheMisses = getL1DMisses();
+                return double(cacheMisses) / double(cacheReferences);
+            }
+
+            double getL1DHitRate() const noexcept {
+                return 1.0 - getL1DMissRate();
+            }
+
+            double getL1IMissRate() const noexcept {
+                uint64_t cacheReferences = getL1IReferences();
+                uint64_t cacheMisses = getL1IMisses();
+                return double(cacheMisses) / double(cacheReferences);
+            }
+
+            double getL1IHitRate() const noexcept {
+                return 1.0 - getL1IMissRate();
+            }
+
+            double getBranchMissRate() const noexcept {
+                uint64_t branchReferences = getBranchInstructions();
+                uint64_t branchMisses = getBranchMisses();
+                return double(branchMisses) / double(branchReferences);
+            }
+
+            double getBranchHitRate() const noexcept {
+                return 1.0 - getBranchMissRate();
+            }
+
+            double getMPKI(uint64_t misses) const noexcept {
+                return (misses * 1000.0) / getInstructions();
+            }
+        };
+
+#if defined(__linux__)
+
+        void reset() noexcept {
+        int fd = mCountersFd[0];
+        ioctl(fd, PERF_EVENT_IOC_RESET,  PERF_IOC_FLAG_GROUP);
+    }
+
+    void start() noexcept {
+        int fd = mCountersFd[0];
+        ioctl(fd, PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
+    }
+
+    void stop() noexcept {
+        int fd = mCountersFd[0];
+        ioctl(fd, PERF_EVENT_IOC_DISABLE, PERF_IOC_FLAG_GROUP);
+    }
+
+    Counters readCounters() noexcept;
+
+#else // !__linux__
+
+        void reset() noexcept { }
+        void start() noexcept { }
+        void stop() noexcept { }
+        Counters readCounters() noexcept { return {}; }
+
+#endif // __linux__
+
+        bool hasBranchRates() const noexcept {
+            return (mCountersFd[BRANCHES] >= 0) && (mCountersFd[BRANCH_MISSES] >= 0);
+        }
+
+        bool hasICacheRates() const noexcept {
+            return (mCountersFd[ICACHE_REFS] >= 0) && (mCountersFd[ICACHE_MISSES] >= 0);
+        }
+
+    private:
+        UTILS_UNUSED uint8_t mIds[EVENT_COUNT] = {};
+        int mCountersFd[EVENT_COUNT];
+        uint32_t mEnabledEvents = 0;
+    };
+
+} // namespace utils
+
+#endif // TNT_UTILS_PROFILER_H
diff --git a/benchmark/benchmark-common/src/main/cpp/androidx_benchmark_CpuCounter.cpp b/benchmark/benchmark-common/src/main/cpp/androidx_benchmark_CpuCounter.cpp
new file mode 100644
index 0000000..447b877
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/cpp/androidx_benchmark_CpuCounter.cpp
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#include <jni.h>
+#include <asm/unistd.h>
+#include <memory>
+#include <android/log.h>
+#include "Profiler.h"
+#include <iostream>
+#include <sys/syscall.h>
+
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "UnusedParameter"
+
+const int32_t CountersLongCount = sizeof(utils::Profiler::Counters) / sizeof(uint64_t);
+
+static_assert(
+        CountersLongCount == 19,
+        "Expected Counters to have consistent length, "
+        "may need to update Kotlin LongArray definition"
+);
+
+static int perf_event_open(perf_event_attr *hw_event, pid_t pid,
+                           int cpu, int group_fd, unsigned long flags) {
+    return (int) syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+}
+
+#pragma clang diagnostic pop
+extern "C"
+JNIEXPORT jstring JNICALL
+Java_androidx_benchmark_CpuCounterJni_checkPerfEventSupport(
+        JNIEnv *env,
+        jobject thiz
+) {
+
+    // perf event group creation code copied from Profiler.cpp to allow us to
+    // return an error string on failure instead of killing process
+    perf_event_attr pe{};
+    pe.type = PERF_TYPE_HARDWARE;
+    pe.size = sizeof(perf_event_attr);
+    pe.config = PERF_COUNT_HW_INSTRUCTIONS;
+    pe.disabled = 1;
+    pe.exclude_kernel = 1;
+    pe.exclude_hv = 1;
+    pe.read_format = PERF_FORMAT_GROUP |
+                     PERF_FORMAT_ID |
+                     PERF_FORMAT_TOTAL_TIME_ENABLED |
+                     PERF_FORMAT_TOTAL_TIME_RUNNING;
+    int fd = perf_event_open(&pe, 0, -1, -1, 0);
+    // TODO: implement checkPerfEventSupport()
+    if (fd == -1) {
+        char output[256];
+        sprintf(&output[0], "perf_event_open failed: [%d]%s", errno, strerror(errno));
+        return (jstring) env->NewStringUTF(&output[0]);
+    } else {
+        close(fd);
+        return (jstring) nullptr;
+    }
+}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_androidx_benchmark_CpuCounterJni_newProfiler(
+        JNIEnv *env,
+        jobject thiz
+) {
+    auto *pProfiler = new utils::Profiler();
+    return (long) pProfiler;
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_benchmark_CpuCounterJni_freeProfiler(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    delete pProfiler;
+}
+extern "C"
+JNIEXPORT jint JNICALL
+Java_androidx_benchmark_CpuCounterJni_resetEvents(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr,
+        jint event_mask
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    return (jint) pProfiler->resetEvents(event_mask);
+}
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_benchmark_CpuCounterJni_reset(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    pProfiler->reset();
+}
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_benchmark_CpuCounterJni_start(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    pProfiler->start();
+}
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_benchmark_CpuCounterJni_stop(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    pProfiler->stop();
+}
+extern "C"
+JNIEXPORT void JNICALL
+Java_androidx_benchmark_CpuCounterJni_read(
+        JNIEnv *env,
+        jobject thiz,
+        jlong profiler_ptr,
+        jlongArray out_data
+) {
+    auto *pProfiler = (utils::Profiler *) profiler_ptr;
+    utils::Profiler::Counters counters = pProfiler->readCounters();
+    jsize longCount = sizeof(utils::Profiler::Counters) / sizeof(uint64_t);
+    env->SetLongArrayRegion(out_data, 0, longCount, reinterpret_cast<jlong *>(&counters));
+}
\ No newline at end of file
diff --git a/benchmark/benchmark-common/src/main/cpp/compiler.h b/benchmark/benchmark-common/src/main/cpp/compiler.h
new file mode 100644
index 0000000..c815266
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/cpp/compiler.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef TNT_UTILS_COMPILER_H
+#define TNT_UTILS_COMPILER_H
+
+// compatibility with non-clang compilers...
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if __has_attribute(visibility)
+#    define UTILS_PUBLIC  __attribute__((visibility("default")))
+#else
+#    define UTILS_PUBLIC
+#endif
+
+#if __has_attribute(deprecated)
+#   define UTILS_DEPRECATED [[deprecated]]
+#else
+#   define UTILS_DEPRECATED
+#endif
+
+#if __has_attribute(packed)
+#   define UTILS_PACKED __attribute__((packed))
+#else
+#   define UTILS_PACKED
+#endif
+
+#if __has_attribute(noreturn)
+#    define UTILS_NORETURN __attribute__((noreturn))
+#else
+#    define UTILS_NORETURN
+#endif
+
+#if __has_attribute(fallthrough)
+#   define UTILS_FALLTHROUGH [[fallthrough]]
+#else
+#   define UTILS_FALLTHROUGH
+#endif
+
+#if __has_attribute(visibility)
+#    ifndef TNT_DEV
+#        define UTILS_PRIVATE __attribute__((visibility("hidden")))
+#    else
+#        define UTILS_PRIVATE
+#    endif
+#else
+#    define UTILS_PRIVATE
+#endif
+
+#define UTILS_NO_SANITIZE_THREAD
+#if __has_feature(thread_sanitizer)
+#undef UTILS_NO_SANITIZE_THREAD
+#define UTILS_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
+#endif
+
+#define UTILS_HAS_SANITIZE_THREAD 0
+#if __has_feature(thread_sanitizer) || defined(__SANITIZE_THREAD__)
+#undef UTILS_HAS_SANITIZE_THREAD
+#define UTILS_HAS_SANITIZE_THREAD 1
+#endif
+
+#define UTILS_HAS_SANITIZE_MEMORY 0
+#if __has_feature(memory_sanitizer)
+#undef UTILS_HAS_SANITIZE_MEMORY
+#define UTILS_HAS_SANITIZE_MEMORY 1
+#endif
+
+/*
+ * helps the compiler's optimizer predicting branches
+ */
+#if __has_builtin(__builtin_expect)
+#   ifdef __cplusplus
+#      define UTILS_LIKELY( exp )    (__builtin_expect( !!(exp), true ))
+#      define UTILS_UNLIKELY( exp )  (__builtin_expect( !!(exp), false ))
+#   else
+#      define UTILS_LIKELY( exp )    (__builtin_expect( !!(exp), 1 ))
+#      define UTILS_UNLIKELY( exp )  (__builtin_expect( !!(exp), 0 ))
+#   endif
+#else
+#   define UTILS_LIKELY( exp )    (!!(exp))
+#   define UTILS_UNLIKELY( exp )  (!!(exp))
+#endif
+
+#if __has_builtin(__builtin_prefetch)
+#   define UTILS_PREFETCH( exp ) (__builtin_prefetch(exp))
+#else
+#   define UTILS_PREFETCH( exp )
+#endif
+
+#if __has_builtin(__builtin_assume)
+#   define UTILS_ASSUME( exp ) (__builtin_assume(exp))
+#else
+#   define UTILS_ASSUME( exp )
+#endif
+
+#if (defined(__i386__) || defined(__x86_64__))
+#   define UTILS_HAS_HYPER_THREADING 1      // on x86 we assume we have hyper-threading.
+#else
+#   define UTILS_HAS_HYPER_THREADING 0
+#endif
+
+#if defined(FILAMENT_SINGLE_THREADED)
+#   define UTILS_HAS_THREADING 0
+#elif defined(__EMSCRIPTEN__)
+#   if defined(__EMSCRIPTEN_PTHREADS__) && defined(FILAMENT_WASM_THREADS)
+#      define UTILS_HAS_THREADING 1
+#   else
+#      define UTILS_HAS_THREADING 0
+#   endif
+#else
+#   define UTILS_HAS_THREADING 1
+#endif
+
+#if __has_attribute(noinline)
+#define UTILS_NOINLINE __attribute__((noinline))
+#else
+#define UTILS_NOINLINE
+#endif
+
+#if __has_attribute(always_inline)
+#define UTILS_ALWAYS_INLINE __attribute__((always_inline))
+#else
+#define UTILS_ALWAYS_INLINE
+#endif
+
+#if __has_attribute(pure)
+#define UTILS_PURE __attribute__((pure))
+#else
+#define UTILS_PURE
+#endif
+
+#if __has_attribute(maybe_unused) || (defined(_MSC_VER) && _MSC_VER >= 1911)
+#define UTILS_UNUSED [[maybe_unused]]
+#define UTILS_UNUSED_IN_RELEASE [[maybe_unused]]
+#elif __has_attribute(unused)
+#define UTILS_UNUSED __attribute__((unused))
+#define UTILS_UNUSED_IN_RELEASE __attribute__((unused))
+#else
+#define UTILS_UNUSED
+#define UTILS_UNUSED_IN_RELEASE
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1900
+#    define UTILS_RESTRICT __restrict
+#elif (defined(__clang__) || defined(__GNUC__))
+#    define UTILS_RESTRICT __restrict__
+#else
+#    define UTILS_RESTRICT
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER >= 1900
+#   define UTILS_HAS_FEATURE_CXX_THREAD_LOCAL 1
+#elif __has_feature(cxx_thread_local)
+#   define UTILS_HAS_FEATURE_CXX_THREAD_LOCAL 1
+#else
+#   define UTILS_HAS_FEATURE_CXX_THREAD_LOCAL 0
+#endif
+
+#if defined(_MSC_VER)
+// MSVC does not support loop unrolling hints
+#   define UTILS_UNROLL
+#   define UTILS_NOUNROLL
+#else
+// C++11 allows pragmas to be specified as part of defines using the _Pragma syntax.
+#   define UTILS_UNROLL _Pragma("unroll")
+#   define UTILS_NOUNROLL _Pragma("nounroll")
+#endif
+
+#if __has_feature(cxx_rtti) || defined(_CPPRTTI)
+#   define UTILS_HAS_RTTI 1
+#else
+#   define UTILS_HAS_RTTI 0
+#endif
+
+#ifdef __ARM_ACLE
+#   include <arm_acle.h>
+#   define UTILS_WAIT_FOR_INTERRUPT()   __wfi()
+#   define UTILS_WAIT_FOR_EVENT()       __wfe()
+#   define UTILS_BROADCAST_EVENT()      __sev()
+#   define UTILS_SIGNAL_EVENT()         __sevl()
+#   define UTILS_PAUSE()                __yield()
+#   define UTILS_PREFETCHW(addr)        __pldx(1, 0, 0, addr)
+#else // !__ARM_ACLE
+#   if (defined(__i386__) || defined(__x86_64__))
+#       define UTILS_X86_PAUSE              {__asm__ __volatile__( "rep; nop" : : : "memory" );}
+#       define UTILS_WAIT_FOR_INTERRUPT()   UTILS_X86_PAUSE
+#       define UTILS_WAIT_FOR_EVENT()       UTILS_X86_PAUSE
+#       define UTILS_BROADCAST_EVENT()
+#       define UTILS_SIGNAL_EVENT()
+#       define UTILS_PAUSE()                UTILS_X86_PAUSE
+#       define UTILS_PREFETCHW(addr)        UTILS_PREFETCH(addr)
+#   else // !x86
+#       define UTILS_WAIT_FOR_INTERRUPT()
+#       define UTILS_WAIT_FOR_EVENT()
+#       define UTILS_BROADCAST_EVENT()
+#       define UTILS_SIGNAL_EVENT()
+#       define UTILS_PAUSE()
+#       define UTILS_PREFETCHW(addr)        UTILS_PREFETCH(addr)
+#   endif // x86
+#endif // __ARM_ACLE
+
+
+// ssize_t is a POSIX type.
+#if defined(WIN32) || defined(_WIN32)
+#include <Basetsd.h>
+typedef SSIZE_T ssize_t;
+#endif
+
+#ifdef _MSC_VER
+#   define UTILS_EMPTY_BASES __declspec(empty_bases)
+#else
+#   define UTILS_EMPTY_BASES
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+#define IMPORTSYMB __declspec(dllimport)
+#else
+#define IMPORTSYMB
+#endif
+
+#if defined(_MSC_VER) && !defined(__PRETTY_FUNCTION__)
+#    define __PRETTY_FUNCTION__ __FUNCSIG__
+#endif
+
+
+#if defined(_MSC_VER)
+#   define UTILS_WARNING_PUSH _Pragma("warning( push )")
+#   define UTILS_WARNING_POP _Pragma("warning( pop )")
+#   define UTILS_WARNING_ENABLE_PADDED _Pragma("warning(1: 4324)")
+#elif defined(__clang__)
+#   define UTILS_WARNING_PUSH _Pragma("clang diagnostic push")
+#   define UTILS_WARNING_POP  _Pragma("clang diagnostic pop")
+#   define UTILS_WARNING_ENABLE_PADDED _Pragma("clang diagnostic warning \"-Wpadded\"")
+#else
+#   define UTILS_WARNING_PUSH
+#   define UTILS_WARNING_POP
+#   define UTILS_WARNING_ENABLE_PADDED
+#endif
+
+#endif // TNT_UTILS_COMPILER_H
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 088cfd8..46dacdc 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/BenchmarkState.kt
@@ -304,6 +304,8 @@
             if (it.warmupManager != null) {
                 // warmup phase
                 currentMetrics.captureInit()
+                // Note that warmupManager presence implies only one metric captured,
+                // this is validated in MicrobenchmarkPhase init
                 val lastMeasuredWarmupValue = currentMetrics.data.last()[0]
                 if (it.warmupManager.onNextIteration(lastMeasuredWarmupValue)) {
                     warmupEstimatedIterationTimeNs = lastMeasuredWarmupValue
@@ -585,8 +587,10 @@
             @IntRange(from = 0) thermalThrottleSleepSeconds: Long,
             @IntRange(from = 1) repeatIterations: Int
         ) {
-            val metricsContainer = MetricsContainer(REPEAT_COUNT = dataNs.size)
-            metricsContainer.data[metricsContainer.data.lastIndex] = dataNs.toLongArray()
+            val metricsContainer = MetricsContainer(repeatCount = dataNs.size)
+            dataNs.forEachIndexed { index, value ->
+                metricsContainer.data[index][0] = value
+            }
             val report = BenchmarkResult(
                 className = className,
                 testName = testName,
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/CpuCounter.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/CpuCounter.kt
new file mode 100644
index 0000000..7e57ab5
--- /dev/null
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/CpuCounter.kt
@@ -0,0 +1,123 @@
+/*
+ * 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.benchmark
+
+import androidx.annotation.RestrictTo
+import java.io.Closeable
+
+/**
+ * Exposes CPU counters from perf_event_open based on libs/utils/src/Profiler.cpp from
+ * Google/Filament.
+ *
+ * This layer is extremely simple to reduce overhead, though it does not yet use
+ * fast/critical JNI.
+ *
+ * This counter must be closed to avoid leaking the associated native allocation.
+ *
+ * This class does not yet help callers with prerequisites to getting counter values on API 30+:
+ *  - setenforce 0 (requires root)
+ *  - security.perf_harden 0
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class CpuCounter : Closeable {
+    private var profilerPtr = CpuCounterJni.newProfiler()
+    private var hasReset = false
+
+    fun resetEvents(events: List<Event>) {
+        hasReset = true
+        val flags = events.fold(0) { acc, event ->
+            acc.or(event.flag)
+        }
+        CpuCounterJni.resetEvents(profilerPtr, flags)
+    }
+
+    override fun close() {
+        CpuCounterJni.freeProfiler(profilerPtr)
+        profilerPtr = 0
+    }
+
+    fun reset() {
+        CpuCounterJni.reset(profilerPtr)
+    }
+    fun start() = CpuCounterJni.start(profilerPtr)
+    fun stop() = CpuCounterJni.stop(profilerPtr)
+
+    fun read(outValues: Values) {
+        check(profilerPtr != 0L) { "Error: attempted to read counters after close" }
+        check(hasReset) { "Error: attempted to read counters without reset" }
+        CpuCounterJni.read(profilerPtr, outValues.longArray)
+    }
+
+    enum class Event(
+        val id: Int
+    ) {
+        Instructions(0),
+        CpuCycles(1),
+        L1DReferences(2),
+        L1DMisses(3),
+        BranchInstructions(4),
+        BranchMisses(5),
+        L1IReferences(6),
+        L1IMisses(7);
+
+        val flag: Int
+            inline get() = 1 shl id
+    }
+
+    /**
+     * Holder class for querying all counter values at once out of native, to avoid multiple JNI
+     * transitions.
+     */
+    @JvmInline
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    value class Values(val longArray: LongArray = LongArray(19)) {
+        init {
+            // See CountersLongCount static_assert in native
+            require(longArray.size == 19)
+        }
+
+        inline val numberOfCounters: Long
+            get() = longArray[0]
+        inline val timeEnabled: Long
+            get() = longArray[1]
+        inline val timeRunning: Long
+            get() = longArray[2]
+
+        @Suppress("NOTHING_TO_INLINE")
+        inline fun getValue(spec: Event): Long = longArray[3 + (2 * spec.id)]
+    }
+
+    companion object {
+        fun checkPerfEventSupport(): String? = CpuCounterJni.checkPerfEventSupport()
+    }
+}
+
+private object CpuCounterJni {
+    init {
+        System.loadLibrary("benchmarkNative")
+    }
+
+    // Profiler methods
+    external fun checkPerfEventSupport(): String?
+    external fun newProfiler(): Long
+    external fun freeProfiler(profilerPtr: Long)
+    external fun resetEvents(profilerPtr: Long, mask: Int): Int
+    external fun reset(profilerPtr: Long)
+    external fun start(profilerPtr: Long)
+    external fun stop(profilerPtr: Long)
+    external fun read(profilerPtr: Long, outData: LongArray)
+}
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 19d5d66..81cad8c 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
@@ -39,7 +39,7 @@
 
     val isEngBuild = Build.FINGERPRINT.contains(":eng/")
 
-    val isRooted =
+    val isRooted = Build.FINGERPRINT.contains(":userdebug/") ||
         arrayOf(
             "/system/app/Superuser.apk",
             "/sbin/su",
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/IsolationActivity.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/IsolationActivity.kt
index 475d34f..0f716e2 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/IsolationActivity.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/IsolationActivity.kt
@@ -53,6 +53,7 @@
         setContentView(R.layout.isolation_activity)
 
         // disable launch animation
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
 
         if (firstInit) {
@@ -117,6 +118,7 @@
 
     public fun actuallyFinish() {
         // disable close animation
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
         super.finish()
     }
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricCapture.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricCapture.kt
index 551d9e0..ec556be 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricCapture.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricCapture.kt
@@ -18,9 +18,9 @@
 
 import android.os.Debug
 
-internal abstract class MetricCapture {
-    abstract val name: String
-
+internal abstract class MetricCapture(
+    val names: List<String>
+) {
     /**
      * Starts collecting data for a run.
      *
@@ -29,11 +29,12 @@
     abstract fun captureStart(timeNs: Long)
 
     /**
-     * Marks the end of a run, and stores the metric value changes since the last start.
+     * Marks the end of a run, and stores one metric value in the output array since the last call
+     * to start.
      *
      * Should be called when a run stops.
      */
-    abstract fun captureStop(timeNs: Long): Long
+    abstract fun captureStop(timeNs: Long, output: LongArray, offset: Int)
 
     /**
      * Pauses data collection.
@@ -50,16 +51,17 @@
     abstract fun captureResumed()
 
     override fun equals(other: Any?): Boolean {
-        return (other is MetricCapture && other.name == this.name)
+        return (other is MetricCapture && other.names == this.names)
     }
 
     override fun hashCode(): Int {
-        return name.hashCode() // This is the only true state retained, and hashCode must match ==
+        return names.hashCode() // This is the only true state retained, and hashCode must match ==
     }
 }
 
-internal class TimeCapture : MetricCapture() {
-    override val name: String = "timeNs"
+internal class TimeCapture : MetricCapture(
+    names = listOf("timeNs")
+) {
     private var currentStarted = 0L
     private var currentPausedStarted = 0L
     private var currentTotalPaused = 0L
@@ -69,8 +71,8 @@
         currentStarted = timeNs
     }
 
-    override fun captureStop(timeNs: Long): Long {
-        return timeNs - currentStarted - currentTotalPaused
+    override fun captureStop(timeNs: Long, output: LongArray, offset: Int) {
+        output[offset] = timeNs - currentStarted - currentTotalPaused
     }
 
     override fun capturePaused() {
@@ -83,8 +85,9 @@
 }
 
 @Suppress("DEPRECATION")
-internal class AllocationCountCapture : MetricCapture() {
-    override val name = "allocationCount"
+internal class AllocationCountCapture : MetricCapture(
+    names = listOf("allocationCount")
+) {
     private var currentPausedStarted = 0
     private var currentTotalPaused = 0
 
@@ -93,9 +96,9 @@
         Debug.startAllocCounting()
     }
 
-    override fun captureStop(timeNs: Long): Long {
+    override fun captureStop(timeNs: Long, output: LongArray, offset: Int) {
         Debug.stopAllocCounting()
-        return (Debug.getGlobalAllocCount() - currentTotalPaused).toLong()
+        output[offset] = (Debug.getGlobalAllocCount() - currentTotalPaused).toLong()
     }
 
     override fun capturePaused() {
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricsContainer.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricsContainer.kt
index 2b9e2b4..995ab06 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricsContainer.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MetricsContainer.kt
@@ -25,12 +25,33 @@
      * Metrics are usually indexed by the names provided for them by the MetricCaptures, or an index
      */
     private val metrics: Array<MetricCapture> = arrayOf(TimeCapture()),
-    private val REPEAT_COUNT: Int
+    private val repeatCount: Int
 ) {
 
-    internal val data: Array<LongArray> = Array(metrics.size) {
-        LongArray(REPEAT_COUNT)
-    }
+    internal val names: List<String> = metrics.flatMap { it.names }
+
+    /**
+     * Each entry in the top level list is a multi-metric set of measurements.
+     *
+     * ```
+     * Example layout:
+     *     repeatCount = 2
+     *     metrics = [ MetricCapture(names = "X","Y"), MetricCapture(names = "Z") ]
+     *
+     * names = [ "X", "Y", "Z" ]
+     * data = [
+     *    // NOTE: Z start()'d first, but stop()'d last
+     *    [X1, Y1, Z1]
+     *    [X2, Y2, Z2]
+     * ]
+     * ```
+     *
+     * NOTE: Performance of warmup is very dependent on this structure, be very careful changing
+     * changing this. E.g. using a single linear LongArray or an Array<LongArray> both caused
+     * warmup measurements of a noop loop to fluctuate, and increase significantly
+     * (from 75ns to 450ns on an API 30 Bramble).
+     */
+    internal val data: List<LongArray> = List(repeatCount) { LongArray(names.size) }
 
     /**
      * Array of start / stop time, per measurement, to be passed to [UserspaceTracing].
@@ -38,7 +59,7 @@
      * These values are used both in metric calculation and trace data, so tracing is extremely low
      * overhead - just the cost of storing the timing data in an additional place in memory.
      */
-    private val traceTiming = LongArray(REPEAT_COUNT * 2)
+    private val traceTiming = LongArray(repeatCount * 2)
 
     private var runNum: Int = 0
 
@@ -59,8 +80,8 @@
     fun captureStart() {
         val timeNs = System.nanoTime()
         traceTiming[runNum * 2] = timeNs
-        for (i in 0..metrics.lastIndex) {
-            metrics[i].captureStart(timeNs) // put the most sensitive metric last to avoid overhead
+        for (i in metrics.lastIndex downTo 0) {
+            metrics[i].captureStart(timeNs) // put the most sensitive metric first to avoid overhead
         }
     }
 
@@ -71,8 +92,10 @@
      */
     fun captureStop() {
         val timeNs = System.nanoTime()
-        for (i in metrics.lastIndex downTo 0) { // stop in reverse order
-            data[i][runNum] = metrics[i].captureStop(timeNs)
+        var offset = 0
+        for (i in 0..metrics.lastIndex) { // stop in reverse order from start
+            metrics[i].captureStop(timeNs, data[runNum], offset)
+            offset += metrics[i].names.size
         }
         traceTiming[runNum * 2 + 1] = timeNs
         runNum += 1
@@ -110,26 +133,24 @@
             UserspaceTracing.beginSection("measurement ${i / 2}", nanoTime = traceTiming[i])
             UserspaceTracing.endSection(nanoTime = traceTiming[i + 1])
         }
-        return data.mapIndexed { index, longMeasurementArray ->
-            val metric = metrics[index]
 
-            // convert to floats and divide by iter count here for efficiency
-            val scaledMeasurements = longMeasurementArray
-                .map { it / maxIterations.toDouble() }
-
-            scaledMeasurements.chunked(10)
+        return names.mapIndexed { index, name ->
+            val metricData = List(repeatCount) {
+                // convert to floats and divide by iter count here for efficiency
+                data[it][index] / maxIterations.toDouble()
+            }
+            metricData.chunked(10)
                 .forEachIndexed { chunkNum, chunk ->
                     Log.d(
                         BenchmarkState.TAG,
-                        metric.name + "[%2d:%2d]: %s".format(
+                        name + "[%2d:%2d]: %s".format(
                             chunkNum * 10,
                             (chunkNum + 1) * 10,
                             chunk.joinToString(" ") { it.toLong().toString() }
                         )
                     )
                 }
-
-            MetricResult(metric.name, scaledMeasurements)
+            MetricResult(name, metricData)
         }
     }
 }
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MicrobenchmarkPhase.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MicrobenchmarkPhase.kt
index 0fe58d5..fe56b1f 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/MicrobenchmarkPhase.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/MicrobenchmarkPhase.kt
@@ -20,6 +20,13 @@
     private var thermalThrottleSleepsRemaining = thermalThrottleSleepsMax
     var thermalThrottleSleepSeconds = 0L
 
+    init {
+        check(loopMode.warmupManager == null || metricsContainer.names.size == 1) {
+            "If warmup is enabled, must only capture one metric," +
+                " as WarmupManager only one value per repeat"
+        }
+    }
+
     /**
      * @return If true, finishing the phase was successful, otherwise must be retried
      */
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Shell.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Shell.kt
index 5df22dd..bcdd92e 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Shell.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Shell.kt
@@ -610,6 +610,16 @@
             .trim()
             .toIntOrNull()
     }
+
+    @RequiresApi(21)
+    fun isSELinuxEnforced(): Boolean {
+        return when (val value = executeScriptCaptureStdout("getenforce").trim()) {
+            "Permissive" -> false
+            "Disabled" -> false
+            "Enforcing" -> true
+            else -> throw IllegalStateException("unexpected result from getenforce: $value")
+        }
+    }
 }
 
 @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
index aa6bea5..a50e8a7 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
@@ -25,13 +25,13 @@
 import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
 import androidx.benchmark.userspaceTrace
 import androidx.test.platform.app.InstrumentationRegistry
-import androidx.tracing.perfetto.PerfettoSdkHandshake
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
+import androidx.tracing.perfetto.handshake.PerfettoSdkHandshake
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_SUCCESS
 import java.io.File
 import java.io.StringReader
 
diff --git a/benchmark/benchmark-macro/build.gradle b/benchmark/benchmark-macro/build.gradle
index bc6c8e3..3f53f87 100644
--- a/benchmark/benchmark-macro/build.gradle
+++ b/benchmark/benchmark-macro/build.gradle
@@ -70,7 +70,7 @@
     androidTestImplementation(project(":internal-testutils-ktx"))
     androidTestImplementation("androidx.activity:activity-ktx:1.3.1")
     androidTestImplementation(project(":tracing:tracing-perfetto"))
-    androidTestImplementation(project(":tracing:tracing-perfetto-common"))
+    androidTestImplementation(project(":tracing:tracing-perfetto-handshake"))
     androidTestImplementation(project(":tracing:tracing-perfetto-binary"))
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testRules)
@@ -147,24 +147,6 @@
     prune 'perfetto.protos.UnsymbolizedFrames'
 }
 
-// https://github.com/square/wire/issues/1947
-// Remove when we upgrade to fixed wire library
-afterEvaluate {
-    tasks.named("compileDebugKotlin").configure {
-        it.dependsOn("generateDebugProtos")
-    }
-    tasks.named("compileReleaseKotlin").configure {
-        it.dependsOn("generateReleaseProtos")
-    }
-}
-
-androidx {
-    deviceTests {
-        targetAppProject = project(":benchmark:integration-tests:macrobenchmark-target")
-        targetAppVariant = "release"
-    }
-}
-
 // Define a task dependency so the app is installed before we run macro benchmarks.
 afterEvaluate {
     // `:benchmark:integration-tests:macrobenchmark-target:installRelease` is not in the compose
@@ -176,3 +158,10 @@
                 .dependsOn(installTask)
     }
 }
+
+androidx {
+    deviceTests {
+        targetAppProject = project(":benchmark:integration-tests:macrobenchmark-target")
+        targetAppVariant = "release"
+    }
+}
diff --git a/benchmark/benchmark-macro/lint-baseline.xml b/benchmark/benchmark-macro/lint-baseline.xml
index 9433540..30a22e1 100644
--- a/benchmark/benchmark-macro/lint-baseline.xml
+++ b/benchmark/benchmark-macro/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -40,69 +40,6 @@
     <issue
         id="BanThreadSleep"
         message="Uses Thread.sleep()"
-        errorLine1="            Thread.sleep(2000)"
-        errorLine2="                   ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="                Thread.sleep(100)"
-        errorLine2="                       ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(delayDurationMs)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(delayDurationMs)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="            Thread.sleep(50)"
-        errorLine2="                   ~~~~~">
-        <location
-            file="src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(5000) // sleep to await flushing cache to disk"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkScopeTest.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="                trace(label) { Thread.sleep(50) }"
-        errorLine2="                                      ~~~~~">
-        <location
-            file="src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
         errorLine1="                Thread.sleep(500)"
         errorLine2="                       ~~~~~">
         <location
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
index ec10dc1..8d70233 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
@@ -28,12 +28,12 @@
 import androidx.benchmark.perfetto.PerfettoCapture
 import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
 import androidx.test.platform.app.InstrumentationRegistry
-import androidx.tracing.perfetto.PerfettoSdkHandshake
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_CANCELLED
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
+import androidx.tracing.perfetto.handshake.PerfettoSdkHandshake
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_CANCELLED
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes.RESULT_CODE_SUCCESS
 import com.google.common.truth.Truth.assertThat
 import java.io.File
 import java.io.StringReader
@@ -47,7 +47,7 @@
 import org.junit.runners.Parameterized
 import org.junit.runners.Parameterized.Parameters
 
-private const val tracingPerfettoVersion = "1.0.0-alpha16" // TODO(224510255): get by 'reflection'
+private const val tracingPerfettoVersion = "1.0.0-alpha17" // TODO(224510255): get by 'reflection'
 private const val minSupportedSdk = Build.VERSION_CODES.R // TODO(234351579): Support API < 30
 
 @RunWith(Parameterized::class)
@@ -161,11 +161,11 @@
     }
 
     /**
-     * This tests [androidx.tracing.perfetto.PerfettoSdkHandshake] which is used by both Benchmark
-     * and Studio.
+     * This tests [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake] which is used by both
+     * Benchmark and Studio.
      *
      * By contrast, other tests use the [PerfettoCapture.enableAndroidxTracingPerfetto], which
-     * is built on top of [androidx.tracing.perfetto.PerfettoSdkHandshake] and implements
+     * is built on top of [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake] and implements
      * the parts where Studio and Benchmark differ.
      */
     @Test
@@ -173,7 +173,7 @@
         assumeTrue(isAbiSupported())
         assumeTrue(Build.VERSION.SDK_INT >= minSupportedSdk)
 
-        /** perform a handshake using [androidx.tracing.perfetto.PerfettoSdkHandshake] */
+        /** perform a handshake using [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake] */
         val libraryZip: File? = resolvePerfettoAar()
         val tmpDir = Outputs.dirUsableByAppAndShell
         val mvTmpDst = createShellFileMover()
diff --git a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/CpuCounterBenchmark.kt b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/CpuCounterBenchmark.kt
new file mode 100644
index 0000000..3ce5c8b
--- /dev/null
+++ b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/CpuCounterBenchmark.kt
@@ -0,0 +1,123 @@
+/*
+ * 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.benchmark.benchmark
+
+import android.os.Build
+import androidx.benchmark.CpuCounter
+import androidx.benchmark.DeviceInfo
+import androidx.benchmark.PropOverride
+import androidx.benchmark.Shell
+import androidx.benchmark.junit4.BenchmarkRule
+import androidx.benchmark.junit4.measureRepeated
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
+class CpuCounterBenchmark {
+    @get:Rule
+    val benchmarkRule = BenchmarkRule()
+    private val values = CpuCounter.Values()
+
+    private val perfHardenProp = PropOverride("security.perf_harden", "0")
+    private var shouldResetEnforce1 = false
+
+    @Before
+    fun before() {
+        // TODO: make this automatic
+        if (Build.VERSION.SDK_INT > 29) {
+            val blockedBySelinux = Shell.isSELinuxEnforced()
+            Assume.assumeTrue(
+                "blocked by selinux = $blockedBySelinux, rooted = ${DeviceInfo.isRooted}",
+                !blockedBySelinux || DeviceInfo.isRooted
+            )
+            if (blockedBySelinux && DeviceInfo.isRooted) {
+                Shell.executeScriptSilent("setenforce 0")
+                shouldResetEnforce1 = true
+            }
+            perfHardenProp.forceValue()
+        }
+        val error = CpuCounter.checkPerfEventSupport()
+        Assume.assumeTrue(error, error == null)
+    }
+
+    @After
+    fun after() {
+        perfHardenProp.resetIfOverridden()
+        if (shouldResetEnforce1) {
+            Shell.executeScriptSilent("setenforce 1")
+        }
+    }
+
+    /**
+     * Measures overhead of starting and stopping
+     *
+     * We can expect to see some portion of this impact measurements directtly.
+     */
+    @Test
+    fun startStopOnly() = CpuCounter().use { counter ->
+        counter.resetEvents(
+            listOf(
+                CpuCounter.Event.CpuCycles,
+                CpuCounter.Event.L1IMisses,
+                CpuCounter.Event.Instructions,
+            )
+        )
+        benchmarkRule.measureRepeated {
+            runWithTimingDisabled {
+                counter.reset()
+            }
+            counter.start()
+            counter.stop()
+        }
+    }
+
+    /**
+     * Measures full per measurement iteration cost
+     *
+     * This is important not because of direct intrusiveness to timing measurements, but because it
+     * may correlate with other intrusiveness, e.g. cache interference from reset/reading values
+     */
+    @Test
+    fun perIterationCost() = CpuCounter().use { counter ->
+        counter.resetEvents(
+            listOf(
+                CpuCounter.Event.CpuCycles,
+                CpuCounter.Event.L1IMisses,
+                CpuCounter.Event.Instructions,
+            )
+        )
+        var out = 0L
+        benchmarkRule.measureRepeated {
+            counter.reset()
+            counter.start()
+            counter.stop()
+            counter.read(values)
+            out += values.getValue(CpuCounter.Event.CpuCycles)
+            out += values.getValue(CpuCounter.Event.L1IMisses)
+            out += values.getValue(CpuCounter.Event.Instructions)
+        }
+    }
+}
diff --git a/benchmark/integration-tests/baselineprofile-flavors-consumer/build.gradle b/benchmark/integration-tests/baselineprofile-flavors-consumer/build.gradle
index 893b521..e2cef97 100644
--- a/benchmark/integration-tests/baselineprofile-flavors-consumer/build.gradle
+++ b/benchmark/integration-tests/baselineprofile-flavors-consumer/build.gradle
@@ -55,8 +55,13 @@
 }
 
 dependencies {
-    implementation(libs.kotlinStdlib)
-    implementation(libs.constraintLayout)
+
+    // Specifying build type dependencies is part of the test
+    debugImplementation(libs.kotlinStdlib)
+    debugImplementation(libs.constraintLayout)
+
+    releaseImplementation(libs.kotlinStdlib)
+    releaseImplementation(libs.constraintLayout)
 }
 
 baselineProfile {
diff --git a/biometric/biometric/src/test/resources/robolectric.properties b/biometric/biometric/src/test/resources/robolectric.properties
index 7946f01..69fde47 100644
--- a/biometric/biometric/src/test/resources/robolectric.properties
+++ b/biometric/biometric/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/bluetooth/bluetooth/api/current.txt b/bluetooth/bluetooth/api/current.txt
index d682668..cdcca53 100644
--- a/bluetooth/bluetooth/api/current.txt
+++ b/bluetooth/bluetooth/api/current.txt
@@ -71,5 +71,19 @@
   public static final class ScanFilter.Companion {
   }
 
+  public final class ScanResult {
+    method public androidx.bluetooth.BluetoothDevice getDevice();
+    method public androidx.bluetooth.BluetoothAddress getDeviceAddress();
+    method public byte[]? getManufacturerSpecificData(int manufacturerId);
+    method public byte[]? getServiceData(java.util.UUID serviceUuid);
+    method public java.util.List<java.util.UUID> getServiceUuids();
+    method public long getTimestampNanos();
+    method public boolean isConnectable();
+    property public final androidx.bluetooth.BluetoothDevice device;
+    property public final androidx.bluetooth.BluetoothAddress deviceAddress;
+    property public final java.util.List<java.util.UUID> serviceUuids;
+    property public final long timestampNanos;
+  }
+
 }
 
diff --git a/bluetooth/bluetooth/api/restricted_current.txt b/bluetooth/bluetooth/api/restricted_current.txt
index d682668..cdcca53 100644
--- a/bluetooth/bluetooth/api/restricted_current.txt
+++ b/bluetooth/bluetooth/api/restricted_current.txt
@@ -71,5 +71,19 @@
   public static final class ScanFilter.Companion {
   }
 
+  public final class ScanResult {
+    method public androidx.bluetooth.BluetoothDevice getDevice();
+    method public androidx.bluetooth.BluetoothAddress getDeviceAddress();
+    method public byte[]? getManufacturerSpecificData(int manufacturerId);
+    method public byte[]? getServiceData(java.util.UUID serviceUuid);
+    method public java.util.List<java.util.UUID> getServiceUuids();
+    method public long getTimestampNanos();
+    method public boolean isConnectable();
+    property public final androidx.bluetooth.BluetoothDevice device;
+    property public final androidx.bluetooth.BluetoothAddress deviceAddress;
+    property public final java.util.List<java.util.UUID> serviceUuids;
+    property public final long timestampNanos;
+  }
+
 }
 
diff --git a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt
new file mode 100644
index 0000000..7f488d7
--- /dev/null
+++ b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/ScanResultTest.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothManager
+import android.bluetooth.le.ScanResult as FwkScanResult
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.rule.GrantPermissionRule
+import java.util.UUID
+import junit.framework.TestCase.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class ScanResultTest {
+    @Rule
+    @JvmField
+    val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(
+        android.Manifest.permission.BLUETOOTH_CONNECT)
+
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val bluetoothManager: BluetoothManager =
+        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
+    private val bluetoothAdapter: BluetoothAdapter? = bluetoothManager.adapter
+
+    @Test
+    fun constructorWithFwkInstance() {
+        val address = "00:01:02:03:04:05"
+        val fwkBluetoothDevice = bluetoothAdapter!!.getRemoteDevice(address)
+        val timeStampNanos: Long = 1
+        val serviceUuid = UUID.randomUUID()
+
+        // TODO(kihongs) Find a way to create framework ScanRecord and use in test
+        val fwkScanResult = FwkScanResult(fwkBluetoothDevice, 1, 0, 0, 0, 0, 0, 0, null,
+            timeStampNanos)
+        val scanResult = ScanResult(fwkScanResult)
+
+        assertEquals(scanResult.device.name, BluetoothDevice(fwkBluetoothDevice).name)
+        assertEquals(scanResult.device.bondState, BluetoothDevice(fwkBluetoothDevice).bondState)
+        assertEquals(scanResult.deviceAddress.address, address)
+        assertEquals(scanResult.deviceAddress.addressType, AddressType.ADDRESS_TYPE_RANDOM)
+        assertEquals(scanResult.isConnectable(), true)
+        assertEquals(scanResult.timestampNanos, timeStampNanos)
+        assertEquals(scanResult.getManufacturerSpecificData(1), null)
+        assertEquals(scanResult.serviceUuids, emptyList<UUID>())
+        assertEquals(scanResult.getServiceData(serviceUuid), null)
+    }
+}
\ No newline at end of file
diff --git a/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt
new file mode 100644
index 0000000..ac79d4a
--- /dev/null
+++ b/bluetooth/bluetooth/src/main/java/androidx/bluetooth/ScanResult.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.bluetooth
+
+import android.bluetooth.le.ScanResult as FwkScanResult
+import android.os.ParcelUuid
+import java.util.UUID
+
+/**
+ * ScanResult for Bluetooth LE scan.
+ *
+ * The ScanResult class is used by Bluetooth LE applications to scan for and discover Bluetooth LE
+ * devices. When a Bluetooth LE application scans for devices, it will receive a list of ScanResult
+ * objects that contain information about the scanned devices. The application can then use this
+ * information to determine which devices it wants to connect to.
+ *
+ * @property device Remote device found
+ * @property deviceAddress Bluetooth address for the remote device found
+ * @property timestampNanos Device timestamp when the result was last seen
+ * @property serviceUuids A list of service UUIDs within advertisement that are used to identify the
+ * bluetooth GATT services.
+ *
+ */
+class ScanResult internal constructor(private val fwkScanResult: FwkScanResult) {
+    /** Remote Bluetooth device found. */
+    val device: BluetoothDevice
+        get() = BluetoothDevice(fwkScanResult.device)
+
+    // TODO(kihongs) Find a way to get address type from framework scan result
+    /** Bluetooth address for the remote device found. */
+    val deviceAddress: BluetoothAddress
+        get() = BluetoothAddress(fwkScanResult.device.address, AddressType.ADDRESS_TYPE_RANDOM)
+
+    /** Device timestamp when the advertisement was last seen. */
+    val timestampNanos: Long
+        get() = fwkScanResult.timestampNanos
+
+    /**
+     * Returns the manufacturer specific data associated with the manufacturer id.
+     *
+     * @param manufacturerId The manufacturer id of the scanned device
+     * @return the manufacturer specific data associated with the manufacturer id, or null if the
+     * manufacturer specific data is not present
+     */
+    fun getManufacturerSpecificData(manufacturerId: Int): ByteArray? {
+        return fwkScanResult.scanRecord?.getManufacturerSpecificData(manufacturerId)
+    }
+
+    /**
+     * A list of service UUIDs within advertisement that are used to identify the bluetooth GATT
+     * services.
+     */
+    val serviceUuids: List<UUID>
+        get() = fwkScanResult.scanRecord?.serviceUuids?.map { it.uuid }.orEmpty()
+
+    /**
+     * Returns the service data associated with the service UUID.
+     *
+     * @param serviceUuid The service UUID of the service data
+     * @return the service data associated with the specified service UUID, or null if the service
+     * UUID is not found
+     */
+    fun getServiceData(serviceUuid: UUID): ByteArray? {
+        return fwkScanResult.scanRecord?.getServiceData(ParcelUuid(serviceUuid))
+    }
+
+    /**
+     * Checks if this object represents connectable scan result.
+     *
+     * @return true if the scanned device is connectable; false otherwise
+     */
+    fun isConnectable(): Boolean {
+        return fwkScanResult.isConnectable
+    }
+}
\ No newline at end of file
diff --git a/browser/browser/src/test/resources/robolectric.properties b/browser/browser/src/test/resources/robolectric.properties
index 7946f01..69fde47 100644
--- a/browser/browser/src/test/resources/robolectric.properties
+++ b/browser/browser/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/AndroidXImplPluginTest.kt b/buildSrc-tests/src/test/java/androidx/build/AndroidXImplPluginTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/AndroidXImplPluginTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/AndroidXImplPluginTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/KmpPlatformsTest.kt b/buildSrc-tests/src/test/java/androidx/build/KmpPlatformsTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/KmpPlatformsTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/KmpPlatformsTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/LibraryVersionsServiceTest.kt b/buildSrc-tests/src/test/java/androidx/build/LibraryVersionsServiceTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/LibraryVersionsServiceTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/LibraryVersionsServiceTest.kt
diff --git a/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt b/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt
new file mode 100644
index 0000000..2e92435
--- /dev/null
+++ b/buildSrc-tests/src/test/java/androidx/build/MavenUploadHelperTest.kt
@@ -0,0 +1,738 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.build
+
+import androidx.build.testutils.POM_COLLECTION
+import androidx.build.testutils.POM_COLLECTION_JVM
+import androidx.build.testutils.XmlProviderImpl
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class MavenUploadHelperTest {
+
+    @Test
+    fun insertDefaultMultiplatformDependenciesTest() {
+        val pom = XmlProviderImpl(POM_COLLECTION)
+
+        /* ktlint-disable max-line-length */
+
+        // Expect that collection-jvm has been inserted in <dependencies>.
+        val expected = """<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>androidx.collection</groupId>
+  <artifactId>collection</artifactId>
+  <version>1.3.0-alpha05</version>
+  <name>collections</name>
+  <description>Standalone efficient collections.</description>
+  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha05</url>
+  <inceptionYear>2018</inceptionYear>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>The Android Open Source Project</name>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
+    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>1.8.21</version>
+      <scope>runtime</scope>
+    </dependency>
+    <dependency>
+      <groupId>androidx.collection</groupId>
+      <artifactId>collection-jvm</artifactId>
+      <version>1.3.0-alpha05</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>
+"""
+        /* ktlint-enable max-line-length */
+
+        insertDefaultMultiplatformDependencies(pom, "jvm")
+
+        val actual = pom.toString()
+        assertEquals(expected, actual)
+    }
+
+    @Test
+    fun testSortPomDependencies() {
+        val pom = POM_COLLECTION_JVM
+
+        /* ktlint-disable max-line-length */
+
+        // Expect that elements in <dependencies> are sorted alphabetically.
+        val expected = """<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!-- This module was also published with a richer model, Gradle metadata,  -->
+  <!-- which should be used instead. Do not delete the following line which  -->
+  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
+  <!-- that they should prefer consuming it instead. -->
+  <!-- do_not_remove: published-with-gradle-metadata -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>androidx.collection</groupId>
+  <artifactId>collection-jvm</artifactId>
+  <version>1.3.0-alpha05</version>
+  <name>collections</name>
+  <description>Standalone efficient collections.</description>
+  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha05</url>
+  <inceptionYear>2018</inceptionYear>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>The Android Open Source Project</name>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
+    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
+  </scm>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>androidx.collection</groupId>
+        <artifactId>collection-ktx</artifactId>
+        <version>1.3.0-alpha01</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>androidx.annotation</groupId>
+      <artifactId>annotation</artifactId>
+      <version>1.3.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>1.8.21</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>"""
+        /* ktlint-enable max-line-length */
+
+        val actual = sortPomDependencies(pom)
+        assertEquals(expected, actual)
+    }
+
+    @Test
+    fun testSortGradleMetadataDependencies() {
+        /* ktlint-disable max-line-length */
+        val metadata = """
+{
+  "formatVersion": "1.1",
+  "component": {
+    "url": "../../collection/1.3.0-alpha01/collection-1.3.0-alpha01.module",
+    "group": "androidx.collection",
+    "module": "collection",
+    "version": "1.3.0-alpha01",
+    "attributes": {
+      "org.gradle.status": "release"
+    }
+  },
+  "createdBy": {
+    "gradle": {
+      "version": "7.4"
+    }
+  },
+  "variants": [
+    {
+      "name": "jvmApiElements-published",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.libraryelements": "jar",
+        "org.gradle.usage": "java-api",
+        "org.jetbrains.kotlin.platform.type": "jvm"
+      },
+      "dependencies": [
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        },
+        {
+          "group": "androidx.annotation",
+          "module": "annotation",
+          "version": {
+            "requires": "1.3.0"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib-common",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "collection-jvm-1.3.0-alpha01.jar",
+          "url": "collection-jvm-1.3.0-alpha01.jar",
+          "size": 42271,
+          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
+          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
+          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
+          "md5": "309042f77be5772d725180056e5e97e9"
+        }
+      ]
+    },
+    {
+      "name": "jvmRuntimeElements-published",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.libraryelements": "jar",
+        "org.gradle.usage": "java-runtime",
+        "org.jetbrains.kotlin.platform.type": "jvm"
+      },
+      "dependencies": [
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        },
+        {
+          "group": "androidx.annotation",
+          "module": "annotation",
+          "version": {
+            "requires": "1.3.0"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib-common",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "collection-jvm-1.3.0-alpha01.jar",
+          "url": "collection-jvm-1.3.0-alpha01.jar",
+          "size": 42271,
+          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
+          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
+          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
+          "md5": "309042f77be5772d725180056e5e97e9"
+        }
+      ]
+    }
+  ]
+}
+        """.trimIndent()
+
+        // Expect that elements in "dependencies" are sorted alphabetically.
+        val expected = """
+{
+  "formatVersion": "1.1",
+  "component": {
+    "url": "../../collection/1.3.0-alpha01/collection-1.3.0-alpha01.module",
+    "group": "androidx.collection",
+    "module": "collection",
+    "version": "1.3.0-alpha01",
+    "attributes": {
+      "org.gradle.status": "release"
+    }
+  },
+  "createdBy": {
+    "gradle": {
+      "version": "7.4"
+    }
+  },
+  "variants": [
+    {
+      "name": "jvmApiElements-published",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.libraryelements": "jar",
+        "org.gradle.usage": "java-api",
+        "org.jetbrains.kotlin.platform.type": "jvm"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.annotation",
+          "module": "annotation",
+          "version": {
+            "requires": "1.3.0"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib-common",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "collection-jvm-1.3.0-alpha01.jar",
+          "url": "collection-jvm-1.3.0-alpha01.jar",
+          "size": 42271,
+          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
+          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
+          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
+          "md5": "309042f77be5772d725180056e5e97e9"
+        }
+      ]
+    },
+    {
+      "name": "jvmRuntimeElements-published",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.libraryelements": "jar",
+        "org.gradle.usage": "java-runtime",
+        "org.jetbrains.kotlin.platform.type": "jvm"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.annotation",
+          "module": "annotation",
+          "version": {
+            "requires": "1.3.0"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib-common",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "collection-jvm-1.3.0-alpha01.jar",
+          "url": "collection-jvm-1.3.0-alpha01.jar",
+          "size": 42271,
+          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
+          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
+          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
+          "md5": "309042f77be5772d725180056e5e97e9"
+        }
+      ]
+    }
+  ]
+}
+        """.trimIndent()
+        /* ktlint-enable max-line-length */
+
+        val actual = sortGradleMetadataDependencies(metadata)
+        assertEquals(expected, actual)
+    }
+
+    @Test
+    fun testSortGradleMetadataDependenciesWithConstraints() {
+        /* ktlint-disable max-line-length */
+        val metadata = """
+{
+  "formatVersion": "1.1",
+  "component": {
+    "group": "androidx.activity",
+    "module": "activity-ktx",
+    "version": "1.5.0-alpha03",
+    "attributes": {
+      "org.gradle.status": "release"
+    }
+  },
+  "createdBy": {
+    "gradle": {
+      "version": "7.4"
+    }
+  },
+  "variants": [
+    {
+      "name": "releaseVariantReleaseApiPublication",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.libraryelements": "aar",
+        "org.gradle.usage": "java-api"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.activity",
+          "module": "activity",
+          "version": {
+            "requires": "1.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.core",
+          "module": "core-ktx",
+          "version": {
+            "requires": "1.1.0"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-runtime-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-viewmodel-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.savedstate",
+          "module": "savedstate-ktx",
+          "version": {
+            "requires": "1.2.0-alpha01"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03.aar",
+          "url": "activity-ktx-1.5.0-alpha03.aar",
+          "size": 31645,
+          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
+          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
+          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
+          "md5": "186145646501129b4bdfd0f804ba96d9"
+        }
+      ]
+    },
+    {
+      "name": "releaseVariantReleaseRuntimePublication",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.libraryelements": "aar",
+        "org.gradle.usage": "java-runtime"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.activity",
+          "module": "activity",
+          "version": {
+            "requires": "1.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.core",
+          "module": "core-ktx",
+          "version": {
+            "requires": "1.1.0"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-runtime-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-viewmodel-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.savedstate",
+          "module": "savedstate-ktx",
+          "version": {
+            "requires": "1.2.0-alpha01"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03.aar",
+          "url": "activity-ktx-1.5.0-alpha03.aar",
+          "size": 31645,
+          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
+          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
+          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
+          "md5": "186145646501129b4bdfd0f804ba96d9"
+        }
+      ]
+    },
+    {
+      "name": "sourcesElements",
+      "attributes": {
+        "org.gradle.category": "documentation",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.docstype": "sources",
+        "org.gradle.usage": "java-runtime"
+      },
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03-sources.jar",
+          "url": "activity-ktx-1.5.0-alpha03-sources.jar",
+          "size": 7897,
+          "sha512": "c484c2a29fdd1896cbdc3613c660eb83acfd8371a800eb8950783a6011623011a336cf2c9c3258119c1f22cb5ea6d9a1513125284cc3be9064a61a38afd0dd30",
+          "sha256": "a66e48c18dda88d8d94f19b4250067f834d9db01ca8390c26e4530bfd2ad015e",
+          "sha1": "cc99180305811c77b3fe5e10bfd099e8637bec44",
+          "md5": "81c0906fb7e820a6ff164add91827fe4"
+        }
+      ]
+    }
+  ]
+}
+        """.trimIndent()
+
+        // Expect that elements in "dependencies" are sorted alphabetically.
+        val expected = """
+{
+  "formatVersion": "1.1",
+  "component": {
+    "group": "androidx.activity",
+    "module": "activity-ktx",
+    "version": "1.5.0-alpha03",
+    "attributes": {
+      "org.gradle.status": "release"
+    }
+  },
+  "createdBy": {
+    "gradle": {
+      "version": "7.4"
+    }
+  },
+  "variants": [
+    {
+      "name": "releaseVariantReleaseApiPublication",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.libraryelements": "aar",
+        "org.gradle.usage": "java-api"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.activity",
+          "module": "activity",
+          "version": {
+            "requires": "1.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.core",
+          "module": "core-ktx",
+          "version": {
+            "requires": "1.1.0"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-runtime-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-viewmodel-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.savedstate",
+          "module": "savedstate-ktx",
+          "version": {
+            "requires": "1.2.0-alpha01"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03.aar",
+          "url": "activity-ktx-1.5.0-alpha03.aar",
+          "size": 31645,
+          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
+          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
+          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
+          "md5": "186145646501129b4bdfd0f804ba96d9"
+        }
+      ]
+    },
+    {
+      "name": "releaseVariantReleaseRuntimePublication",
+      "attributes": {
+        "org.gradle.category": "library",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.libraryelements": "aar",
+        "org.gradle.usage": "java-runtime"
+      },
+      "dependencies": [
+        {
+          "group": "androidx.activity",
+          "module": "activity",
+          "version": {
+            "requires": "1.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.core",
+          "module": "core-ktx",
+          "version": {
+            "requires": "1.1.0"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-runtime-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "androidx.lifecycle",
+          "module": "lifecycle-viewmodel-ktx",
+          "version": {
+            "requires": "2.5.0-alpha03"
+          }
+        },
+        {
+          "group": "androidx.savedstate",
+          "module": "savedstate-ktx",
+          "version": {
+            "requires": "1.2.0-alpha01"
+          },
+          "reason": "Mirror activity dependency graph for -ktx artifacts"
+        },
+        {
+          "group": "org.jetbrains.kotlin",
+          "module": "kotlin-stdlib",
+          "version": {
+            "requires": "1.6.10"
+          }
+        }
+      ],
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03.aar",
+          "url": "activity-ktx-1.5.0-alpha03.aar",
+          "size": 31645,
+          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
+          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
+          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
+          "md5": "186145646501129b4bdfd0f804ba96d9"
+        }
+      ]
+    },
+    {
+      "name": "sourcesElements",
+      "attributes": {
+        "org.gradle.category": "documentation",
+        "org.gradle.dependency.bundling": "external",
+        "org.gradle.docstype": "sources",
+        "org.gradle.usage": "java-runtime"
+      },
+      "files": [
+        {
+          "name": "activity-ktx-1.5.0-alpha03-sources.jar",
+          "url": "activity-ktx-1.5.0-alpha03-sources.jar",
+          "size": 7897,
+          "sha512": "c484c2a29fdd1896cbdc3613c660eb83acfd8371a800eb8950783a6011623011a336cf2c9c3258119c1f22cb5ea6d9a1513125284cc3be9064a61a38afd0dd30",
+          "sha256": "a66e48c18dda88d8d94f19b4250067f834d9db01ca8390c26e4530bfd2ad015e",
+          "sha1": "cc99180305811c77b3fe5e10bfd099e8637bec44",
+          "md5": "81c0906fb7e820a6ff164add91827fe4"
+        }
+      ]
+    }
+  ]
+}
+        """.trimIndent()
+        /* ktlint-enable max-line-length */
+
+        val actual = sortGradleMetadataDependencies(metadata)
+        assertEquals(expected, actual)
+    }
+}
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/SdkResourceGeneratorTest.kt b/buildSrc-tests/src/test/java/androidx/build/SdkResourceGeneratorTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/SdkResourceGeneratorTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/SdkResourceGeneratorTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/SettingsParserTest.kt b/buildSrc-tests/src/test/java/androidx/build/SettingsParserTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/SettingsParserTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/SettingsParserTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/VersionTest.kt b/buildSrc-tests/src/test/java/androidx/build/VersionTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/VersionTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/VersionTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTaskTest.kt b/buildSrc-tests/src/test/java/androidx/build/buildInfo/CreateLibraryBuildInfoFileTaskTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTaskTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/buildInfo/CreateLibraryBuildInfoFileTaskTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/checkapi/CheckApiTest.kt b/buildSrc-tests/src/test/java/androidx/build/checkapi/CheckApiTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/checkapi/CheckApiTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/checkapi/CheckApiTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AffectedModuleDetectorImplTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AttachLogsTestRule.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AttachLogsTestRule.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/AttachLogsTestRule.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/AttachLogsTestRule.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/BuildPropParserTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/BuildPropParserTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/BuildPropParserTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/BuildPropParserTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/ChangeInfoGitClientTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/ChangeInfoGitClientTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/ChangeInfoGitClientTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/ChangeInfoGitClientTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitRunnerGitClientTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/GitRunnerGitClientTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/GitRunnerGitClientTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/GitRunnerGitClientTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/ProjectGraphTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyTracker/ProjectGraphTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyTracker/ProjectGraphTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyTracker/ProjectGraphTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/dependencyallowlist/DependencyAllowlistTest.kt b/buildSrc-tests/src/test/java/androidx/build/dependencyallowlist/DependencyAllowlistTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/dependencyallowlist/DependencyAllowlistTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/dependencyallowlist/DependencyAllowlistTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/metalava/CheckApiCompatibilityTaskTest.kt b/buildSrc-tests/src/test/java/androidx/build/metalava/CheckApiCompatibilityTaskTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/metalava/CheckApiCompatibilityTaskTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/metalava/CheckApiCompatibilityTaskTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/metalava/UpdateApiTaskTest.kt b/buildSrc-tests/src/test/java/androidx/build/metalava/UpdateApiTaskTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/metalava/UpdateApiTaskTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/metalava/UpdateApiTaskTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/playground/VerifyPlaygroundGradleConfigurationTaskTest.kt b/buildSrc-tests/src/test/java/androidx/build/playground/VerifyPlaygroundGradleConfigurationTaskTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/playground/VerifyPlaygroundGradleConfigurationTaskTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/playground/VerifyPlaygroundGradleConfigurationTaskTest.kt
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt b/buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
similarity index 100%
rename from buildSrc-tests/src/test/kotlin/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
rename to buildSrc-tests/src/test/java/androidx/build/testConfiguration/AndroidTestConfigBuilderTest.kt
diff --git a/buildSrc-tests/src/test/java/androidx/build/testutils/PomTestData.kt b/buildSrc-tests/src/test/java/androidx/build/testutils/PomTestData.kt
new file mode 100644
index 0000000..14a2842
--- /dev/null
+++ b/buildSrc-tests/src/test/java/androidx/build/testutils/PomTestData.kt
@@ -0,0 +1,124 @@
+/*
+ * 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.build.testutils
+
+/* ktlint-disable max-line-length */
+
+/**
+ * POM for androidx.collection:collection:1.3.0-alpha04, which is a KMP library anchor artifact.
+ */
+const val POM_COLLECTION = """<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!-- This module was also published with a richer model, Gradle metadata,  -->
+  <!-- which should be used instead. Do not delete the following line which  -->
+  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
+  <!-- that they should prefer consuming it instead. -->
+  <!-- do_not_remove: published-with-gradle-metadata -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>androidx.collection</groupId>
+  <artifactId>collection</artifactId>
+  <version>1.3.0-alpha05</version>
+  <name>collections</name>
+  <description>Standalone efficient collections.</description>
+  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha05</url>
+  <inceptionYear>2018</inceptionYear>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>The Android Open Source Project</name>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
+    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>1.8.21</version>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+</project>"""
+
+/**
+ * POM for androidx.collection:collection-jvm:1.3.0-alpha04, which is a KMP library targeted to JVM.
+ */
+const val POM_COLLECTION_JVM = """<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!-- This module was also published with a richer model, Gradle metadata,  -->
+  <!-- which should be used instead. Do not delete the following line which  -->
+  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
+  <!-- that they should prefer consuming it instead. -->
+  <!-- do_not_remove: published-with-gradle-metadata -->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>androidx.collection</groupId>
+  <artifactId>collection-jvm</artifactId>
+  <version>1.3.0-alpha05</version>
+  <name>collections</name>
+  <description>Standalone efficient collections.</description>
+  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha05</url>
+  <inceptionYear>2018</inceptionYear>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>The Android Open Source Project</name>
+    </developer>
+  </developers>
+  <scm>
+    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
+    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
+  </scm>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>androidx.collection</groupId>
+        <artifactId>collection-ktx</artifactId>
+        <version>1.3.0-alpha01</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>androidx.annotation</groupId>
+      <artifactId>annotation</artifactId>
+      <version>1.3.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>1.8.21</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+</project>"""
+
+/* ktlint-enable max-line-length */
diff --git a/buildSrc-tests/src/test/java/androidx/build/testutils/XmlProviderImpl.java b/buildSrc-tests/src/test/java/androidx/build/testutils/XmlProviderImpl.java
new file mode 100644
index 0000000..7b8f999
--- /dev/null
+++ b/buildSrc-tests/src/test/java/androidx/build/testutils/XmlProviderImpl.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2010 the original author or authors.
+ *
+ * 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.build.testutils;
+
+import org.gradle.api.Action;
+import org.gradle.api.XmlProvider;
+import org.gradle.api.internal.DomNode;
+import org.gradle.internal.SystemProperties;
+import org.gradle.internal.UncheckedException;
+import org.gradle.util.internal.GUtil;
+import org.gradle.util.internal.TextUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import groovy.util.IndentPrinter;
+import groovy.util.Node;
+import groovy.xml.XmlNodePrinter;
+import groovy.xml.XmlParser;
+
+/**
+ * Test fixture for Gradle's XmlProvider.
+ * <p>
+ * Adapted from org.gradle.internal.xml.XmlTransformer.java in the Android Studio repo.
+ */
+@SuppressWarnings({"NullableProblems", "unused"})
+public class XmlProviderImpl implements XmlProvider {
+    private final String indentation = "  ";
+
+    private StringBuilder builder;
+    private Node node;
+    private String stringValue;
+    private Element element;
+    private String publicId;
+    private String systemId;
+
+    public XmlProviderImpl(String original) {
+        this.stringValue = original;
+    }
+
+    public XmlProviderImpl(Node original) {
+        this.node = original;
+    }
+
+    public XmlProviderImpl(DomNode original) {
+        this.node = original;
+        publicId = original.getPublicId();
+        systemId = original.getSystemId();
+    }
+
+    public void apply(Iterable<Action<? super XmlProvider>> actions) {
+        for (Action<? super XmlProvider> action : actions) {
+            action.execute(this);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringWriter writer = new StringWriter();
+        writeTo(writer);
+        return writer.toString();
+    }
+
+    public void writeTo(Writer writer) {
+        doWriteTo(writer, null);
+    }
+
+    public void writeTo(Writer writer, String encoding) {
+        doWriteTo(writer, encoding);
+    }
+
+    public void writeTo(File file) {
+        try (OutputStream outputStream = new BufferedOutputStream(
+                Files.newOutputStream(file.toPath()))) {
+            writeTo(outputStream);
+        } catch (IOException e) {
+            throw UncheckedException.throwAsUncheckedException(e);
+        }
+    }
+
+    public void writeTo(OutputStream stream) {
+        try(Writer writer = new BufferedWriter(new OutputStreamWriter(
+                stream, StandardCharsets.UTF_8))) {
+            doWriteTo(writer, "UTF-8");
+            writer.flush();
+        } catch (IOException e) {
+            throw UncheckedException.throwAsUncheckedException(e);
+        }
+    }
+
+    @Override
+    public StringBuilder asString() {
+        if (builder == null) {
+            builder = new StringBuilder(toString());
+            node = null;
+            element = null;
+        }
+        return builder;
+    }
+
+    @Override
+    public Node asNode() {
+        if (node == null) {
+            try {
+                node = new XmlParser().parseText(toString());
+            } catch (Exception e) {
+                throw UncheckedException.throwAsUncheckedException(e);
+            }
+            builder = null;
+            element = null;
+        }
+        return node;
+    }
+
+    @Override
+    public Element asElement() {
+        if (element == null) {
+            Document document;
+            try {
+                document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+                        new InputSource(new StringReader(toString())));
+            } catch (Exception e) {
+                throw UncheckedException.throwAsUncheckedException(e);
+            }
+            element = document.getDocumentElement();
+            builder = null;
+            node = null;
+        }
+        return element;
+    }
+
+    private void doWriteTo(Writer writer, String encoding) {
+        writeXmlDeclaration(writer, encoding);
+
+        try {
+            if (node != null) {
+                printNode(node, writer);
+            } else if (element != null) {
+                printDomNode(element, writer);
+            } else if (builder != null) {
+                writer.append(TextUtil.toPlatformLineSeparators(stripXmlDeclaration(builder)));
+            } else {
+                writer.append(TextUtil.toPlatformLineSeparators(stripXmlDeclaration(stringValue)));
+            }
+        } catch (IOException e) {
+            throw UncheckedException.throwAsUncheckedException(e);
+        }
+    }
+
+    private void printNode(Node node, Writer writer) {
+        final PrintWriter printWriter = new PrintWriter(writer);
+        if (GUtil.isTrue(publicId)) {
+            printWriter.format("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">%n", node.name(), publicId,
+                    systemId);
+        }
+        IndentPrinter indentPrinter = new IndentPrinter(printWriter, indentation) {
+            @Override
+            public void println() {
+                printWriter.println();
+            }
+
+            @Override
+            public void flush() {
+                // for performance, ignore flushes
+            }
+        };
+        XmlNodePrinter nodePrinter = new XmlNodePrinter(indentPrinter);
+        nodePrinter.setPreserveWhitespace(true);
+        nodePrinter.print(node);
+        printWriter.flush();
+    }
+
+    private void printDomNode(org.w3c.dom.Node node, Writer destination) {
+        removeEmptyTextNodes(node); // empty text nodes hinder subsequent formatting
+        int indentAmount = determineIndentAmount();
+
+        try {
+            TransformerFactory factory = TransformerFactory.newInstance();
+            try {
+                factory.setAttribute("indent-number", indentAmount);
+            } catch (IllegalArgumentException ignored) {
+                /* unsupported by this transformer */
+            }
+
+            javax.xml.transform.Transformer transformer = factory.newTransformer();
+            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+            if (GUtil.isTrue(publicId)) {
+                transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, publicId);
+                transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, systemId);
+            }
+            try {
+                // some impls support this but not factory.setAttribute("indent-number")
+                transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
+                        String.valueOf(indentAmount));
+            } catch (IllegalArgumentException ignored) {
+                /* unsupported by this transformer */
+            }
+
+            transformer.transform(new DOMSource(node), new StreamResult(destination));
+        } catch (TransformerException e) {
+            throw UncheckedException.throwAsUncheckedException(e);
+        }
+    }
+
+    private int determineIndentAmount() {
+        return indentation.length(); // assume indentation uses spaces
+    }
+
+    private void removeEmptyTextNodes(org.w3c.dom.Node node) {
+        org.w3c.dom.NodeList children = node.getChildNodes();
+
+        for (int i = 0; i < children.getLength(); i++) {
+            org.w3c.dom.Node child = children.item(i);
+            if (child.getNodeType() == org.w3c.dom.Node.TEXT_NODE
+                    && child.getNodeValue().trim().length() == 0) {
+                node.removeChild(child);
+                i--;
+            } else {
+                removeEmptyTextNodes(child);
+            }
+        }
+    }
+
+    private void writeXmlDeclaration(Writer writer, String encoding) {
+        try {
+            writer.write("<?xml version=\"1.0\"");
+            if (encoding != null) {
+                writer.write(" encoding=\"");
+                writer.write(encoding);
+                writer.write("\"");
+            }
+            writer.write("?>");
+            writer.write(SystemProperties.getInstance().getLineSeparator());
+        } catch (IOException e) {
+            throw UncheckedException.throwAsUncheckedException(e);
+        }
+    }
+    private boolean hasXmlDeclaration(String xml) {
+        // XML declarations must be located at first position of first line
+        return xml.startsWith("<?xml");
+    }
+
+    private String stripXmlDeclaration(CharSequence sequence) {
+        String str = sequence.toString();
+        if (hasXmlDeclaration(str)) {
+            str = str.substring(str.indexOf("?>") + 2);
+            str = str.stripLeading();
+        }
+        return str;
+    }
+}
diff --git a/buildSrc-tests/src/test/kotlin/androidx/build/MavenUploadHelperTest.kt b/buildSrc-tests/src/test/kotlin/androidx/build/MavenUploadHelperTest.kt
deleted file mode 100644
index 4f91ae3..0000000
--- a/buildSrc-tests/src/test/kotlin/androidx/build/MavenUploadHelperTest.kt
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.build
-
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-
-@RunWith(JUnit4::class)
-class MavenUploadHelperTest {
-
-    @Test
-    fun testSortPomDependencies() {
-        /* ktlint-disable max-line-length */
-        val pom = """<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <!-- This module was also published with a richer model, Gradle metadata,  -->
-  <!-- which should be used instead. Do not delete the following line which  -->
-  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
-  <!-- that they should prefer consuming it instead. -->
-  <!-- do_not_remove: published-with-gradle-metadata -->
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>androidx.collection</groupId>
-  <artifactId>collection-jvm</artifactId>
-  <version>1.3.0-alpha01</version>
-  <name>Android Support Library collections</name>
-  <description>Standalone efficient collections.</description>
-  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha01</url>
-  <inceptionYear>2018</inceptionYear>
-  <licenses>
-    <license>
-      <name>The Apache Software License, Version 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-      <distribution>repo</distribution>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>The Android Open Source Project</name>
-    </developer>
-  </developers>
-  <scm>
-    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
-    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <groupId>org.jetbrains.kotlin</groupId>
-      <artifactId>kotlin-stdlib-common</artifactId>
-      <version>1.6.10</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jetbrains.kotlin</groupId>
-      <artifactId>kotlin-stdlib</artifactId>
-      <version>1.6.10</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>androidx.annotation</groupId>
-      <artifactId>annotation</artifactId>
-      <version>1.3.0</version>
-      <scope>compile</scope>
-    </dependency>
-  </dependencies>
-</project>"""
-
-        // Expect that elements in <dependencies> are sorted alphabetically.
-        val expected = """<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <!-- This module was also published with a richer model, Gradle metadata,  -->
-  <!-- which should be used instead. Do not delete the following line which  -->
-  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
-  <!-- that they should prefer consuming it instead. -->
-  <!-- do_not_remove: published-with-gradle-metadata -->
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>androidx.collection</groupId>
-  <artifactId>collection-jvm</artifactId>
-  <version>1.3.0-alpha01</version>
-  <name>Android Support Library collections</name>
-  <description>Standalone efficient collections.</description>
-  <url>https://developer.android.com/jetpack/androidx/releases/collection#1.3.0-alpha01</url>
-  <inceptionYear>2018</inceptionYear>
-  <licenses>
-    <license>
-      <name>The Apache Software License, Version 2.0</name>
-      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
-      <distribution>repo</distribution>
-    </license>
-  </licenses>
-  <developers>
-    <developer>
-      <name>The Android Open Source Project</name>
-    </developer>
-  </developers>
-  <scm>
-    <connection>scm:git:https://android.googlesource.com/platform/frameworks/support</connection>
-    <url>https://cs.android.com/androidx/platform/frameworks/support</url>
-  </scm>
-  <dependencies>
-    <dependency>
-      <groupId>androidx.annotation</groupId>
-      <artifactId>annotation</artifactId>
-      <version>1.3.0</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jetbrains.kotlin</groupId>
-      <artifactId>kotlin-stdlib</artifactId>
-      <version>1.6.10</version>
-      <scope>compile</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.jetbrains.kotlin</groupId>
-      <artifactId>kotlin-stdlib-common</artifactId>
-      <version>1.6.10</version>
-      <scope>compile</scope>
-    </dependency>
-  </dependencies>
-</project>"""
-        /* ktlint-enable max-line-length */
-
-        val actual = sortPomDependencies(pom)
-        assertEquals(expected, actual)
-    }
-
-    @Test
-    fun testSortGradleMetadataDependencies() {
-        /* ktlint-disable max-line-length */
-        val metadata = """
-{
-  "formatVersion": "1.1",
-  "component": {
-    "url": "../../collection/1.3.0-alpha01/collection-1.3.0-alpha01.module",
-    "group": "androidx.collection",
-    "module": "collection",
-    "version": "1.3.0-alpha01",
-    "attributes": {
-      "org.gradle.status": "release"
-    }
-  },
-  "createdBy": {
-    "gradle": {
-      "version": "7.4"
-    }
-  },
-  "variants": [
-    {
-      "name": "jvmApiElements-published",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.libraryelements": "jar",
-        "org.gradle.usage": "java-api",
-        "org.jetbrains.kotlin.platform.type": "jvm"
-      },
-      "dependencies": [
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        },
-        {
-          "group": "androidx.annotation",
-          "module": "annotation",
-          "version": {
-            "requires": "1.3.0"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib-common",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "collection-jvm-1.3.0-alpha01.jar",
-          "url": "collection-jvm-1.3.0-alpha01.jar",
-          "size": 42271,
-          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
-          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
-          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
-          "md5": "309042f77be5772d725180056e5e97e9"
-        }
-      ]
-    },
-    {
-      "name": "jvmRuntimeElements-published",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.libraryelements": "jar",
-        "org.gradle.usage": "java-runtime",
-        "org.jetbrains.kotlin.platform.type": "jvm"
-      },
-      "dependencies": [
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        },
-        {
-          "group": "androidx.annotation",
-          "module": "annotation",
-          "version": {
-            "requires": "1.3.0"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib-common",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "collection-jvm-1.3.0-alpha01.jar",
-          "url": "collection-jvm-1.3.0-alpha01.jar",
-          "size": 42271,
-          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
-          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
-          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
-          "md5": "309042f77be5772d725180056e5e97e9"
-        }
-      ]
-    }
-  ]
-}
-        """.trimIndent()
-
-        // Expect that elements in "dependencies" are sorted alphabetically.
-        val expected = """
-{
-  "formatVersion": "1.1",
-  "component": {
-    "url": "../../collection/1.3.0-alpha01/collection-1.3.0-alpha01.module",
-    "group": "androidx.collection",
-    "module": "collection",
-    "version": "1.3.0-alpha01",
-    "attributes": {
-      "org.gradle.status": "release"
-    }
-  },
-  "createdBy": {
-    "gradle": {
-      "version": "7.4"
-    }
-  },
-  "variants": [
-    {
-      "name": "jvmApiElements-published",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.libraryelements": "jar",
-        "org.gradle.usage": "java-api",
-        "org.jetbrains.kotlin.platform.type": "jvm"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.annotation",
-          "module": "annotation",
-          "version": {
-            "requires": "1.3.0"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib-common",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "collection-jvm-1.3.0-alpha01.jar",
-          "url": "collection-jvm-1.3.0-alpha01.jar",
-          "size": 42271,
-          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
-          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
-          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
-          "md5": "309042f77be5772d725180056e5e97e9"
-        }
-      ]
-    },
-    {
-      "name": "jvmRuntimeElements-published",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.libraryelements": "jar",
-        "org.gradle.usage": "java-runtime",
-        "org.jetbrains.kotlin.platform.type": "jvm"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.annotation",
-          "module": "annotation",
-          "version": {
-            "requires": "1.3.0"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib-common",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "collection-jvm-1.3.0-alpha01.jar",
-          "url": "collection-jvm-1.3.0-alpha01.jar",
-          "size": 42271,
-          "sha512": "b01746682f5499426492ed56cfa10e863b181f0a94e1c97de935a1d68bc1a8da9b60bbc670a71642e4c4ebde0cedbed42f08f6b305bbfa7270b3b1fa76059fa6",
-          "sha256": "647d39d1ef35b45ff9b4c4b2afd7b0280431223142ededb4ee2d3ff73eb2657a",
-          "sha1": "11cbbdeaa0540d0cef16567781a99cdf7b34b242",
-          "md5": "309042f77be5772d725180056e5e97e9"
-        }
-      ]
-    }
-  ]
-}
-        """.trimIndent()
-        /* ktlint-enable max-line-length */
-
-        val actual = sortGradleMetadataDependencies(metadata)
-        assertEquals(expected, actual)
-    }
-
-    @Test
-    fun testSortGradleMetadataDependenciesWithConstraints() {
-        /* ktlint-disable max-line-length */
-        val metadata = """
-{
-  "formatVersion": "1.1",
-  "component": {
-    "group": "androidx.activity",
-    "module": "activity-ktx",
-    "version": "1.5.0-alpha03",
-    "attributes": {
-      "org.gradle.status": "release"
-    }
-  },
-  "createdBy": {
-    "gradle": {
-      "version": "7.4"
-    }
-  },
-  "variants": [
-    {
-      "name": "releaseVariantReleaseApiPublication",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.libraryelements": "aar",
-        "org.gradle.usage": "java-api"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.activity",
-          "module": "activity",
-          "version": {
-            "requires": "1.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.core",
-          "module": "core-ktx",
-          "version": {
-            "requires": "1.1.0"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-runtime-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-viewmodel-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.savedstate",
-          "module": "savedstate-ktx",
-          "version": {
-            "requires": "1.2.0-alpha01"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03.aar",
-          "url": "activity-ktx-1.5.0-alpha03.aar",
-          "size": 31645,
-          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
-          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
-          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
-          "md5": "186145646501129b4bdfd0f804ba96d9"
-        }
-      ]
-    },
-    {
-      "name": "releaseVariantReleaseRuntimePublication",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.libraryelements": "aar",
-        "org.gradle.usage": "java-runtime"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.activity",
-          "module": "activity",
-          "version": {
-            "requires": "1.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.core",
-          "module": "core-ktx",
-          "version": {
-            "requires": "1.1.0"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-runtime-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-viewmodel-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.savedstate",
-          "module": "savedstate-ktx",
-          "version": {
-            "requires": "1.2.0-alpha01"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03.aar",
-          "url": "activity-ktx-1.5.0-alpha03.aar",
-          "size": 31645,
-          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
-          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
-          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
-          "md5": "186145646501129b4bdfd0f804ba96d9"
-        }
-      ]
-    },
-    {
-      "name": "sourcesElements",
-      "attributes": {
-        "org.gradle.category": "documentation",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.docstype": "sources",
-        "org.gradle.usage": "java-runtime"
-      },
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03-sources.jar",
-          "url": "activity-ktx-1.5.0-alpha03-sources.jar",
-          "size": 7897,
-          "sha512": "c484c2a29fdd1896cbdc3613c660eb83acfd8371a800eb8950783a6011623011a336cf2c9c3258119c1f22cb5ea6d9a1513125284cc3be9064a61a38afd0dd30",
-          "sha256": "a66e48c18dda88d8d94f19b4250067f834d9db01ca8390c26e4530bfd2ad015e",
-          "sha1": "cc99180305811c77b3fe5e10bfd099e8637bec44",
-          "md5": "81c0906fb7e820a6ff164add91827fe4"
-        }
-      ]
-    }
-  ]
-}
-        """.trimIndent()
-
-        // Expect that elements in "dependencies" are sorted alphabetically.
-        val expected = """
-{
-  "formatVersion": "1.1",
-  "component": {
-    "group": "androidx.activity",
-    "module": "activity-ktx",
-    "version": "1.5.0-alpha03",
-    "attributes": {
-      "org.gradle.status": "release"
-    }
-  },
-  "createdBy": {
-    "gradle": {
-      "version": "7.4"
-    }
-  },
-  "variants": [
-    {
-      "name": "releaseVariantReleaseApiPublication",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.libraryelements": "aar",
-        "org.gradle.usage": "java-api"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.activity",
-          "module": "activity",
-          "version": {
-            "requires": "1.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.core",
-          "module": "core-ktx",
-          "version": {
-            "requires": "1.1.0"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-runtime-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-viewmodel-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.savedstate",
-          "module": "savedstate-ktx",
-          "version": {
-            "requires": "1.2.0-alpha01"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03.aar",
-          "url": "activity-ktx-1.5.0-alpha03.aar",
-          "size": 31645,
-          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
-          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
-          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
-          "md5": "186145646501129b4bdfd0f804ba96d9"
-        }
-      ]
-    },
-    {
-      "name": "releaseVariantReleaseRuntimePublication",
-      "attributes": {
-        "org.gradle.category": "library",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.libraryelements": "aar",
-        "org.gradle.usage": "java-runtime"
-      },
-      "dependencies": [
-        {
-          "group": "androidx.activity",
-          "module": "activity",
-          "version": {
-            "requires": "1.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.core",
-          "module": "core-ktx",
-          "version": {
-            "requires": "1.1.0"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-runtime-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "androidx.lifecycle",
-          "module": "lifecycle-viewmodel-ktx",
-          "version": {
-            "requires": "2.5.0-alpha03"
-          }
-        },
-        {
-          "group": "androidx.savedstate",
-          "module": "savedstate-ktx",
-          "version": {
-            "requires": "1.2.0-alpha01"
-          },
-          "reason": "Mirror activity dependency graph for -ktx artifacts"
-        },
-        {
-          "group": "org.jetbrains.kotlin",
-          "module": "kotlin-stdlib",
-          "version": {
-            "requires": "1.6.10"
-          }
-        }
-      ],
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03.aar",
-          "url": "activity-ktx-1.5.0-alpha03.aar",
-          "size": 31645,
-          "sha512": "d4b175f956cd329698705ab7ecdb080c6668d689bf9ae99e8d7c53baa4383848af73c65e280baabb4938121d5d06367a900b5fc9c072eb29aa86e89b6f0c4595",
-          "sha256": "e30b007d69f63a2a0c56b5275faea7badf0f80a06caa1c50b2eba7129581793e",
-          "sha1": "9818a50c9ed22d6c089026f4edd3106b06eb4a4e",
-          "md5": "186145646501129b4bdfd0f804ba96d9"
-        }
-      ]
-    },
-    {
-      "name": "sourcesElements",
-      "attributes": {
-        "org.gradle.category": "documentation",
-        "org.gradle.dependency.bundling": "external",
-        "org.gradle.docstype": "sources",
-        "org.gradle.usage": "java-runtime"
-      },
-      "files": [
-        {
-          "name": "activity-ktx-1.5.0-alpha03-sources.jar",
-          "url": "activity-ktx-1.5.0-alpha03-sources.jar",
-          "size": 7897,
-          "sha512": "c484c2a29fdd1896cbdc3613c660eb83acfd8371a800eb8950783a6011623011a336cf2c9c3258119c1f22cb5ea6d9a1513125284cc3be9064a61a38afd0dd30",
-          "sha256": "a66e48c18dda88d8d94f19b4250067f834d9db01ca8390c26e4530bfd2ad015e",
-          "sha1": "cc99180305811c77b3fe5e10bfd099e8637bec44",
-          "md5": "81c0906fb7e820a6ff164add91827fe4"
-        }
-      ]
-    }
-  ]
-}
-        """.trimIndent()
-        /* ktlint-enable max-line-length */
-
-        val actual = sortGradleMetadataDependencies(metadata)
-        assertEquals(expected, actual)
-    }
-}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index b23ef80..5defa2f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -107,10 +107,11 @@
             throw Exception("Root project should use AndroidXRootImplPlugin instead")
         val extension = project.extensions.create<AndroidXExtension>(EXTENSION_NAME, project)
 
-        project.extensions.create<AndroidXMultiplatformExtension>(
+        val kmpExtension = project.extensions.create<AndroidXMultiplatformExtension>(
             AndroidXMultiplatformExtension.EXTENSION_NAME,
             project
         )
+
         project.tasks.register(BUILD_ON_SERVER_TASK, DefaultTask::class.java)
         // Perform different actions based on which plugins have been applied to the project.
         // Many of the actions overlap, ex. API tracking.
@@ -140,7 +141,7 @@
         }
 
         project.configureTaskTimeouts()
-        project.configureMavenArtifactUpload(extension, componentFactory)
+        project.configureMavenArtifactUpload(extension, kmpExtension, componentFactory)
         project.configureExternalDependencyLicenseCheck()
         project.configureProjectStructureValidation(extension)
         project.configureProjectVersionValidation(extension)
@@ -160,6 +161,9 @@
             if (extension.shouldPublishSbom()) {
                 project.configureSbomPublishing()
             }
+            if (extension.shouldPublish()) {
+                project.validatePublishedMultiplatformHasDefault()
+            }
         }
     }
 
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
index 417e2d5..488a5a6 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
@@ -18,6 +18,7 @@
 
 import groovy.lang.Closure
 import org.gradle.api.Action
+import org.gradle.api.GradleException
 import org.gradle.api.NamedDomainObjectCollection
 import org.gradle.api.Project
 import org.gradle.api.provider.Provider
@@ -48,6 +49,65 @@
     }
     private val kotlinExtension: KotlinMultiplatformExtension by kotlinExtensionDelegate
 
+    /**
+     * The list of platforms that have been requested in the build configuration.
+     *
+     * The list of enabled platforms in [targetPlatforms] will vary based on the build environment.
+     * For example, a project's build configuration may have requested `mac()` but this is not
+     * available when building on Linux.
+     */
+    val requestedPlatforms: MutableSet<PlatformIdentifier> = mutableSetOf()
+
+    /**
+     * The list of platforms that are enabled.
+     *
+     * This will vary across build environments. For example, a project's build configuration may
+     * have requested `mac()` but this is not available when building on Linux.
+     */
+    val targetPlatforms: List<String>
+        get() = if (kotlinExtensionDelegate.isInitialized()) {
+            kotlinExtension.targets.mapNotNull {
+                if (it.targetName != "metadata") {
+                    it.targetName
+                } else {
+                    null
+                }
+            }
+        } else {
+            throw GradleException("Kotlin multi-platform extension has not been initialized")
+        }
+
+    /**
+     * Default platform identifier used for specifying POM dependencies.
+     *
+     * This platform will be added as a dependency to the multi-platform anchor artifact's POM
+     * publication. For example, if the anchor artifact is `collection` and the default platform
+     * is `jvm`, then the POM for `collection` will express a dependency on `collection-jvm`. This
+     * ensures that developers who are silently upgrade to KMP artifacts but are not using Gradle
+     * still see working artifacts.
+     *
+     * If no default was specified and a single platform is requested (ex. using [jvm]), returns
+     * the identifier for that platform.
+     */
+    var defaultPlatform: String? = null
+        get() = field ?: requestedPlatforms.singleOrNull()?.id
+
+        set(value) {
+            if (value != null) {
+                if (requestedPlatforms.none { it.id == value }) {
+                    throw GradleException("Platform $value has not been requested as a target. " +
+                        "Available platforms are: " +
+                        requestedPlatforms.joinToString(", ") { it.id })
+                }
+                if (targetPlatforms.none { it == value }) {
+                    throw GradleException("Platform $value is not available in this build " +
+                        "environment. Available platforms are: " +
+                        targetPlatforms.joinToString(", "))
+                }
+            }
+            field = value
+        }
+
     val presets: NamedDomainObjectCollection<KotlinTargetPreset<*>>
         get() = kotlinExtension.presets
     val targets: NamedDomainObjectCollection<KotlinTarget>
@@ -65,13 +125,33 @@
         }
     }
 
+    /**
+     * Sets the default target platform.
+     *
+     * The default target platform *must* be enabled in all build environments. For projects which
+     * request multiple target platforms, this method *must* be called to explicitly specify a
+     * default target platform.
+     *
+     * See [defaultPlatform] for details on how the value is used.
+     */
+    fun defaultPlatform(value: PlatformIdentifier) {
+        defaultPlatform = value.id
+    }
+
     @JvmOverloads
     fun jvm(
         block: Action<KotlinJvmTarget>? = null
     ): KotlinJvmTarget? {
+        requestedPlatforms.add(PlatformIdentifier.JVM)
         return if (project.enableJvm()) {
             kotlinExtension.jvm {
                 block?.execute(this)
+                // quick fix for b/286852059
+                // We need to have either Java plugin or Android plugin for the API
+                // files to be generated.
+                if (!project.plugins.hasPlugin("com.android.library")) {
+                    withJava()
+                }
             }
         } else { null }
     }
@@ -80,6 +160,7 @@
     fun android(
         block: Action<KotlinAndroidTarget>? = null
     ): KotlinAndroidTarget? {
+        requestedPlatforms.add(PlatformIdentifier.ANDROID)
         return if (project.enableJvm()) {
             kotlinExtension.android {
                 block?.execute(this)
@@ -91,6 +172,7 @@
     fun desktop(
         block: Action<KotlinJvmTarget>? = null
     ): KotlinJvmTarget? {
+        requestedPlatforms.add(PlatformIdentifier.DESKTOP)
         return if (project.enableDesktop()) {
             kotlinExtension.jvm("desktop") {
                 block?.execute(this)
@@ -115,6 +197,7 @@
     fun macosX64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTargetWithHostTests? {
+        requestedPlatforms.add(PlatformIdentifier.MAC_OSX_64)
         return if (project.enableMac()) {
             kotlinExtension.macosX64().also {
                 block?.execute(it)
@@ -126,6 +209,7 @@
     fun macosArm64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTargetWithHostTests? {
+        requestedPlatforms.add(PlatformIdentifier.MAC_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.macosArm64().also {
                 block?.execute(it)
@@ -137,6 +221,7 @@
     fun iosArm64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTarget? {
+        requestedPlatforms.add(PlatformIdentifier.IOS_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.iosArm64().also {
                 block?.execute(it)
@@ -161,6 +246,7 @@
     fun iosX64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTarget? {
+        requestedPlatforms.add(PlatformIdentifier.IOS_X_64)
         return if (project.enableMac()) {
             kotlinExtension.iosX64().also {
                 block?.execute(it)
@@ -172,6 +258,7 @@
     fun iosSimulatorArm64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTarget? {
+        requestedPlatforms.add(PlatformIdentifier.IOS_SIMULATOR_ARM_64)
         return if (project.enableMac()) {
             kotlinExtension.iosSimulatorArm64().also {
                 block?.execute(it)
@@ -192,6 +279,7 @@
     fun linuxX64(
         block: Action<KotlinNativeTarget>? = null
     ): KotlinNativeTargetWithHostTests? {
+        requestedPlatforms.add(PlatformIdentifier.LINUX_64)
         return if (project.enableLinux()) {
             kotlinExtension.linuxX64().also {
                 block?.execute(it)
@@ -203,6 +291,7 @@
     fun js(
         block: Action<KotlinJsTargetDsl>? = null
     ): KotlinJsTargetDsl? {
+        requestedPlatforms.add(PlatformIdentifier.JS)
         return if (project.enableJs()) {
             kotlinExtension.js().also {
                 block?.execute(it)
@@ -224,3 +313,14 @@
 internal fun Project.hasKotlinNativeTarget(): Provider<Boolean> = project.provider {
     project.extensions.getByType(AndroidXMultiplatformExtension::class.java).hasNativeTarget()
 }
+
+fun Project.validatePublishedMultiplatformHasDefault() {
+    val extension = project.extensions.getByType(AndroidXMultiplatformExtension::class.java)
+    if (extension.defaultPlatform == null && extension.requestedPlatforms.isNotEmpty()) {
+        throw GradleException("Project is published and multiple platforms are requested. You " +
+            "must explicitly specify androidXMultiplatform.defaultPlatform as one of: " +
+            extension.targetPlatforms.joinToString(", ") {
+                "PlatformIdentifier.${PlatformIdentifier.fromId(it)!!.name}"
+            })
+    }
+}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
index c010d99..19752f0 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
@@ -18,6 +18,7 @@
 
 import com.android.build.gradle.AppPlugin
 import com.android.build.gradle.LibraryPlugin
+import com.android.utils.childrenIterator
 import com.google.gson.GsonBuilder
 import com.google.gson.JsonObject
 import com.google.gson.stream.JsonWriter
@@ -52,13 +53,14 @@
 
 fun Project.configureMavenArtifactUpload(
     extension: AndroidXExtension,
+    kmpExtension: AndroidXMultiplatformExtension,
     componentFactory: SoftwareComponentFactory
 ) {
     apply(mapOf("plugin" to "maven-publish"))
     var registered = false
     fun registerOnFirstPublishableArtifact(component: SoftwareComponent) {
         if (!registered) {
-            configureComponentPublishing(extension, component, componentFactory)
+            configureComponentPublishing(extension, kmpExtension, component, componentFactory)
             Release.register(this, extension)
             registered = true
         }
@@ -95,6 +97,7 @@
  */
 private fun Project.configureComponentPublishing(
     extension: AndroidXExtension,
+    kmpExtension: AndroidXMultiplatformExtension,
     component: SoftwareComponent,
     componentFactory: SoftwareComponentFactory
 ) {
@@ -154,10 +157,11 @@
                 }
             }
         }
-        publications.withType(MavenPublication::class.java).all {
-            it.pom { pom ->
+        publications.withType(MavenPublication::class.java).all { publication ->
+            publication.pom { pom ->
                 addInformativeMetadata(extension, pom)
-                tweakDependenciesMetadata(androidxGroup, pom, androidLibrariesSetProvider)
+                tweakDependenciesMetadata(androidxGroup, pom, androidLibrariesSetProvider,
+                    publication.name == KMP_ANCHOR_PUBLICATION_NAME, kmpExtension.defaultPlatform)
             }
         }
     }
@@ -297,7 +301,7 @@
     ) { sourcesComponents ->
         configure<PublishingExtension> {
             publications { pubs ->
-                pubs.create<MavenPublication>("androidxKmp") {
+                pubs.create<MavenPublication>(KMP_ANCHOR_PUBLICATION_NAME) {
                     // Duplicate behavior from KMP plugin
                     // (https://cs.github.com/JetBrains/kotlin/blob/0c001cc9939a2ab11815263ed825c1096b3ce087/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/Publishing.kt#L42)
                     // Should be able to remove internal API usage once
@@ -306,7 +310,7 @@
 
                     from(object : ComponentWithVariants, SoftwareComponentInternal {
                         override fun getName(): String {
-                            return "androidxKmp"
+                            return KMP_ANCHOR_PUBLICATION_NAME
                         }
 
                         override fun getUsages(): MutableSet<out UsageContext> {
@@ -454,7 +458,9 @@
 private fun tweakDependenciesMetadata(
     mavenGroup: LibraryGroup,
     pom: MavenPom,
-    androidLibrariesSetProvider: Provider<Set<String>>
+    androidLibrariesSetProvider: Provider<Set<String>>,
+    kmpAnchor: Boolean,
+    pomPlatform: String?
 ) {
     pom.withXml { xml ->
         // The following code depends on getProjectsMap which is only available late in
@@ -465,6 +471,10 @@
         assignSingleVersionDependenciesInGroupForPom(xml, mavenGroup)
         assignAarTypes(xml, androidLibrariesSetProvider)
         ensureConsistentJvmSuffix(xml)
+
+        if (kmpAnchor && pomPlatform != null) {
+            insertDefaultMultiplatformDependencies(xml, pomPlatform)
+        }
     }
 }
 
@@ -497,6 +507,37 @@
     }
 }
 
+fun insertDefaultMultiplatformDependencies(
+    xml: XmlProvider,
+    platformId: String
+) {
+    val groupId = xml.asElement().find { it.nodeName == "groupId" }?.textContent ?: return
+    val artifactId = xml.asElement().find { it.nodeName == "artifactId" }?.textContent ?: return
+    val version = xml.asElement().find { it.nodeName == "version" }?.textContent ?: return
+
+    val dependencies = xml.asNode().children().find {
+        it is Node && it.name().toString().endsWith("dependencies")
+    } as Node? ?: return
+
+    dependencies.appendNode("dependency").apply {
+        appendNode("groupId", groupId)
+        appendNode("artifactId", "$artifactId-$platformId")
+        appendNode("version", version)
+        appendNode("scope", "compile")
+    }
+}
+
+private fun org.w3c.dom.Element.find(predicate: (org.w3c.dom.Node) -> Boolean): org.w3c.dom.Node? {
+    val iterator = childrenIterator()
+    while (iterator.hasNext()) {
+        val node = iterator.next()
+        if (predicate(node)) {
+            return node
+        }
+    }
+    return null
+}
+
 /**
  * Modifies the given .pom to specify that every dependency in <group> refers to a single version
  * and can't be automatically promoted to a new version.
@@ -581,3 +622,5 @@
 
 private const val ANDROID_GIT_URL =
     "scm:git:https://android.googlesource.com/platform/frameworks/support"
+
+internal const val KMP_ANCHOR_PUBLICATION_NAME = "androidxKmp"
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
index d49701d..efe1549 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
@@ -63,6 +63,7 @@
         task.from(layout.projectDirectory)
         task.include("**/OWNERS")
         task.exclude("buildSrc/.gradle/**")
+        task.exclude(".gradle/**")
         task.includeEmptyDirs = false
     }
 
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/KmpPlatforms.kt b/buildSrc/public/src/main/kotlin/androidx/build/KmpPlatforms.kt
index 7961e09..821b8f1 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/KmpPlatforms.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/KmpPlatforms.kt
@@ -52,6 +52,25 @@
     }
 }
 
+enum class PlatformIdentifier(val id: String) {
+    JVM("jvm"),
+    JS("js"),
+    ANDROID("android"),
+    MAC_ARM_64("macosarm64"),
+    MAC_OSX_64("macosx64"),
+    LINUX_64("linuxx64"),
+    IOS_SIMULATOR_ARM_64("iossimulatorarm64"),
+    IOS_X_64("iosx64"),
+    IOS_ARM_64("iosarm64"),
+    DESKTOP("desktop");
+
+    companion object {
+        private val byId = values().associateBy { it.id }
+
+        fun fromId(id: String): PlatformIdentifier? = byId[id]
+    }
+}
+
 object KmpFlagParser {
     fun parse(flag: String?): Set<KmpPlatform> {
         if (flag.isNullOrBlank()) {
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
index 48287fe..ac91da5 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
@@ -34,7 +34,7 @@
      * Either an integer value or a pre-release platform code, prefixed with "android-" (ex.
      * "android-28" or "android-Q") as you would see within the SDK's platforms directory.
      */
-    const val COMPILE_SDK_VERSION = "android-33-ext5"
+    const val COMPILE_SDK_VERSION = "android-34"
 
     /**
      * The Android SDK version to use for targetSdkVersion meta-data.
@@ -47,7 +47,7 @@
      * order for tests to run on devices running released versions of the Android OS. If this is
      * set to a pre-release version, tests will only be able to run on pre-release devices.
      */
-    const val TARGET_SDK_VERSION = 33
+    const val TARGET_SDK_VERSION = 34
 
     /**
      * Returns the build tools version that should be used for the project.
diff --git a/busytown/impl/check_translations.sh b/busytown/impl/check_translations.sh
index 35501ad..0f9e440 100755
--- a/busytown/impl/check_translations.sh
+++ b/busytown/impl/check_translations.sh
@@ -20,6 +20,7 @@
 find . \
     \( \
       -iname '*sample*' \
+      -o -iname '*demo*' \
       -o -iname '*donottranslate*' \
       -o -iname '*debug*' \
       -o -iname '*test*' \
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
index f88ee43..80eed7d 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
@@ -36,8 +36,10 @@
     private val waitingCount = atomic(capturesCount)
     private val failureException =
         TimeoutException("Test doesn't complete after waiting for $capturesCount frames.")
-    @Volatile private var startReceiving = false
-    @Volatile private var _verifyBlock: (
+    @Volatile
+    private var startReceiving = false
+    @Volatile
+    private var _verifyBlock: (
         captureRequest: RequestMetadata,
         captureResult: FrameInfo
     ) -> Boolean = { _, _ -> false }
@@ -77,6 +79,10 @@
         }
     }
 
+    @Deprecated(
+        message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+        level = DeprecationLevel.WARNING
+    )
     override fun onFailed(
         requestMetadata: RequestMetadata,
         frameNumber: FrameNumber,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CameraCallbackMap.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CameraCallbackMap.kt
index 6929c99..dfb4e41 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CameraCallbackMap.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CameraCallbackMap.kt
@@ -118,6 +118,10 @@
         }
     }
 
+    @Deprecated(
+        message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+        level = DeprecationLevel.WARNING
+    )
     override fun onFailed(
         requestMetadata: RequestMetadata,
         frameNumber: FrameNumber,
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
index 146f2b4..d696fb1 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
@@ -123,12 +123,14 @@
         requests: List<Request>,
         captureMode: Int,
         flashMode: Int,
-    ): List<Deferred<Void?>> =
-        if (hasFlashUnit && isFlashRequired(flashMode)) {
+    ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#torchAsFlashCapture" }
+        return if (hasFlashUnit && isFlashRequired(flashMode)) {
             torchApplyCapture(requests, captureMode, CHECK_3A_WITH_FLASH_TIMEOUT_IN_NS)
         } else {
             defaultNoFlashCapture(requests, captureMode)
         }
+    }
 
     private suspend fun defaultCapture(
         requests: List<Request>,
@@ -154,15 +156,24 @@
         requests: List<Request>,
         captureMode: Int
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#defaultNoFlashCapture" }
         val lock3ARequired = captureMode == CAPTURE_MODE_MAXIMIZE_QUALITY
         if (lock3ARequired) {
+            debug { "CapturePipeline#defaultNoFlashCapture: Locking 3A" }
             lock3A(CHECK_3A_TIMEOUT_IN_NS)
+            debug { "CapturePipeline#defaultNoFlashCapture: Locking 3A done" }
         }
         return submitRequestInternal(requests).also { captureSignal ->
             if (lock3ARequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#defaultNoFlashCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
-                    unlock3A()
+                    debug {
+                        "CapturePipeline#defaultNoFlashCapture: Waiting for capture signal done"
+                    }
+                    debug { "CapturePipeline#defaultNoFlashCapture: Unlocking 3A" }
+                    unlock3A(CHECK_3A_TIMEOUT_IN_NS)
+                    debug { "CapturePipeline#defaultNoFlashCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -173,28 +184,39 @@
         captureMode: Int,
         timeLimitNs: Long,
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#torchApplyCapture" }
         val torchOnRequired = torchControl.torchStateLiveData.value == TorchState.OFF
         if (torchOnRequired) {
+            debug { "CapturePipeline#torchApplyCapture: Setting torch" }
             torchControl.setTorchAsync(true).join()
+            debug { "CapturePipeline#torchApplyCapture: Setting torch done" }
         }
 
         val lock3ARequired = torchOnRequired || captureMode == CAPTURE_MODE_MAXIMIZE_QUALITY
         if (lock3ARequired) {
+            debug { "CapturePipeline#torchApplyCapture: Locking 3A" }
             lock3A(timeLimitNs)
+            debug { "CapturePipeline#torchApplyCapture: Locking 3A done" }
         }
 
         return submitRequestInternal(requests).also { captureSignal ->
             if (torchOnRequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#torchApplyCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
+                    debug { "CapturePipeline#torchApplyCapture: Unsetting torch" }
                     @Suppress("DeferredResultUnused")
                     torchControl.setTorchAsync(false)
+                    debug { "CapturePipeline#torchApplyCapture: Unsetting torch done" }
                 }
             }
             if (lock3ARequired) {
                 threads.sequentialScope.launch {
+                    debug { "CapturePipeline#torchApplyCapture: Waiting for capture signal" }
                     captureSignal.joinAll()
-                    unlock3A()
+                    debug { "CapturePipeline#torchApplyCapture: Unlocking 3A" }
+                    unlock3A(CHECK_3A_TIMEOUT_IN_NS)
+                    debug { "CapturePipeline#torchApplyCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -204,16 +226,29 @@
         requests: List<Request>,
         timeLimitNs: Long,
     ): List<Deferred<Void?>> {
+        debug { "CapturePipeline#aePreCaptureApplyCapture" }
+        debug { "CapturePipeline#aePreCaptureApplyCapture: Acquiring session for locking 3A" }
         graph.acquireSession().use {
+            debug { "CapturePipeline#aePreCaptureApplyCapture: Locking 3A for capture" }
             it.lock3AForCapture(timeLimitNs = timeLimitNs).join()
+            debug { "CapturePipeline#aePreCaptureApplyCapture: Locking 3A for capture done" }
         }
 
         return submitRequestInternal(requests).also { captureSignal ->
             threads.sequentialScope.launch {
+                debug { "CapturePipeline#aePreCaptureApplyCapture: Waiting for capture signal" }
                 captureSignal.joinAll()
+                debug {
+                    "CapturePipeline#aePreCaptureApplyCapture: Waiting for capture signal done"
+                }
+                debug {
+                    "CapturePipeline#aePreCaptureApplyCapture: Acquiring session for unlocking 3A"
+                }
                 graph.acquireSession().use {
+                    debug { "CapturePipeline#aePreCaptureApplyCapture: Unlocking 3A" }
                     @Suppress("DeferredResultUnused")
                     it.unlock3APostCapture()
+                    debug { "CapturePipeline#aePreCaptureApplyCapture: Unlocking 3A done" }
                 }
             }
         }
@@ -228,8 +263,13 @@
         )
     }.await()
 
-    private suspend fun unlock3A(): Result3A = graph.acquireSession().use {
-        it.unlock3A(ae = true, af = true, awb = true)
+    private suspend fun unlock3A(timeLimitNs: Long): Result3A = graph.acquireSession().use {
+        it.unlock3A(
+            ae = true,
+            af = true,
+            awb = true,
+            timeLimitNs = timeLimitNs,
+        )
     }.await()
 
     private fun submitRequestInternal(requests: List<Request>): List<Deferred<Void?>> {
@@ -256,6 +296,12 @@
                             completeSignal.complete(null)
                         }
 
+                        @Deprecated(
+                            message = "Migrating to using RequestFailureWrapper instead of " +
+                                "CaptureFailure",
+                            level = DeprecationLevel.WARNING,
+                            replaceWith = ReplaceWith("onFailed")
+                        )
                         @SuppressLint("ClassVerificationFailure")
                         override fun onFailed(
                             requestMetadata: RequestMetadata,
@@ -276,14 +322,17 @@
         }
 
         threads.sequentialScope.launch {
+            debug {
+                "CapturePipeline#submitRequestInternal: Acquiring session for submitting requests"
+            }
             // graph.acquireSession may fail if camera has entered closing stage
             var cameraGraphSession: CameraGraph.Session? = null
             try {
                 cameraGraphSession = graph.acquireSession()
             } catch (_: CancellationException) {
                 info {
-                    "CapturePipeline#submitRequestInternal:" +
-                    " CameraGraph.Session could not be acquired, requests may need re-submission"
+                    "CapturePipeline#submitRequestInternal: " +
+                        "CameraGraph.Session could not be acquired, requests may need re-submission"
                 }
 
                 // completing the requests exceptionally so that they are retried with next camera
@@ -304,6 +353,7 @@
                     it.stopRepeating()
                 }
 
+                debug { "CapturePipeline#submitRequestInternal: Submitting $requestsToSubmit" }
                 it.submit(requestsToSubmit)
 
                 if (requiresStopRepeating) {
@@ -324,6 +374,7 @@
                     CaptureResult.CONTROL_AE_STATE
                 ) == CONTROL_AE_STATE_FLASH_REQUIRED
             }
+
             FLASH_MODE_OFF -> false
             else -> throw AssertionError(flashMode)
         }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ComboRequestListener.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ComboRequestListener.kt
index 4f1c06d..6f98ef1 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ComboRequestListener.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/ComboRequestListener.kt
@@ -84,11 +84,16 @@
         }
     }
 
+    @Deprecated(
+        message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+        level = DeprecationLevel.WARNING
+    )
     override fun onFailed(
         requestMetadata: RequestMetadata,
         frameNumber: FrameNumber,
         captureFailure: CaptureFailure
     ) {
+        @Suppress("DEPRECATION")
         listeners.forEach { (listener, executor) ->
             executor.execute { listener.onFailed(requestMetadata, frameNumber, captureFailure) }
         }
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
index 47a80ac..e4dec65 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestControl.kt
@@ -19,6 +19,7 @@
 import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.core.Log.debug
+import androidx.camera.camera2.pipe.core.Log.warn
 import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
 import androidx.camera.camera2.pipe.integration.adapter.propagateOnceTo
 import androidx.camera.camera2.pipe.integration.config.CameraScope
@@ -39,6 +40,7 @@
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
+import kotlinx.coroutines.withTimeoutOrNull
 
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 @CameraScope
@@ -141,7 +143,14 @@
         // Prior to submitStillCaptures, wait until the pending flash mode session change is
         // completed. On some devices, AE preCapture triggered in submitStillCaptures may not
         // work properly if the repeating request to change the flash mode is not completed.
-        flashControl.updateSignal.join()
+        debug { "StillCaptureRequestControl: Waiting for flash control" }
+        withTimeoutOrNull(1_000L) {
+            flashControl.updateSignal.join()
+        } ?: {
+            warn { "StillCaptureRequestControl: Waiting for flash control timed out" }
+        }
+        debug { "StillCaptureRequestControl: Waiting for flash control done" }
+        debug { "StillCaptureRequestControl: Issuing single capture" }
         val deferredList = camera.requestControl.issueSingleCaptureAsync(
             request.captureConfigs,
             request.captureMode,
@@ -152,7 +161,10 @@
         return threads.sequentialScope.async {
             // requestControl.issueSingleCaptureAsync shouldn't be invoked from here directly,
             // because sequentialScope.async is may not be executed immediately
-            deferredList.awaitAll()
+            debug { "StillCaptureRequestControl: Waiting for deferred list from $request" }
+            deferredList.awaitAll().also {
+                debug { "StillCaptureRequestControl: Waiting for deferred list from $request done" }
+            }
         }
     }
 
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
index fda33c0..6ce070e 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControl.kt
@@ -281,6 +281,7 @@
         return synchronized(lock) {
             infoBundleMap.merge()
         }.let { infoBundle ->
+            debug { "UseCaseCameraRequestControl: Submitting still captures to capture pipeline" }
             capturePipeline.submitStillCaptures(
                 requests = captureSequence.map {
                     configAdapter.mapToRequest(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
index dadbc05..75a210e 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraState.kt
@@ -308,7 +308,7 @@
         key: CaptureRequest.Key<*>
     ): Int? = this?.get(key) as? Int
 
-    inner class RequestListener() : Request.Listener {
+    inner class RequestListener : Request.Listener {
         override fun onTotalCaptureResult(
             requestMetadata: RequestMetadata,
             frameNumber: FrameNumber,
@@ -324,11 +324,16 @@
             }
         }
 
+        @Deprecated(
+            message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+            level = DeprecationLevel.WARNING
+        )
         override fun onFailed(
             requestMetadata: RequestMetadata,
             frameNumber: FrameNumber,
             captureFailure: CaptureFailure,
         ) {
+            @Suppress("DEPRECATION")
             super.onFailed(requestMetadata, frameNumber, captureFailure)
             completeExceptionally(requestMetadata, captureFailure)
         }
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CaptureConfigAdapterTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CaptureConfigAdapterTest.kt
index 34c2fa3..b6ff946 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CaptureConfigAdapterTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/CaptureConfigAdapterTest.kt
@@ -96,8 +96,9 @@
     @Test
     fun shouldFail_whenCaptureConfigSurfaceNotRecognized() {
         // Arrange
+        val fakeSurface = FakeSurface()
         val captureConfig = CaptureConfig.Builder()
-            .apply { addSurface(FakeSurface()) }
+            .apply { addSurface(fakeSurface) }
             .build()
         val sessionConfigOptions = Camera2ImplConfig.Builder().build()
 
@@ -109,6 +110,9 @@
                 sessionConfigOptions
             )
         }
+
+        // Clean up
+        fakeSurface.close()
     }
 
     @Test
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
index d4c2e51..8896087 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/FocusMeteringControlTest.kt
@@ -178,6 +178,10 @@
     fun tearDown() {
         // CoroutineScope#cancel can throw exception if the scope has no job left
         try {
+            fakeUseCaseCamera.runningUseCases.forEach {
+                it.onStateDetached()
+                it.onUnbind()
+            }
             // fakeUseCaseThreads may still be using Main dispatcher which sometimes
             // causes Dispatchers.resetMain() to throw an exception:
             // "IllegalStateException: Dispatchers.Main is used concurrently with setting it"
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/workaround/PreviewPixelHDRnetQuirkTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/workaround/PreviewPixelHDRnetQuirkTest.kt
index 08f756f..5542e0b 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/workaround/PreviewPixelHDRnetQuirkTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/compat/workaround/PreviewPixelHDRnetQuirkTest.kt
@@ -103,7 +103,7 @@
     @Test
     fun previewShouldApplyToneModeForHDRNet() {
         // Arrange
-        val cameraUseCaseAdapter = configureCameraUseCaseAdapter(
+        cameraUseCaseAdapter = configureCameraUseCaseAdapter(
             resolutionVGA,
             configType = PreviewConfig::class.java
         )
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
index ae0292a..a98c7d5 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
@@ -612,6 +612,7 @@
         fakeCameraGraphSession.requestHandler = { requests ->
             requests.forEach { request ->
                 // Callback capture fail immediately.
+                @Suppress("DEPRECATION")
                 request.listeners.forEach {
                     it.onFailed(
                         requestMetadata = FakeRequestMetadata(),
@@ -687,11 +688,13 @@
 
         // Act.
         capturePipeline.submitStillCaptures(
-            requests = listOf(Request(
-                streams = emptyList(),
-                parameters = mapOf(CONTROL_AE_MODE to CONTROL_AE_MODE_ON_ALWAYS_FLASH),
-                template = RequestTemplate(CameraDevice.TEMPLATE_STILL_CAPTURE)
-            )),
+            requests = listOf(
+                Request(
+                    streams = emptyList(),
+                    parameters = mapOf(CONTROL_AE_MODE to CONTROL_AE_MODE_ON_ALWAYS_FLASH),
+                    template = RequestTemplate(CameraDevice.TEMPLATE_STILL_CAPTURE)
+                )
+            ),
             captureMode = ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY,
             flashMode = ImageCapture.FLASH_MODE_ON,
             flashType = ImageCapture.FLASH_TYPE_ONE_SHOT_FLASH,
@@ -725,11 +728,13 @@
 
         // Act.
         capturePipeline.submitStillCaptures(
-            requests = listOf(Request(
-                streams = emptyList(),
-                parameters = mapOf(CONTROL_AE_MODE to CONTROL_AE_MODE_ON_ALWAYS_FLASH),
-                template = RequestTemplate(CameraDevice.TEMPLATE_STILL_CAPTURE)
-            )),
+            requests = listOf(
+                Request(
+                    streams = emptyList(),
+                    parameters = mapOf(CONTROL_AE_MODE to CONTROL_AE_MODE_ON_ALWAYS_FLASH),
+                    template = RequestTemplate(CameraDevice.TEMPLATE_STILL_CAPTURE)
+                )
+            ),
             captureMode = ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY,
             flashMode = ImageCapture.FLASH_MODE_ON,
             flashType = ImageCapture.FLASH_TYPE_ONE_SHOT_FLASH,
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestTest.kt
index 63e023a..945507d 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/StillCaptureRequestTest.kt
@@ -49,6 +49,7 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
+import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Assume.assumeTrue
 import org.junit.Before
@@ -109,6 +110,11 @@
         stillCaptureRequestControl.setNewUseCaseCamera()
     }
 
+    @After
+    fun tearDown() {
+        fakeSurface.close()
+    }
+
     @Test
     fun captureRequestsSubmitted_whenCameraIsSet() = runTest(testDispatcher) {
         stillCaptureRequestControl.issueCaptureRequests()
@@ -201,6 +207,7 @@
 
         fakeCameraGraphSession.submittedRequests.first().let { request ->
             request.listeners.forEach { listener ->
+                @Suppress("DEPRECATION")
                 listener.onFailed(
                     FakeRequestMetadata(),
                     FrameNumber(0),
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControlTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControlTest.kt
index c129403..00f0f4c 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControlTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraRequestControlTest.kt
@@ -49,6 +49,7 @@
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.asExecutor
 import kotlinx.coroutines.runBlocking
+import org.junit.After
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.robolectric.annotation.Config
@@ -93,6 +94,11 @@
         useCaseGraphConfig = fakeUseCaseGraphConfig,
     )
 
+    @After
+    fun tearDown() {
+        surface.close()
+    }
+
     @Test
     fun testMergeRequestOptions(): Unit = runBlocking {
         // Arrange
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraStateTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraStateTest.kt
index a724e46..abd71a4 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraStateTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraStateTest.kt
@@ -42,6 +42,7 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
+import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Rule
@@ -89,6 +90,11 @@
         fakeCameraGraphSession.startRepeatingSignal = CompletableDeferred() // not complete yet
     }
 
+    @After
+    fun tearDown() {
+        surface.close()
+    }
+
     @Test
     fun updateAsyncCompletes_whenStopRepeating(): Unit = runBlocking {
         // stopRepeating is called when there is no stream after updateAsync call
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraTest.kt
index 20d762e..c1d3ac6 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseCameraTest.kt
@@ -41,6 +41,7 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.asExecutor
+import org.junit.After
 import org.junit.Assume.assumeTrue
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -89,6 +90,11 @@
         useCaseGraphConfig = fakeUseCaseGraphConfig,
     )
 
+    @After
+    fun tearDown() {
+        surface.close()
+    }
+
     @Test
     fun setInvalidSessionConfig_repeatingShouldStop() {
         // Arrange
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraGraphSession.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraGraphSession.kt
index 806a400..c3d481e 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraGraphSession.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/testing/FakeCameraGraphSession.kt
@@ -51,6 +51,7 @@
         FAILED,
         ABORTED
     }
+
     var startRepeatingSignal = CompletableDeferred(TOTAL_CAPTURE_DONE) // already completed
 
     val submittedRequests = mutableListOf<Request>()
@@ -173,9 +174,11 @@
                 TOTAL_CAPTURE_DONE -> listener.onTotalCaptureResult(
                     FakeRequestMetadata(request = request), FrameNumber(0), FakeFrameInfo()
                 )
-                FAILED -> listener.onFailed(
+
+                FAILED -> @Suppress("DEPRECATION") listener.onFailed(
                     FakeRequestMetadata(request = request), FrameNumber(0), getFakeCaptureFailure()
                 )
+
                 ABORTED -> listener.onRequestSequenceAborted(
                     FakeRequestMetadata(request = request)
                 )
diff --git a/camera/camera-camera2-pipe-integration/src/test/resources/robolectric.properties b/camera/camera-camera2-pipe-integration/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulator.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulator.kt
index a301e01..bf2264c 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulator.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/CameraGraphSimulator.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.graphics.SurfaceTexture
-import android.hardware.camera2.CaptureFailure
 import android.hardware.camera2.CaptureResult
 import android.view.Surface
 import androidx.annotation.RequiresApi
@@ -34,6 +33,7 @@
 import androidx.camera.camera2.pipe.GraphState.GraphStateError
 import androidx.camera.camera2.pipe.Metadata
 import androidx.camera.camera2.pipe.Request
+import androidx.camera.camera2.pipe.RequestFailureWrapper
 import androidx.camera.camera2.pipe.StreamId
 import kotlinx.atomicfu.atomic
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -283,9 +283,9 @@
             }
         }
 
-        fun simulateFailure(captureFailure: CaptureFailure) {
+        fun simulateFailure(requestFailureWrapper: RequestFailureWrapper) {
             requestSequence.invokeOnRequest(requestMetadata) {
-                it.onFailed(requestMetadata, frameNumber, captureFailure)
+                it.onFailed(requestMetadata, frameNumber, requestFailureWrapper)
             }
         }
 
diff --git a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeRequestListener.kt b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeRequestListener.kt
index a3ca0db..e097dc3 100644
--- a/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeRequestListener.kt
+++ b/camera/camera-camera2-pipe-testing/src/main/java/androidx/camera/camera2/pipe/testing/FakeRequestListener.kt
@@ -37,7 +37,7 @@
  * to be sent.
  */
 @Suppress("ListenerInterface")
-public class FakeRequestListener(private val replayBuffer: Int = 10) : Request.Listener {
+class FakeRequestListener(private val replayBuffer: Int = 10) : Request.Listener {
 
     private val _onStartedFlow = MutableSharedFlow<OnStarted>(replay = replayBuffer)
     val onStartedFlow = _onStartedFlow.asSharedFlow()
@@ -148,6 +148,10 @@
             "($replayBuffer) may need to be increased."
     }
 
+    @Deprecated(
+        message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+        level = DeprecationLevel.WARNING
+    )
     override fun onFailed(
         requestMetadata: RequestMetadata,
         frameNumber: FrameNumber,
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/Requests.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/Requests.kt
index 359e98d..1c98dad 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/Requests.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/Requests.kt
@@ -141,6 +141,17 @@
         ) {
         }
 
+        @Deprecated(
+            message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+            level = DeprecationLevel.WARNING
+        )
+        fun onFailed(
+            requestMetadata: RequestMetadata,
+            frameNumber: FrameNumber,
+            captureFailure: CaptureFailure
+        ) {
+        }
+
         /**
          * onFailed occurs when a CaptureRequest failed in some way and the frame will not receive
          * the [onTotalCaptureResult] callback.
@@ -149,13 +160,13 @@
          *
          * @param requestMetadata the data about the camera2 request that was sent to the camera.
          * @param frameNumber the android frame number for this exposure
-         * @param captureFailure the android [CaptureFailure] data
+         * @param requestFailureWrapper the android [RequestFailureWrapper] data wrapper
          * @see android.hardware.camera2.CameraCaptureSession.CaptureCallback.onCaptureFailed
          */
         fun onFailed(
             requestMetadata: RequestMetadata,
             frameNumber: FrameNumber,
-            captureFailure: CaptureFailure
+            requestFailureWrapper: RequestFailureWrapper
         ) {
         }
 
@@ -239,6 +250,23 @@
 }
 
 /**
+ * Interface wrapper for [CaptureFailure].
+ *
+ * This interface should be used instead of [CaptureFailure] because its package-private
+ * constructor prevents directly creating an instance of it.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface RequestFailureWrapper {
+    val requestMetadata: RequestMetadata
+
+    val frameNumber: FrameNumber
+
+    val reason: Int
+
+    val wasImageCaptured: Boolean
+}
+
+/**
  * A [RequestTemplate] indicates which preset set list of parameters will be applied to a request by
  * default. These values are defined by camera2.
  */
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/AndroidCaptureFailure.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/AndroidCaptureFailure.kt
new file mode 100644
index 0000000..7b22375
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/AndroidCaptureFailure.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+@file:RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+
+package androidx.camera.camera2.pipe.compat
+
+import android.hardware.camera2.CaptureFailure
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.FrameNumber
+import androidx.camera.camera2.pipe.RequestFailureWrapper
+import androidx.camera.camera2.pipe.RequestMetadata
+
+/**
+ * This class implements the [RequestFailureWrapper] interface to create a
+ * CaptureFailure object that can be used instead of the package-private [CaptureFailure]
+ */
+@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+internal class AndroidCaptureFailure(
+    override val requestMetadata: RequestMetadata,
+    override val wasImageCaptured: Boolean,
+    override val frameNumber: FrameNumber,
+    override val reason: Int
+) : RequestFailureWrapper
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureCallback.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureCallback.kt
new file mode 100644
index 0000000..4fbaac1
--- /dev/null
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureCallback.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.camera.camera2.pipe.compat
+
+import android.hardware.camera2.CameraCaptureSession
+import android.hardware.camera2.CameraExtensionSession
+import android.hardware.camera2.CaptureRequest
+import android.hardware.camera2.CaptureResult
+import android.hardware.camera2.TotalCaptureResult
+import androidx.camera.camera2.pipe.FrameNumber
+
+/**
+ * Interface for merging functionality of [CameraCaptureSession.CaptureCallback] and
+ * [CameraExtensionSession.ExtensionCaptureCallback].
+ *
+ * [CameraCaptureSession.CaptureCallback] and [CameraExtensionSession.ExtensionCaptureCallback]
+ * are abstract classes, so a class cannot extend both of them. This interface prevents duplication
+ * of code and developer facing endpoints because it is agnostic of which session type it is
+ * used for.
+ */
+internal interface Camera2CaptureCallback {
+    fun onCaptureStarted(
+        captureRequest: CaptureRequest,
+        captureFrameNumber: Long,
+        captureTimestamp: Long
+    )
+
+    fun onCaptureProgressed(captureRequest: CaptureRequest, partialCaptureResult: CaptureResult)
+
+    fun onCaptureCompleted(
+        captureRequest: CaptureRequest,
+        captureResult: TotalCaptureResult,
+        frameNumber: FrameNumber
+    )
+
+    fun onCaptureFailed(
+        captureRequest: CaptureRequest,
+        frameNumber: FrameNumber
+    )
+
+    fun onCaptureSequenceCompleted(captureSequenceId: Int, captureFrameNumber: Long)
+
+    fun onCaptureSequenceAborted(captureSequenceId: Int)
+}
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequence.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequence.kt
index c58f0f6..f0ad932a 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequence.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequence.kt
@@ -50,7 +50,8 @@
     override val sequenceListener: CaptureSequence.CaptureSequenceListener,
     private val requestNumberMap: Map<RequestNumber, RequestMetadata>,
     private val surfaceMap: Map<Surface, StreamId>,
-) : CameraCaptureSession.CaptureCallback(), CaptureSequence<CaptureRequest> {
+) : Camera2CaptureCallback, CameraCaptureSession.CaptureCallback(),
+    CaptureSequence<CaptureRequest> {
     private val debugId = captureSequenceDebugIds.incrementAndGet()
     private val hasStarted = CompletableDeferred<Unit>()
 
@@ -85,6 +86,12 @@
         captureRequest: CaptureRequest,
         captureTimestamp: Long,
         captureFrameNumber: Long
+    ) = onCaptureStarted(captureRequest, captureTimestamp, captureFrameNumber)
+
+    override fun onCaptureStarted(
+        captureRequest: CaptureRequest,
+        captureFrameNumber: Long,
+        captureTimestamp: Long
     ) {
         val requestNumber = readRequestNumber(captureRequest)
         val timestamp = CameraTimestamp(captureTimestamp)
@@ -102,6 +109,11 @@
         captureSession: CameraCaptureSession,
         captureRequest: CaptureRequest,
         partialCaptureResult: CaptureResult
+    ) = onCaptureProgressed(captureRequest, partialCaptureResult)
+
+    override fun onCaptureProgressed(
+        captureRequest: CaptureRequest,
+        partialCaptureResult: CaptureResult
     ) {
         val requestNumber = readRequestNumber(captureRequest)
         val frameNumber = FrameNumber(partialCaptureResult.frameNumber)
@@ -118,11 +130,16 @@
         captureSession: CameraCaptureSession,
         captureRequest: CaptureRequest,
         captureResult: TotalCaptureResult
+    ) = onCaptureCompleted(captureRequest, captureResult, FrameNumber(captureResult.frameNumber))
+
+    override fun onCaptureCompleted(
+        captureRequest: CaptureRequest,
+        captureResult: TotalCaptureResult,
+        frameNumber: FrameNumber
     ) {
         sequenceListener.onCaptureSequenceComplete(this)
 
         val requestNumber = readRequestNumber(captureRequest)
-        val frameNumber = FrameNumber(captureResult.frameNumber)
 
         // Load the request and throw if we are not able to find an associated request. Under
         // normal circumstances this should never happen.
@@ -137,21 +154,42 @@
         invokeOnRequest(request) { it.onComplete(request, frameNumber, frameInfo) }
     }
 
+    @Deprecated(
+        message = "Migrating to using RequestFailureWrapper instead of CaptureFailure",
+        level = DeprecationLevel.WARNING,
+        replaceWith = ReplaceWith("onFailed")
+    )
     override fun onCaptureFailed(
         captureSession: CameraCaptureSession,
         captureRequest: CaptureRequest,
         captureFailure: CaptureFailure
+    ) = onCaptureFailed(
+        captureRequest,
+        FrameNumber(captureFailure.frameNumber)
+    )
+
+    override fun onCaptureFailed(
+        captureRequest: CaptureRequest,
+        frameNumber: FrameNumber
     ) {
         sequenceListener.onCaptureSequenceComplete(this)
 
         val requestNumber = readRequestNumber(captureRequest)
-        val frameNumber = FrameNumber(captureFailure.frameNumber)
 
         // Load the request and throw if we are not able to find an associated request. Under
         // normal circumstances this should never happen.
         val request = readRequestMetadata(requestNumber)
 
-        invokeOnRequest(request) { it.onFailed(request, frameNumber, captureFailure) }
+        val androidCaptureFailure = AndroidCaptureFailure(
+            request,
+            false,
+            frameNumber,
+            CaptureFailure.REASON_ERROR
+        )
+
+        invokeOnRequest(request) {
+            it.onFailed(request, frameNumber, androidCaptureFailure)
+        }
     }
 
     override fun onCaptureBufferLost(
@@ -178,6 +216,11 @@
         captureSession: CameraCaptureSession,
         captureSequenceId: Int,
         captureFrameNumber: Long
+    ) = onCaptureSequenceCompleted(captureSequenceId, captureFrameNumber)
+
+    override fun onCaptureSequenceCompleted(
+        captureSequenceId: Int,
+        captureFrameNumber: Long
     ) {
         sequenceListener.onCaptureSequenceComplete(this)
 
@@ -195,7 +238,9 @@
     override fun onCaptureSequenceAborted(
         captureSession: CameraCaptureSession,
         captureSequenceId: Int
-    ) {
+    ) = onCaptureSequenceAborted(captureSequenceId)
+
+    override fun onCaptureSequenceAborted(captureSequenceId: Int) {
         sequenceListener.onCaptureSequenceComplete(this)
 
         check(sequenceNumber == captureSequenceId) {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
index 9a9bd8ac..212b808 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/Camera2CaptureSequenceProcessor.kt
@@ -277,23 +277,15 @@
                 if (shouldWaitForRepeatingRequest) {
                     lastSingleRepeatingRequestSequence = captureSequence
                 }
-                session.setRepeatingRequest(
-                    captureSequence.captureRequestList[0], captureCallback, threads.camera2Handler
-                )
+                session.setRepeatingRequest(captureSequence.captureRequestList[0], captureCallback)
             } else {
-                session.capture(
-                    captureSequence.captureRequestList[0], captureSequence, threads.camera2Handler
-                )
+                session.capture(captureSequence.captureRequestList[0], captureSequence)
             }
         } else {
             if (captureSequence.repeating) {
-                session.setRepeatingBurst(
-                    captureSequence.captureRequestList, captureSequence, threads.camera2Handler
-                )
+                session.setRepeatingBurst(captureSequence.captureRequestList, captureSequence)
             } else {
-                session.captureBurst(
-                    captureSequence.captureRequestList, captureSequence, threads.camera2Handler
-                )
+                session.captureBurst(captureSequence.captureRequestList, captureSequence)
             }
         }
     }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
index 8981549..6a4b1eb 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CameraDeviceWrapper.kt
@@ -26,7 +26,6 @@
 import android.hardware.camera2.params.InputConfiguration
 import android.hardware.camera2.params.OutputConfiguration
 import android.os.Build
-import android.os.Handler
 import android.view.Surface
 import androidx.annotation.GuardedBy
 import androidx.annotation.RequiresApi
@@ -37,6 +36,7 @@
 import androidx.camera.camera2.pipe.core.Debug
 import androidx.camera.camera2.pipe.core.Log
 import androidx.camera.camera2.pipe.core.SystemTimeSource
+import androidx.camera.camera2.pipe.core.Threads
 import androidx.camera.camera2.pipe.core.Timestamps
 import androidx.camera.camera2.pipe.core.Timestamps.formatMs
 import androidx.camera.camera2.pipe.internal.CameraErrorListener
@@ -64,8 +64,7 @@
     /** @see CameraDevice.createCaptureSession */
     fun createCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean
 
     /** @see CameraDevice.createReprocessableCaptureSession */
@@ -73,24 +72,21 @@
     fun createReprocessableCaptureSession(
         input: InputConfiguration,
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean
 
     /** @see CameraDevice.createConstrainedHighSpeedCaptureSession */
     @RequiresApi(Build.VERSION_CODES.M)
     fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean
 
     /** @see CameraDevice.createCaptureSessionByOutputConfigurations */
     @RequiresApi(Build.VERSION_CODES.N)
     fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean
 
     /** @see CameraDevice.createReprocessableCaptureSessionByConfigurations */
@@ -98,8 +94,7 @@
     fun createReprocessableCaptureSessionByConfigurations(
         inputConfig: InputConfigData,
         outputs: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean
 
     /** @see CameraDevice.createCaptureSession */
@@ -133,13 +128,13 @@
     private val cameraErrorListener: CameraErrorListener,
     private val interopSessionStateCallback: StateCallback? = null,
     private val interopExtensionSessionStateCallback: CameraExtensionSession.StateCallback? = null,
+    private val threads: Threads
 ) : CameraDeviceWrapper {
     private val _lastStateCallback = atomic<OnSessionFinalized?>(null)
 
     override fun createCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
@@ -154,9 +149,10 @@
                 stateCallback,
                 previousStateCallback,
                 cameraErrorListener,
-                interopSessionStateCallback
+                interopSessionStateCallback,
+                threads.camera2Handler
             ),
-            handler
+            threads.camera2Handler
         )
     } != null
 
@@ -183,7 +179,8 @@
                         stateCallback,
                         previousStateCallback,
                         cameraErrorListener,
-                        interopExtensionSessionStateCallback
+                        interopExtensionSessionStateCallback,
+                        config.executor
                     ),
                 )
             Api31Compat.createExtensionCaptureSession(cameraDevice, sessionConfig)
@@ -193,8 +190,7 @@
     override fun createReprocessableCaptureSession(
         input: InputConfiguration,
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
@@ -210,17 +206,17 @@
                 stateCallback,
                 previousStateCallback,
                 cameraErrorListener,
-                interopSessionStateCallback
+                interopSessionStateCallback,
+                threads.camera2Handler
             ),
-            handler
+            threads.camera2Handler
         )
     } != null
 
     @RequiresApi(23)
     override fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
@@ -235,17 +231,17 @@
                 stateCallback,
                 previousStateCallback,
                 cameraErrorListener,
-                interopSessionStateCallback
+                interopSessionStateCallback,
+                threads.camera2Handler
             ),
-            handler
+            threads.camera2Handler
         )
     } != null
 
     @RequiresApi(24)
     override fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
@@ -260,9 +256,10 @@
                 stateCallback,
                 previousStateCallback,
                 cameraErrorListener,
-                interopSessionStateCallback
+                interopSessionStateCallback,
+                threads.camera2Handler
             ),
-            handler
+            threads.camera2Handler
         )
     } != null
 
@@ -270,8 +267,7 @@
     override fun createReprocessableCaptureSessionByConfigurations(
         inputConfig: InputConfigData,
         outputs: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean = catchAndReportCameraExceptions(cameraId, cameraErrorListener) {
         val previousStateCallback = _lastStateCallback.value
         check(_lastStateCallback.compareAndSet(previousStateCallback, stateCallback))
@@ -289,9 +285,10 @@
                 stateCallback,
                 previousStateCallback,
                 cameraErrorListener,
-                interopSessionStateCallback
+                interopSessionStateCallback,
+                threads.camera2Handler
             ),
-            handler
+            threads.camera2Handler
         )
     } != null
 
@@ -312,7 +309,8 @@
                         stateCallback,
                         previousStateCallback,
                         cameraErrorListener,
-                        interopSessionStateCallback
+                        interopSessionStateCallback,
+                        threads.camera2Handler
                     )
                 )
 
@@ -387,15 +385,14 @@
 
     override fun createCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ) = synchronized(lock) {
         if (disconnected) {
             Log.warn { "createCaptureSession failed: Virtual device disconnected" }
             stateCallback.onSessionFinalized()
             false
         } else {
-            androidCameraDevice.createCaptureSession(outputs, stateCallback, handler)
+            androidCameraDevice.createCaptureSession(outputs, stateCallback)
         }
     }
 
@@ -403,8 +400,7 @@
     override fun createReprocessableCaptureSession(
         input: InputConfiguration,
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ) = synchronized(lock) {
         if (disconnected) {
             Log.warn { "createReprocessableCaptureSession failed: Virtual device disconnected" }
@@ -414,8 +410,7 @@
             androidCameraDevice.createReprocessableCaptureSession(
                 input,
                 outputs,
-                stateCallback,
-                handler
+                stateCallback
             )
         }
     }
@@ -423,8 +418,7 @@
     @RequiresApi(23)
     override fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ) = synchronized(lock) {
         if (disconnected) {
             Log.warn {
@@ -435,8 +429,7 @@
         } else {
             androidCameraDevice.createConstrainedHighSpeedCaptureSession(
                 outputs,
-                stateCallback,
-                handler
+                stateCallback
             )
         }
     }
@@ -444,8 +437,7 @@
     @RequiresApi(24)
     override fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ) = synchronized(lock) {
         if (disconnected) {
             Log.warn {
@@ -456,8 +448,7 @@
         } else {
             androidCameraDevice.createCaptureSessionByOutputConfigurations(
                 outputConfigurations,
-                stateCallback,
-                handler
+                stateCallback
             )
         }
     }
@@ -466,8 +457,7 @@
     override fun createReprocessableCaptureSessionByConfigurations(
         inputConfig: InputConfigData,
         outputs: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ) = synchronized(lock) {
         if (disconnected) {
             Log.warn {
@@ -480,8 +470,7 @@
             androidCameraDevice.createReprocessableCaptureSessionByConfigurations(
                 inputConfig,
                 outputs,
-                stateCallback,
-                handler
+                stateCallback
             )
         }
     }
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 c13f8c6..694c257 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
@@ -106,7 +106,7 @@
         captureSessionState: CaptureSessionState
     ): Map<StreamId, OutputConfigurationWrapper> {
         if (!cameraDevice.createCaptureSession(
-                surfaces.map { it.value }, captureSessionState, threads.camera2Handler
+                surfaces.map { it.value }, captureSessionState
             )
         ) {
             Log.warn {
@@ -137,8 +137,7 @@
                         outputConfig.format.value
                     ),
                     surfaces.map { it.value },
-                    captureSessionState,
-                    threads.camera2Handler
+                    captureSessionState
                 )
             ) {
                 Log.warn {
@@ -149,7 +148,7 @@
             }
         } else {
             if (!cameraDevice.createCaptureSession(
-                    surfaces.map { it.value }, captureSessionState, threads.camera2Handler
+                    surfaces.map { it.value }, captureSessionState
                 )
             ) {
                 Log.warn {
@@ -171,7 +170,7 @@
         captureSessionState: CaptureSessionState
     ): Map<StreamId, OutputConfigurationWrapper> {
         if (!cameraDevice.createConstrainedHighSpeedCaptureSession(
-                surfaces.map { it.value }, captureSessionState, threads.camera2Handler
+                surfaces.map { it.value }, captureSessionState
             )
         ) {
             Log.warn {
@@ -213,7 +212,7 @@
 
         val result = if (graphConfig.input == null) {
             cameraDevice.createCaptureSessionByOutputConfigurations(
-                outputs.all, captureSessionState, threads.camera2Handler
+                outputs.all, captureSessionState
             )
         } else {
             val outputConfig = graphConfig.input.stream.outputs.single()
@@ -224,8 +223,7 @@
                     outputConfig.format.value
                 ),
                 outputs.all,
-                captureSessionState,
-                threads.camera2Handler
+                captureSessionState
             )
         }
         if (!result) {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
index 47b388f..93fb66d 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/CaptureSessionWrapper.kt
@@ -66,59 +66,47 @@
     /**
      * @param request The settings for this exposure
      * @param listener The callback object to notify once this request has been processed.
-     * @param handler The handler on which the listener should be invoked, or null to use the
-     *   current thread's looper.
      * @return An unique capture sequence id.
      * @see [CameraCaptureSession.capture].
      */
     fun capture(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int?
 
     /**
      * @param requests A list of CaptureRequest(s) for this sequence of exposures
      * @param listener A callback object to notify each time one of the requests in the burst has
      *   been processed.
-     * @param handler The handler on which the listener should be invoked, or null to use the
-     *   current thread's looper.
      * @return An unique capture sequence id.
      * @see [CameraCaptureSession.captureBurst].
      */
     fun captureBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int?
 
     /**
      * @param requests A list of settings to cycle through indefinitely.
      * @param listener A callback object to notify each time one of the requests in the repeating
      *   bursts has finished processing.
-     * @param handler The handler on which the listener should be invoked, or null to use the
-     *   current thread's looper.
      * @return An unique capture sequence ID.
      * @see [CameraCaptureSession.setRepeatingBurst]
      */
     fun setRepeatingBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int?
 
     /**
      * @param request The request to repeat indefinitely.
      * @param listener The callback object to notify every time the request finishes processing.
-     * @param handler The handler on which the listener should be invoked, or null to use the
-     *   current thread's looper.
      * @return An unique capture sequence ID.
      * @see [CameraCaptureSession.setRepeatingRequest].
      */
     fun setRepeatingRequest(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int?
 
     /** @see [CameraCaptureSession.stopRepeating]. */
@@ -166,7 +154,8 @@
     private val stateCallback: CameraCaptureSessionWrapper.StateCallback,
     lastStateCallback: OnSessionFinalized?,
     private val cameraErrorListener: CameraErrorListener,
-    private val interopSessionStateCallback: CameraCaptureSession.StateCallback? = null
+    private val interopSessionStateCallback: CameraCaptureSession.StateCallback? = null,
+    private val callbackHandler: Handler
 ) : CameraCaptureSession.StateCallback() {
     private val _lastStateCallback = atomic(lastStateCallback)
     private val captureSession = atomic<CameraCaptureSessionWrapper?>(null)
@@ -237,9 +226,11 @@
         return if (Build.VERSION.SDK_INT >= 23 &&
             session is CameraConstrainedHighSpeedCaptureSession
         ) {
-            AndroidCameraConstrainedHighSpeedCaptureSession(device, session, cameraErrorListener)
+            AndroidCameraConstrainedHighSpeedCaptureSession(
+                device, session, cameraErrorListener, callbackHandler
+            )
         } else {
-            AndroidCameraCaptureSession(device, session, cameraErrorListener)
+            AndroidCameraCaptureSession(device, session, cameraErrorListener, callbackHandler)
         }
     }
 
@@ -272,6 +263,7 @@
     override val device: CameraDeviceWrapper,
     private val cameraCaptureSession: CameraCaptureSession,
     private val cameraErrorListener: CameraErrorListener,
+    private val callbackHandler: Handler
 ) : CameraCaptureSessionWrapper {
     override fun abortCaptures(): Boolean =
         catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
@@ -280,38 +272,34 @@
 
     override fun capture(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
         cameraCaptureSession.capture(
             request,
             listener,
-            handler
+            callbackHandler
         )
     }
 
     override fun captureBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
-        cameraCaptureSession.captureBurst(requests, listener, handler)
+        cameraCaptureSession.captureBurst(requests, listener, callbackHandler)
     }
 
     override fun setRepeatingBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
-        cameraCaptureSession.setRepeatingBurst(requests, listener, handler)
+        cameraCaptureSession.setRepeatingBurst(requests, listener, callbackHandler)
     }
 
     override fun setRepeatingRequest(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
-        cameraCaptureSession.setRepeatingRequest(request, listener, handler)
+        cameraCaptureSession.setRepeatingRequest(request, listener, callbackHandler)
     }
 
     override fun stopRepeating(): Boolean =
@@ -377,7 +365,8 @@
     device: CameraDeviceWrapper,
     private val session: CameraConstrainedHighSpeedCaptureSession,
     private val cameraErrorListener: CameraErrorListener,
-) : AndroidCameraCaptureSession(device, session, cameraErrorListener),
+    private val callbackHandler: Handler
+) : AndroidCameraCaptureSession(device, session, cameraErrorListener, callbackHandler),
     CameraConstrainedHighSpeedCaptureSessionWrapper {
     @Throws(ObjectUnavailableException::class)
     override fun createHighSpeedRequestList(request: CaptureRequest): List<CaptureRequest> {
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExtensionSessionWrapper.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExtensionSessionWrapper.kt
index e75ce9a..2d69b39 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExtensionSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/ExtensionSessionWrapper.kt
@@ -18,13 +18,21 @@
 
 package androidx.camera.camera2.pipe.compat
 
+import android.hardware.camera2.CameraCaptureSession
 import android.hardware.camera2.CameraExtensionSession
 import android.hardware.camera2.CaptureRequest
+import android.hardware.camera2.TotalCaptureResult
+import android.view.Surface
 import androidx.annotation.RequiresApi
+import androidx.camera.camera2.pipe.FrameNumber
 import androidx.camera.camera2.pipe.UnsafeWrapper
+import androidx.camera.camera2.pipe.core.Log
 import androidx.camera.camera2.pipe.internal.CameraErrorListener
+import java.util.LinkedList
+import java.util.Queue
 import java.util.concurrent.Executor
 import kotlin.reflect.KClass
+import kotlinx.atomicfu.AtomicLong
 import kotlinx.atomicfu.atomic
 
 /**
@@ -33,44 +41,17 @@
  * This interface has been modified to correct nullness, adjust exceptions, and to return or produce
  * wrapper interfaces instead of the native Camera2 types.
  */
-internal interface CameraExtensionSessionWrapper : UnsafeWrapper, AutoCloseable {
+internal interface CameraExtensionSessionWrapper : CameraCaptureSessionWrapper, UnsafeWrapper,
+    AutoCloseable {
 
     /**
      * @return The [CameraDeviceWrapper] that created this CameraExtensionSession
      * @see [CameraExtensionSession.getDevice]
      */
-    val device: CameraDeviceWrapper
-
-    /**
-     * @param request The settings for this exposure
-     * @param listener The callback object to notify once this request has been processed.
-     * @param executor The executor on which the listener should be invoked, or null to use the
-     *   current thread's looper.
-     * @return An unique capture sequence id.
-     * @see [CameraExtensionSession.capture].
-     */
-    fun capture(
-        request: CaptureRequest,
-        executor: Executor,
-        listener: CameraExtensionSession.ExtensionCaptureCallback
-    ): Int?
-
-    /**
-     * @param request The request to repeat indefinitely.
-     * @param executor The executor on which the listener should be invoked, or null to use the
-     *   current thread's looper.
-     * @param listener The callback object to notify every time the request finishes processing.
-     * @return An unique capture sequence ID.
-     * @see [CameraExtensionSession.setRepeatingRequest].
-     */
-    fun setRepeatingRequest(
-        request: CaptureRequest,
-        executor: Executor,
-        listener: CameraExtensionSession.ExtensionCaptureCallback
-    ): Int?
+    override val device: CameraDeviceWrapper
 
     /** @see [CameraExtensionSession.stopRepeating]. */
-    fun stopRepeating(): Boolean
+    override fun stopRepeating(): Boolean
 
     /** @see CameraExtensionSession.StateCallback */
     interface StateCallback : OnSessionFinalized {
@@ -91,7 +72,8 @@
     private val stateCallback: CameraExtensionSessionWrapper.StateCallback,
     lastStateCallback: OnSessionFinalized?,
     private val cameraErrorListener: CameraErrorListener,
-    private val interopSessionStateCallback: CameraExtensionSession.StateCallback? = null
+    private val interopSessionStateCallback: CameraExtensionSession.StateCallback? = null,
+    private val callbackExecutor: Executor
 ) : CameraExtensionSession.StateCallback() {
     private val _lastStateCallback = atomic(lastStateCallback)
     private val extensionSession = atomic<CameraExtensionSessionWrapper?>(null)
@@ -139,7 +121,7 @@
         session: CameraExtensionSession,
         cameraErrorListener: CameraErrorListener,
     ): CameraExtensionSessionWrapper {
-        return AndroidCameraExtensionSession(device, session, cameraErrorListener)
+        return AndroidCameraExtensionSession(device, session, cameraErrorListener, callbackExecutor)
     }
 
     private fun finalizeSession() {
@@ -159,25 +141,40 @@
     override val device: CameraDeviceWrapper,
     private val cameraExtensionSession: CameraExtensionSession,
     private val cameraErrorListener: CameraErrorListener,
+    private val callbackExecutor: Executor
 ) : CameraExtensionSessionWrapper {
+
+    private val frameNumbers: AtomicLong = atomic(0L)
+    private val frameNumbersMap: MutableMap<CameraExtensionSession, Long> = HashMap()
+
     override fun capture(
         request: CaptureRequest,
-        executor: Executor,
-        listener: CameraExtensionSession.ExtensionCaptureCallback
+        listener: CameraCaptureSession.CaptureCallback
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
+        val frameQueue = LinkedList<Long>()
         cameraExtensionSession.capture(
             request,
-            executor,
-            listener,
+            callbackExecutor,
+            Camera2CaptureSessionCallbackToExtensionCaptureCallback(
+                listener as Camera2CaptureCallback,
+                frameQueue
+            )
         )
     }
 
     override fun setRepeatingRequest(
         request: CaptureRequest,
-        executor: Executor,
-        listener: CameraExtensionSession.ExtensionCaptureCallback,
+        listener: CameraCaptureSession.CaptureCallback,
     ): Int? = catchAndReportCameraExceptions(device.cameraId, cameraErrorListener) {
-        cameraExtensionSession.setRepeatingRequest(request, executor, listener)
+        val frameQueue = LinkedList<Long>()
+        cameraExtensionSession.setRepeatingRequest(
+            request,
+            callbackExecutor,
+            Camera2CaptureSessionCallbackToExtensionCaptureCallback(
+                listener as Camera2CaptureCallback,
+                frameQueue
+            )
+        )
     }
 
     override fun stopRepeating(): Boolean =
@@ -185,6 +182,40 @@
             cameraExtensionSession.stopRepeating()
         } != null
 
+    override val isReprocessable: Boolean
+        get() = false
+
+    override val inputSurface: Surface?
+        get() = null
+
+    override fun abortCaptures(): Boolean = false
+
+    override fun captureBurst(
+        requests: List<CaptureRequest>,
+        listener: CameraCaptureSession.CaptureCallback
+    ): Int? {
+        requests.forEach { captureRequest -> capture(captureRequest, listener) }
+        return null
+    }
+
+    override fun setRepeatingBurst(
+        requests: List<CaptureRequest>,
+        listener: CameraCaptureSession.CaptureCallback
+    ): Int? {
+        check(requests.size == 1) {
+            "CameraExtensionSession does not support setRepeatingBurst for more than one" +
+                "CaptureRequest"
+        }
+        return setRepeatingRequest(requests.single(), listener)
+    }
+
+    override fun finalizeOutputConfigurations(
+        outputConfigs: List<OutputConfigurationWrapper>
+    ): Boolean {
+        Log.warn { "CameraExtensionSession does not support finalizeOutputConfigurations()" }
+        return false
+    }
+
     @Suppress("UNCHECKED_CAST")
     override fun <T : Any> unwrapAs(type: KClass<T>): T? =
         when (type) {
@@ -195,4 +226,57 @@
     override fun close() {
         return cameraExtensionSession.close()
     }
+
+    inner class Camera2CaptureSessionCallbackToExtensionCaptureCallback(
+        private val captureCallback: Camera2CaptureCallback,
+        private val frameQueue: Queue<Long>
+    ) : CameraExtensionSession.ExtensionCaptureCallback() {
+
+        override fun onCaptureStarted(
+            session: CameraExtensionSession,
+            request: CaptureRequest,
+            timestamp: Long
+        ) {
+            val frameNumber = frameNumbers.incrementAndGet()
+            frameNumbersMap[session] = frameNumber
+            frameQueue.add(frameNumber)
+            captureCallback.onCaptureStarted(
+                request,
+                frameNumber,
+                timestamp
+            )
+        }
+
+        override fun onCaptureProcessStarted(
+            session: CameraExtensionSession,
+            request: CaptureRequest
+        ) {
+        }
+
+        override fun onCaptureFailed(session: CameraExtensionSession, request: CaptureRequest) {
+            val frameNumber = frameQueue.remove()
+            captureCallback.onCaptureFailed(
+                request,
+                FrameNumber(frameNumber)
+            )
+        }
+
+        override fun onCaptureSequenceCompleted(session: CameraExtensionSession, sequenceId: Int) {
+            val frameNumber = frameNumbersMap[session]
+            captureCallback.onCaptureSequenceCompleted(sequenceId, frameNumber!!)
+        }
+
+        override fun onCaptureSequenceAborted(session: CameraExtensionSession, sequenceId: Int) {
+            captureCallback.onCaptureSequenceAborted(sequenceId)
+        }
+
+        override fun onCaptureResultAvailable(
+            session: CameraExtensionSession,
+            request: CaptureRequest,
+            result: TotalCaptureResult
+        ) {
+            val frameNumber = frameQueue.remove()
+            captureCallback.onCaptureCompleted(request, result, FrameNumber(frameNumber))
+        }
+    }
 }
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
index a5d46ea..c12e597 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpener.kt
@@ -166,7 +166,8 @@
     private val cameraErrorListener: CameraErrorListener,
     private val camera2DeviceCloser: Camera2DeviceCloser,
     private val timeSource: TimeSource,
-    private val cameraInteropConfig: CameraPipe.CameraInteropConfig?
+    private val cameraInteropConfig: CameraPipe.CameraInteropConfig?,
+    private val threads: Threads
 ) {
     internal suspend fun tryOpenCamera(
         cameraId: CameraId,
@@ -183,6 +184,7 @@
                 timeSource,
                 cameraErrorListener,
                 camera2DeviceCloser,
+                threads,
                 cameraInteropConfig?.cameraDeviceStateCallback,
                 cameraInteropConfig?.cameraSessionStateCallback
             )
diff --git a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
index 05cc5eb..456e87f 100644
--- a/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
+++ b/camera/camera-camera2-pipe/src/main/java/androidx/camera/camera2/pipe/compat/VirtualCamera.kt
@@ -31,6 +31,7 @@
 import androidx.camera.camera2.pipe.core.DurationNs
 import androidx.camera.camera2.pipe.core.Log
 import androidx.camera.camera2.pipe.core.SystemTimeSource
+import androidx.camera.camera2.pipe.core.Threads
 import androidx.camera.camera2.pipe.core.TimeSource
 import androidx.camera.camera2.pipe.core.TimestampNs
 import androidx.camera.camera2.pipe.core.Timestamps
@@ -248,6 +249,7 @@
     private val timeSource: TimeSource,
     private val cameraErrorListener: CameraErrorListener,
     private val camera2DeviceCloser: Camera2DeviceCloser,
+    private val threads: Threads,
     private val interopDeviceStateCallback: CameraDevice.StateCallback? = null,
     private val interopSessionStateCallback: StateCallback? = null,
     private val interopExtensionSessionStateCallback: CameraExtensionSession.StateCallback? = null
@@ -347,7 +349,8 @@
                     cameraId,
                     cameraErrorListener,
                     interopSessionStateCallback,
-                    interopExtensionSessionStateCallback
+                    interopExtensionSessionStateCallback,
+                    threads
                 )
             )
 
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
index 6b0573a..9ed1ce8 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/AndroidCaptureSessionStateCallbackTest.kt
@@ -18,6 +18,7 @@
 
 import android.hardware.camera2.CameraCaptureSession
 import android.os.Build
+import android.os.Handler
 import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import org.junit.Test
@@ -37,12 +38,14 @@
     private val previousStateCallback: CameraCaptureSessionWrapper.StateCallback = mock()
     private val captureSession: CameraCaptureSession = mock()
     private val cameraErrorListener: CameraErrorListener = mock()
+    private val callbackHandler: Handler = mock()
     private val androidStateCallback =
         AndroidCaptureSessionStateCallback(
             device = camera,
             stateCallback = stateCallback,
             lastStateCallback = previousStateCallback,
             cameraErrorListener = cameraErrorListener,
+            callbackHandler = callbackHandler
         )
 
     @Test
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
index 7cafd66..dcf8a14 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/CaptureSessionFactoryTest.kt
@@ -47,6 +47,7 @@
 import androidx.camera.camera2.pipe.testing.FakeCaptureSequence
 import androidx.camera.camera2.pipe.testing.FakeCaptureSequenceProcessor
 import androidx.camera.camera2.pipe.testing.FakeGraphProcessor
+import androidx.camera.camera2.pipe.testing.FakeThreads
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import androidx.camera.camera2.pipe.testing.RobolectricCameras
 import androidx.test.core.app.ApplicationProvider
@@ -116,7 +117,8 @@
                     testCamera.metadata,
                     testCamera.cameraDevice,
                     testCamera.cameraId,
-                    cameraErrorListener
+                    cameraErrorListener,
+                    threads = FakeThreads.fromTestScope(this)
                 ),
                 mapOf(stream1.id to surface),
                 captureSessionState =
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
index c6f20ef..7c5d185 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/RetryingCameraStateOpenerTest.kt
@@ -35,12 +35,14 @@
 import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.FakeCamera2DeviceCloser
 import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
+import androidx.camera.camera2.pipe.testing.FakeThreads
 import androidx.camera.camera2.pipe.testing.FakeTimeSource
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.async
 import kotlinx.coroutines.delay
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
@@ -101,6 +103,7 @@
             cameraDeviceCloser,
             fakeTimeSource,
             cameraInteropConfig = null,
+            FakeThreads.fromTestScope(TestScope())
         )
 
     private val cameraAvailabilityMonitor =
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
index a77eec4..eda65e8 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/compat/VirtualCameraTest.kt
@@ -31,6 +31,7 @@
 import androidx.camera.camera2.pipe.graph.GraphListener
 import androidx.camera.camera2.pipe.internal.CameraErrorListener
 import androidx.camera.camera2.pipe.testing.FakeCamera2DeviceCloser
+import androidx.camera.camera2.pipe.testing.FakeThreads
 import androidx.camera.camera2.pipe.testing.RobolectricCameraPipeTestRunner
 import androidx.camera.camera2.pipe.testing.RobolectricCameras
 import com.google.common.truth.Truth.assertThat
@@ -41,6 +42,7 @@
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -105,6 +107,7 @@
                         testCamera.cameraDevice,
                         testCamera.cameraId,
                         cameraErrorListener,
+                        threads = FakeThreads.fromTestScope(this)
                     )
                 )
             )
@@ -137,6 +140,7 @@
             testCamera.cameraDevice,
             testCamera.cameraId,
             cameraErrorListener,
+            threads = FakeThreads.fromTestScope(this)
         )
         val cameraStateClosing = CameraStateClosing()
         val cameraStateClosed =
@@ -190,6 +194,7 @@
                         testCamera.cameraDevice,
                         testCamera.cameraId,
                         cameraErrorListener,
+                        threads = FakeThreads.fromTestScope(this)
                     )
                 )
             )
@@ -227,6 +232,7 @@
                         testCamera.cameraDevice,
                         testCamera.cameraId,
                         cameraErrorListener,
+                        threads = FakeThreads.fromTestScope(this)
                     )
                 )
             )
@@ -251,7 +257,7 @@
         val surfaceTexture = SurfaceTexture(0).also { it.setDefaultBufferSize(640, 480) }
         val surface = Surface(surfaceTexture)
         val callback: CameraCaptureSessionWrapper.StateCallback = mock()
-        val result = virtualAndroidCameraState.createCaptureSession(listOf(surface), callback, null)
+        val result = virtualAndroidCameraState.createCaptureSession(listOf(surface), callback)
         assertThat(result).isFalse()
         verify(callback, times(1)).onSessionFinalized()
         surface.release()
@@ -261,6 +267,7 @@
 
 @RunWith(RobolectricCameraPipeTestRunner::class)
 @Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+@OptIn(ExperimentalCoroutinesApi::class)
 internal class AndroidCameraDeviceTest {
     private val mainLooper = shadowOf(getMainLooper())
     private val cameraId = RobolectricCameras.create()
@@ -299,6 +306,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         assertThat(listener.state.value).isInstanceOf(CameraStateUnopened.javaClass)
@@ -346,6 +354,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.onDisconnected(testCamera.cameraDevice)
@@ -369,6 +378,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.close()
@@ -389,6 +399,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.closeWith(IllegalArgumentException("Test Exception"))
@@ -409,6 +420,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.onError(testCamera.cameraDevice, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE)
@@ -431,6 +443,7 @@
                 timeSource,
                 cameraErrorListener,
                 cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.onOpened(testCamera.cameraDevice)
@@ -453,7 +466,8 @@
                 attemptTimestampNanos = now,
                 timeSource,
                 cameraErrorListener,
-                cameraDeviceCloser
+                cameraDeviceCloser,
+                FakeThreads.fromTestScope(TestScope())
             )
 
         listener.onError(testCamera.cameraDevice, CameraDevice.StateCallback.ERROR_CAMERA_SERVICE)
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
index f46885f..0fdd447 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCameraDeviceWrapper.kt
@@ -21,7 +21,6 @@
 import android.hardware.camera2.TotalCaptureResult
 import android.hardware.camera2.params.InputConfiguration
 import android.os.Build
-import android.os.Handler
 import android.view.Surface
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.CameraId
@@ -63,8 +62,7 @@
 
     override fun createCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean {
         createFakeCaptureSession(stateCallback)
         return true
@@ -78,8 +76,7 @@
     override fun createReprocessableCaptureSession(
         input: InputConfiguration,
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean {
         createFakeCaptureSession(stateCallback)
         return true
@@ -87,8 +84,7 @@
 
     override fun createConstrainedHighSpeedCaptureSession(
         outputs: List<Surface>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean {
         createFakeCaptureSession(stateCallback)
         return true
@@ -96,8 +92,7 @@
 
     override fun createCaptureSessionByOutputConfigurations(
         outputConfigurations: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean {
         createFakeCaptureSession(stateCallback)
         return true
@@ -106,8 +101,7 @@
     override fun createReprocessableCaptureSessionByConfigurations(
         inputConfig: InputConfigData,
         outputs: List<OutputConfigurationWrapper>,
-        stateCallback: CameraCaptureSessionWrapper.StateCallback,
-        handler: Handler?
+        stateCallback: CameraCaptureSessionWrapper.StateCallback
     ): Boolean {
         createFakeCaptureSession(stateCallback)
         return true
diff --git a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
index bc4d75d..1b63efa 100644
--- a/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
+++ b/camera/camera-camera2-pipe/src/test/java/androidx/camera/camera2/pipe/testing/FakeCaptureSessionWrapper.kt
@@ -18,7 +18,6 @@
 
 import android.hardware.camera2.CameraCaptureSession
 import android.hardware.camera2.CaptureRequest
-import android.os.Handler
 import android.view.Surface
 import androidx.camera.camera2.pipe.compat.CameraCaptureSessionWrapper
 import androidx.camera.camera2.pipe.compat.CameraDeviceWrapper
@@ -50,8 +49,7 @@
 
     override fun capture(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int {
         lastCapture = listOf(request)
         lastCaptureCallback = listener
@@ -62,8 +60,7 @@
 
     override fun captureBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int {
         lastCapture = requests.toList()
         lastCaptureCallback = listener
@@ -74,8 +71,7 @@
 
     override fun setRepeatingBurst(
         requests: List<CaptureRequest>,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int {
         lastRepeating = requests.toList()
         lastRepeatingCallback = listener
@@ -86,8 +82,7 @@
 
     override fun setRepeatingRequest(
         request: CaptureRequest,
-        listener: CameraCaptureSession.CaptureCallback,
-        handler: Handler?
+        listener: CameraCaptureSession.CaptureCallback
     ): Int {
         lastRepeating = listOf(request)
         lastRepeatingCallback = listener
diff --git a/camera/camera-camera2/api/1.3.0-beta01.txt b/camera/camera-camera2/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..ea5cacc
--- /dev/null
+++ b/camera/camera-camera2/api/1.3.0-beta01.txt
@@ -0,0 +1,54 @@
+// Signature format: 4.0
+package androidx.camera.camera2 {
+
+  @RequiresApi(21) public final class Camera2Config {
+    method public static androidx.camera.core.CameraXConfig defaultConfig();
+  }
+
+}
+
+package androidx.camera.camera2.interop {
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> addCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> clearCaptureRequestOptions();
+    method public static androidx.camera.camera2.interop.Camera2CameraControl from(androidx.camera.core.CameraControl);
+    method public androidx.camera.camera2.interop.CaptureRequestOptions getCaptureRequestOptions();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraInfo {
+    method public static androidx.camera.camera2.interop.Camera2CameraInfo from(androidx.camera.core.CameraInfo);
+    method public <T> T? getCameraCharacteristic(android.hardware.camera2.CameraCharacteristics.Key<T!>);
+    method public String getCameraId();
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2Interop {
+  }
+
+  @RequiresApi(21) public static final class Camera2Interop.Extender<T> {
+    ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T!>);
+    method public <ValueT> androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback);
+    method @RequiresApi(28) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setPhysicalCameraId(String);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionStateCallback(android.hardware.camera2.CameraCaptureSession.StateCallback);
+    method @RequiresApi(33) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setStreamUseCase(long);
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public class CaptureRequestOptions {
+    method public <ValueT> ValueT? getCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+  }
+
+  @RequiresApi(21) public static final class CaptureRequestOptions.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.camera2.interop.CaptureRequestOptions> {
+    ctor public CaptureRequestOptions.Builder();
+    method public androidx.camera.camera2.interop.CaptureRequestOptions build();
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCamera2Interop {
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-camera2/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-camera2/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-camera2/api/restricted_1.3.0-beta01.txt b/camera/camera-camera2/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..ea5cacc
--- /dev/null
+++ b/camera/camera-camera2/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,54 @@
+// Signature format: 4.0
+package androidx.camera.camera2 {
+
+  @RequiresApi(21) public final class Camera2Config {
+    method public static androidx.camera.core.CameraXConfig defaultConfig();
+  }
+
+}
+
+package androidx.camera.camera2.interop {
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> addCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> clearCaptureRequestOptions();
+    method public static androidx.camera.camera2.interop.Camera2CameraControl from(androidx.camera.core.CameraControl);
+    method public androidx.camera.camera2.interop.CaptureRequestOptions getCaptureRequestOptions();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setCaptureRequestOptions(androidx.camera.camera2.interop.CaptureRequestOptions);
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2CameraInfo {
+    method public static androidx.camera.camera2.interop.Camera2CameraInfo from(androidx.camera.core.CameraInfo);
+    method public <T> T? getCameraCharacteristic(android.hardware.camera2.CameraCharacteristics.Key<T!>);
+    method public String getCameraId();
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public final class Camera2Interop {
+  }
+
+  @RequiresApi(21) public static final class Camera2Interop.Extender<T> {
+    ctor public Camera2Interop.Extender(androidx.camera.core.ExtendableBuilder<T!>);
+    method public <ValueT> androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setDeviceStateCallback(android.hardware.camera2.CameraDevice.StateCallback);
+    method @RequiresApi(28) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setPhysicalCameraId(String);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionCaptureCallback(android.hardware.camera2.CameraCaptureSession.CaptureCallback);
+    method public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setSessionStateCallback(android.hardware.camera2.CameraCaptureSession.StateCallback);
+    method @RequiresApi(33) public androidx.camera.camera2.interop.Camera2Interop.Extender<T!> setStreamUseCase(long);
+  }
+
+  @RequiresApi(21) @androidx.camera.camera2.interop.ExperimentalCamera2Interop public class CaptureRequestOptions {
+    method public <ValueT> ValueT? getCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+  }
+
+  @RequiresApi(21) public static final class CaptureRequestOptions.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.camera2.interop.CaptureRequestOptions> {
+    ctor public CaptureRequestOptions.Builder();
+    method public androidx.camera.camera2.interop.CaptureRequestOptions build();
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder clearCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>);
+    method public <ValueT> androidx.camera.camera2.interop.CaptureRequestOptions.Builder setCaptureRequestOption(android.hardware.camera2.CaptureRequest.Key<ValueT!>, ValueT);
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCamera2Interop {
+  }
+
+}
+
diff --git a/camera/camera-camera2/src/test/resources/robolectric.properties b/camera/camera-camera2/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/camera/camera-camera2/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/camera/camera-core/api/1.3.0-beta01.txt b/camera/camera-core/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..5cda9c6
--- /dev/null
+++ b/camera/camera-core/api/1.3.0-beta01.txt
@@ -0,0 +1,612 @@
+// Signature format: 4.0
+package androidx.camera.core {
+
+  @RequiresApi(21) public class AspectRatio {
+    field public static final int RATIO_16_9 = 1; // 0x1
+    field public static final int RATIO_4_3 = 0; // 0x0
+    field public static final int RATIO_DEFAULT = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public interface Camera {
+    method public androidx.camera.core.CameraControl getCameraControl();
+    method public androidx.camera.core.CameraInfo getCameraInfo();
+  }
+
+  @RequiresApi(21) public interface CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> cancelFocusAndMetering();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> setExposureCompensationIndex(int);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.camera.core.FocusMeteringResult!> startFocusAndMetering(androidx.camera.core.FocusMeteringAction);
+  }
+
+  public static final class CameraControl.OperationCanceledException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public abstract class CameraEffect {
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.ImageProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.SurfaceProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public androidx.core.util.Consumer<java.lang.Throwable!> getErrorListener();
+    method public java.util.concurrent.Executor getExecutor();
+    method public androidx.camera.core.SurfaceProcessor? getSurfaceProcessor();
+    method public int getTargets();
+    field public static final int IMAGE_CAPTURE = 4; // 0x4
+    field public static final int PREVIEW = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 2; // 0x2
+  }
+
+  @RequiresApi(21) public interface CameraFilter {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+  }
+
+  @RequiresApi(21) public interface CameraInfo {
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.CameraState!> getCameraState();
+    method public androidx.camera.core.ExposureState getExposureState();
+    method @FloatRange(from=0, fromInclusive=false) public default float getIntrinsicZoomRatio();
+    method public default int getLensFacing();
+    method public int getSensorRotationDegrees();
+    method public int getSensorRotationDegrees(int);
+    method public default java.util.Set<android.util.Range<java.lang.Integer!>!> getSupportedFrameRateRanges();
+    method public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method public boolean hasFlashUnit();
+    method public default boolean isFocusMeteringSupported(androidx.camera.core.FocusMeteringAction);
+    method @androidx.camera.core.ExperimentalZeroShutterLag public default boolean isZslSupported();
+  }
+
+  @RequiresApi(21) public final class CameraInfoUnavailableException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public interface CameraProvider {
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+  }
+
+  @RequiresApi(21) public final class CameraSelector {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+    field public static final androidx.camera.core.CameraSelector DEFAULT_BACK_CAMERA;
+    field public static final androidx.camera.core.CameraSelector DEFAULT_FRONT_CAMERA;
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field @androidx.camera.core.ExperimentalLensFacing public static final int LENS_FACING_EXTERNAL = 2; // 0x2
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_FACING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class CameraSelector.Builder {
+    ctor public CameraSelector.Builder();
+    method public androidx.camera.core.CameraSelector.Builder addCameraFilter(androidx.camera.core.CameraFilter);
+    method public androidx.camera.core.CameraSelector build();
+    method public androidx.camera.core.CameraSelector.Builder requireLensFacing(int);
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class CameraState {
+    ctor public CameraState();
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type);
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type, androidx.camera.core.CameraState.StateError?);
+    method public abstract androidx.camera.core.CameraState.StateError? getError();
+    method public abstract androidx.camera.core.CameraState.Type getType();
+    field public static final int ERROR_CAMERA_DISABLED = 5; // 0x5
+    field public static final int ERROR_CAMERA_FATAL_ERROR = 6; // 0x6
+    field public static final int ERROR_CAMERA_IN_USE = 2; // 0x2
+    field public static final int ERROR_DO_NOT_DISTURB_MODE_ENABLED = 7; // 0x7
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 1; // 0x1
+    field public static final int ERROR_OTHER_RECOVERABLE_ERROR = 3; // 0x3
+    field public static final int ERROR_STREAM_CONFIG = 4; // 0x4
+  }
+
+  public enum CameraState.ErrorType {
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType CRITICAL;
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType RECOVERABLE;
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class CameraState.StateError {
+    ctor public CameraState.StateError();
+    method public static androidx.camera.core.CameraState.StateError create(int);
+    method public static androidx.camera.core.CameraState.StateError create(int, Throwable?);
+    method public abstract Throwable? getCause();
+    method public abstract int getCode();
+    method public androidx.camera.core.CameraState.ErrorType getType();
+  }
+
+  public enum CameraState.Type {
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSED;
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSING;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPEN;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPENING;
+    enum_constant public static final androidx.camera.core.CameraState.Type PENDING_OPEN;
+  }
+
+  @RequiresApi(21) public class CameraUnavailableException extends java.lang.Exception {
+    ctor public CameraUnavailableException(int);
+    ctor public CameraUnavailableException(int, String?);
+    ctor public CameraUnavailableException(int, String?, Throwable?);
+    ctor public CameraUnavailableException(int, Throwable?);
+    method public int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+    field public static final int CAMERA_IN_USE = 4; // 0x4
+    field public static final int CAMERA_MAX_IN_USE = 5; // 0x5
+    field public static final int CAMERA_UNAVAILABLE_DO_NOT_DISTURB = 6; // 0x6
+    field public static final int CAMERA_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class CameraXConfig {
+    method public androidx.camera.core.CameraSelector? getAvailableCamerasLimiter(androidx.camera.core.CameraSelector?);
+    method public java.util.concurrent.Executor? getCameraExecutor(java.util.concurrent.Executor?);
+    method public int getMinimumLoggingLevel();
+    method public android.os.Handler? getSchedulerHandler(android.os.Handler?);
+  }
+
+  public static final class CameraXConfig.Builder {
+    method public androidx.camera.core.CameraXConfig build();
+    method public static androidx.camera.core.CameraXConfig.Builder fromConfig(androidx.camera.core.CameraXConfig);
+    method public androidx.camera.core.CameraXConfig.Builder setAvailableCamerasLimiter(androidx.camera.core.CameraSelector);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.CameraXConfig.Builder setMinimumLoggingLevel(@IntRange(from=android.util.Log.DEBUG, to=android.util.Log.ERROR) int);
+    method public androidx.camera.core.CameraXConfig.Builder setSchedulerHandler(android.os.Handler);
+  }
+
+  public static interface CameraXConfig.Provider {
+    method public androidx.camera.core.CameraXConfig getCameraXConfig();
+  }
+
+  @RequiresApi(21) public class ConcurrentCamera {
+    ctor public ConcurrentCamera(java.util.List<androidx.camera.core.Camera!>);
+    method public java.util.List<androidx.camera.core.Camera!> getCameras();
+  }
+
+  public static final class ConcurrentCamera.SingleCameraConfig {
+    ctor public ConcurrentCamera.SingleCameraConfig(androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup, androidx.lifecycle.LifecycleOwner);
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LifecycleOwner getLifecycleOwner();
+    method public androidx.camera.core.UseCaseGroup getUseCaseGroup();
+  }
+
+  @RequiresApi(21) public final class DisplayOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public DisplayOrientedMeteringPointFactory(android.view.Display, androidx.camera.core.CameraInfo, float, float);
+  }
+
+  @RequiresApi(21) public final class DynamicRange {
+    ctor public DynamicRange(int, int);
+    method public int getBitDepth();
+    method public int getEncoding();
+    field public static final int BIT_DEPTH_10_BIT = 10; // 0xa
+    field public static final int BIT_DEPTH_8_BIT = 8; // 0x8
+    field public static final int BIT_DEPTH_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_10_BIT;
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_8_BIT;
+    field public static final int ENCODING_DOLBY_VISION = 6; // 0x6
+    field public static final int ENCODING_HDR10 = 4; // 0x4
+    field public static final int ENCODING_HDR10_PLUS = 5; // 0x5
+    field public static final int ENCODING_HDR_UNSPECIFIED = 2; // 0x2
+    field public static final int ENCODING_HLG = 3; // 0x3
+    field public static final int ENCODING_SDR = 1; // 0x1
+    field public static final int ENCODING_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange HDR10_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR10_PLUS_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR_UNSPECIFIED_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HLG_10_BIT;
+    field public static final androidx.camera.core.DynamicRange SDR;
+    field public static final androidx.camera.core.DynamicRange UNSPECIFIED;
+  }
+
+  @RequiresApi(21) @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalGetImage {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalUseCaseApi {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalZeroShutterLag {
+  }
+
+  @RequiresApi(21) public interface ExposureState {
+    method public int getExposureCompensationIndex();
+    method public android.util.Range<java.lang.Integer!> getExposureCompensationRange();
+    method public android.util.Rational getExposureCompensationStep();
+    method public boolean isExposureCompensationSupported();
+  }
+
+  @RequiresApi(21) public interface ExtendableBuilder<T> {
+    method public T build();
+  }
+
+  @RequiresApi(21) public final class FocusMeteringAction {
+    method public long getAutoCancelDurationInMillis();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAe();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAf();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAwb();
+    method public boolean isAutoCancelEnabled();
+    field public static final int FLAG_AE = 2; // 0x2
+    field public static final int FLAG_AF = 1; // 0x1
+    field public static final int FLAG_AWB = 4; // 0x4
+  }
+
+  public static class FocusMeteringAction.Builder {
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint);
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction build();
+    method public androidx.camera.core.FocusMeteringAction.Builder disableAutoCancel();
+    method public androidx.camera.core.FocusMeteringAction.Builder setAutoCancelDuration(@IntRange(from=1) long, java.util.concurrent.TimeUnit);
+  }
+
+  @RequiresApi(21) public final class FocusMeteringResult {
+    method public boolean isFocusSuccessful();
+  }
+
+  @RequiresApi(21) public final class ImageAnalysis extends androidx.camera.core.UseCase {
+    method public void clearAnalyzer();
+    method @androidx.camera.core.ExperimentalUseCaseApi public java.util.concurrent.Executor? getBackgroundExecutor();
+    method public int getBackpressureStrategy();
+    method public int getImageQueueDepth();
+    method public int getOutputImageFormat();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public boolean isOutputImageRotationEnabled();
+    method public void setAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method public void setTargetRotation(int);
+    field public static final int COORDINATE_SYSTEM_ORIGINAL = 0; // 0x0
+    field public static final int OUTPUT_IMAGE_FORMAT_RGBA_8888 = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_YUV_420_888 = 1; // 0x1
+    field public static final int STRATEGY_BLOCK_PRODUCER = 1; // 0x1
+    field public static final int STRATEGY_KEEP_ONLY_LATEST = 0; // 0x0
+  }
+
+  public static interface ImageAnalysis.Analyzer {
+    method public void analyze(androidx.camera.core.ImageProxy);
+    method public default android.util.Size? getDefaultTargetResolution();
+    method public default int getTargetCoordinateSystem();
+    method public default void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class ImageAnalysis.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageAnalysis> {
+    ctor public ImageAnalysis.Builder();
+    method public androidx.camera.core.ImageAnalysis build();
+    method public androidx.camera.core.ImageAnalysis.Builder setBackgroundExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageAnalysis.Builder setBackpressureStrategy(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setImageQueueDepth(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setOutputImageFormat(int);
+    method @RequiresApi(23) public androidx.camera.core.ImageAnalysis.Builder setOutputImageRotationEnabled(boolean);
+    method public androidx.camera.core.ImageAnalysis.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
+    method public int getCaptureMode();
+    method public int getFlashMode();
+    method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public void setCropAspectRatio(android.util.Rational);
+    method public void setFlashMode(int);
+    method public void setTargetRotation(int);
+    method public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int CAPTURE_MODE_MAXIMIZE_QUALITY = 0; // 0x0
+    field public static final int CAPTURE_MODE_MINIMIZE_LATENCY = 1; // 0x1
+    field @androidx.camera.core.ExperimentalZeroShutterLag public static final int CAPTURE_MODE_ZERO_SHUTTER_LAG = 2; // 0x2
+    field public static final int ERROR_CAMERA_CLOSED = 3; // 0x3
+    field public static final int ERROR_CAPTURE_FAILED = 2; // 0x2
+    field public static final int ERROR_FILE_IO = 1; // 0x1
+    field public static final int ERROR_INVALID_CAMERA = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int FLASH_MODE_AUTO = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 2; // 0x2
+    field public static final int FLASH_MODE_ON = 1; // 0x1
+  }
+
+  public static final class ImageCapture.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageCapture> {
+    ctor public ImageCapture.Builder();
+    method public androidx.camera.core.ImageCapture build();
+    method public androidx.camera.core.ImageCapture.Builder setCaptureMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageCapture.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageCapture.Builder setTargetRotation(int);
+  }
+
+  public static final class ImageCapture.Metadata {
+    ctor public ImageCapture.Metadata();
+    method public android.location.Location? getLocation();
+    method public boolean isReversedHorizontal();
+    method public boolean isReversedVertical();
+    method public void setLocation(android.location.Location?);
+    method public void setReversedHorizontal(boolean);
+    method public void setReversedVertical(boolean);
+  }
+
+  public abstract static class ImageCapture.OnImageCapturedCallback {
+    ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
+    method public void onError(androidx.camera.core.ImageCaptureException);
+  }
+
+  public static interface ImageCapture.OnImageSavedCallback {
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+  }
+
+  public static final class ImageCapture.OutputFileOptions {
+  }
+
+  public static final class ImageCapture.OutputFileOptions.Builder {
+    ctor public ImageCapture.OutputFileOptions.Builder(android.content.ContentResolver, android.net.Uri, android.content.ContentValues);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.File);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.OutputStream);
+    method public androidx.camera.core.ImageCapture.OutputFileOptions build();
+    method public androidx.camera.core.ImageCapture.OutputFileOptions.Builder setMetadata(androidx.camera.core.ImageCapture.Metadata);
+  }
+
+  public static class ImageCapture.OutputFileResults {
+    method public android.net.Uri? getSavedUri();
+  }
+
+  @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
+    ctor public ImageCaptureException(int, String, Throwable?);
+    method public int getImageCaptureError();
+  }
+
+  @RequiresApi(21) public interface ImageInfo {
+    method public int getRotationDegrees();
+    method public default android.graphics.Matrix getSensorToBufferTransformMatrix();
+    method public long getTimestamp();
+  }
+
+  public interface ImageProcessor {
+    method public androidx.camera.core.ImageProcessor.Response process(androidx.camera.core.ImageProcessor.Request) throws androidx.camera.core.ProcessingException;
+  }
+
+  public static interface ImageProcessor.Request {
+    method public androidx.camera.core.ImageProxy getInputImage();
+    method public int getOutputFormat();
+  }
+
+  public static interface ImageProcessor.Response {
+    method public androidx.camera.core.ImageProxy getOutputImage();
+  }
+
+  @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
+    method public void close();
+    method public android.graphics.Rect getCropRect();
+    method public int getFormat();
+    method public int getHeight();
+    method @androidx.camera.core.ExperimentalGetImage public android.media.Image? getImage();
+    method public androidx.camera.core.ImageInfo getImageInfo();
+    method public androidx.camera.core.ImageProxy.PlaneProxy![] getPlanes();
+    method public int getWidth();
+    method public void setCropRect(android.graphics.Rect?);
+    method public default android.graphics.Bitmap toBitmap();
+  }
+
+  public static interface ImageProxy.PlaneProxy {
+    method public java.nio.ByteBuffer getBuffer();
+    method public int getPixelStride();
+    method public int getRowStride();
+  }
+
+  @RequiresApi(21) public class InitializationException extends java.lang.Exception {
+    ctor public InitializationException(String?);
+    ctor public InitializationException(String?, Throwable?);
+    ctor public InitializationException(Throwable?);
+  }
+
+  @RequiresApi(21) public class MeteringPoint {
+    method public float getSize();
+  }
+
+  @RequiresApi(21) public abstract class MeteringPointFactory {
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float);
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float, float);
+    method public static float getDefaultPointSize();
+  }
+
+  @RequiresApi(21) public class MirrorMode {
+    field public static final int MIRROR_MODE_OFF = 0; // 0x0
+    field public static final int MIRROR_MODE_ON = 1; // 0x1
+    field public static final int MIRROR_MODE_ON_FRONT_ONLY = 2; // 0x2
+  }
+
+  @RequiresApi(21) public final class Preview extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method @UiThread public void setSurfaceProvider(androidx.camera.core.Preview.SurfaceProvider?);
+    method @UiThread public void setSurfaceProvider(java.util.concurrent.Executor, androidx.camera.core.Preview.SurfaceProvider?);
+    method public void setTargetRotation(int);
+  }
+
+  public static final class Preview.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.Preview> {
+    ctor public Preview.Builder();
+    method public androidx.camera.core.Preview build();
+    method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.Preview.Builder setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.core.Preview.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.Preview.Builder setTargetRotation(int);
+  }
+
+  public static interface Preview.SurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  public class ProcessingException extends java.lang.Exception {
+    ctor public ProcessingException();
+  }
+
+  @RequiresApi(21) public class ResolutionInfo {
+    ctor public ResolutionInfo(android.util.Size, android.graphics.Rect, int);
+    method public android.graphics.Rect getCropRect();
+    method public android.util.Size getResolution();
+    method public int getRotationDegrees();
+  }
+
+  @RequiresApi(21) public class SurfaceOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public SurfaceOrientedMeteringPointFactory(float, float);
+    ctor public SurfaceOrientedMeteringPointFactory(float, float, androidx.camera.core.UseCase);
+  }
+
+  public interface SurfaceOutput extends java.io.Closeable {
+    method public void close();
+    method public android.util.Size getSize();
+    method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
+    method public int getTargets();
+    method public void updateTransformMatrix(float[], float[]);
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceOutput.Event {
+    method public abstract int getEventCode();
+    method public abstract androidx.camera.core.SurfaceOutput getSurfaceOutput();
+    field public static final int EVENT_REQUEST_CLOSE = 0; // 0x0
+  }
+
+  public interface SurfaceProcessor {
+    method public void onInputSurface(androidx.camera.core.SurfaceRequest) throws androidx.camera.core.ProcessingException;
+    method public void onOutputSurface(androidx.camera.core.SurfaceOutput) throws androidx.camera.core.ProcessingException;
+  }
+
+  @RequiresApi(21) public final class SurfaceRequest {
+    method public void addRequestCancellationListener(java.util.concurrent.Executor, Runnable);
+    method public void clearTransformationInfoListener();
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public android.util.Size getResolution();
+    method public boolean invalidate();
+    method public void provideSurface(android.view.Surface, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result!>);
+    method public void setTransformationInfoListener(java.util.concurrent.Executor, androidx.camera.core.SurfaceRequest.TransformationInfoListener);
+    method public boolean willNotProvideSurface();
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.Result {
+    method public abstract int getResultCode();
+    method public abstract android.view.Surface getSurface();
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract int getRotationDegrees();
+  }
+
+  public static interface SurfaceRequest.TransformationInfoListener {
+    method public void onTransformationInfoUpdate(androidx.camera.core.SurfaceRequest.TransformationInfo);
+  }
+
+  @RequiresApi(21) public class TorchState {
+    field public static final int OFF = 0; // 0x0
+    field public static final int ON = 1; // 0x1
+  }
+
+  @RequiresApi(21) public abstract class UseCase {
+    method public static int snapToSurfaceRotation(@IntRange(from=0, to=359) int);
+  }
+
+  @RequiresApi(21) public final class UseCaseGroup {
+    method public java.util.List<androidx.camera.core.CameraEffect!> getEffects();
+    method public java.util.List<androidx.camera.core.UseCase!> getUseCases();
+    method public androidx.camera.core.ViewPort? getViewPort();
+  }
+
+  public static final class UseCaseGroup.Builder {
+    ctor public UseCaseGroup.Builder();
+    method public androidx.camera.core.UseCaseGroup.Builder addEffect(androidx.camera.core.CameraEffect);
+    method public androidx.camera.core.UseCaseGroup.Builder addUseCase(androidx.camera.core.UseCase);
+    method public androidx.camera.core.UseCaseGroup build();
+    method public androidx.camera.core.UseCaseGroup.Builder setViewPort(androidx.camera.core.ViewPort);
+  }
+
+  @RequiresApi(21) public final class ViewPort {
+    method public android.util.Rational getAspectRatio();
+    method public int getLayoutDirection();
+    method public int getRotation();
+    method public int getScaleType();
+    field public static final int FILL_CENTER = 1; // 0x1
+    field public static final int FILL_END = 2; // 0x2
+    field public static final int FILL_START = 0; // 0x0
+    field public static final int FIT = 3; // 0x3
+  }
+
+  public static final class ViewPort.Builder {
+    ctor public ViewPort.Builder(android.util.Rational, int);
+    method public androidx.camera.core.ViewPort build();
+    method public androidx.camera.core.ViewPort.Builder setLayoutDirection(int);
+    method public androidx.camera.core.ViewPort.Builder setScaleType(int);
+  }
+
+  @RequiresApi(21) public interface ZoomState {
+    method public float getLinearZoom();
+    method public float getMaxZoomRatio();
+    method public float getMinZoomRatio();
+    method public float getZoomRatio();
+  }
+
+}
+
+package androidx.camera.core.resolutionselector {
+
+  @RequiresApi(21) public final class AspectRatioStrategy {
+    ctor public AspectRatioStrategy(int, int);
+    method public int getFallbackRule();
+    method public int getPreferredAspectRatio();
+    field public static final int FALLBACK_RULE_AUTO = 1; // 0x1
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_16_9_FALLBACK_AUTO_STRATEGY;
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_4_3_FALLBACK_AUTO_STRATEGY;
+  }
+
+  @RequiresApi(21) public interface ResolutionFilter {
+    method public java.util.List<android.util.Size!> filter(java.util.List<android.util.Size!>, int);
+  }
+
+  @RequiresApi(21) public final class ResolutionSelector {
+    method public int getAllowedResolutionMode();
+    method public androidx.camera.core.resolutionselector.AspectRatioStrategy getAspectRatioStrategy();
+    method public androidx.camera.core.resolutionselector.ResolutionFilter? getResolutionFilter();
+    method public androidx.camera.core.resolutionselector.ResolutionStrategy? getResolutionStrategy();
+    field public static final int PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION = 0; // 0x0
+    field public static final int PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE = 1; // 0x1
+  }
+
+  public static final class ResolutionSelector.Builder {
+    ctor public ResolutionSelector.Builder();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector build();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAllowedResolutionMode(int);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAspectRatioStrategy(androidx.camera.core.resolutionselector.AspectRatioStrategy);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionFilter(androidx.camera.core.resolutionselector.ResolutionFilter);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionStrategy(androidx.camera.core.resolutionselector.ResolutionStrategy);
+  }
+
+  @RequiresApi(21) public final class ResolutionStrategy {
+    ctor public ResolutionStrategy(android.util.Size, int);
+    method public android.util.Size? getBoundSize();
+    method public int getFallbackRule();
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER = 2; // 0x2
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER = 1; // 0x1
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER = 4; // 0x4
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER = 3; // 0x3
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.ResolutionStrategy HIGHEST_AVAILABLE_STRATEGY;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-core/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-core/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-core/api/restricted_1.3.0-beta01.txt b/camera/camera-core/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..5cda9c6
--- /dev/null
+++ b/camera/camera-core/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,612 @@
+// Signature format: 4.0
+package androidx.camera.core {
+
+  @RequiresApi(21) public class AspectRatio {
+    field public static final int RATIO_16_9 = 1; // 0x1
+    field public static final int RATIO_4_3 = 0; // 0x0
+    field public static final int RATIO_DEFAULT = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public interface Camera {
+    method public androidx.camera.core.CameraControl getCameraControl();
+    method public androidx.camera.core.CameraInfo getCameraInfo();
+  }
+
+  @RequiresApi(21) public interface CameraControl {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> cancelFocusAndMetering();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> setExposureCompensationIndex(int);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.camera.core.FocusMeteringResult!> startFocusAndMetering(androidx.camera.core.FocusMeteringAction);
+  }
+
+  public static final class CameraControl.OperationCanceledException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public abstract class CameraEffect {
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.ImageProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    ctor protected CameraEffect(int, java.util.concurrent.Executor, androidx.camera.core.SurfaceProcessor, androidx.core.util.Consumer<java.lang.Throwable!>);
+    method public androidx.core.util.Consumer<java.lang.Throwable!> getErrorListener();
+    method public java.util.concurrent.Executor getExecutor();
+    method public androidx.camera.core.SurfaceProcessor? getSurfaceProcessor();
+    method public int getTargets();
+    field public static final int IMAGE_CAPTURE = 4; // 0x4
+    field public static final int PREVIEW = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 2; // 0x2
+  }
+
+  @RequiresApi(21) public interface CameraFilter {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+  }
+
+  @RequiresApi(21) public interface CameraInfo {
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.CameraState!> getCameraState();
+    method public androidx.camera.core.ExposureState getExposureState();
+    method @FloatRange(from=0, fromInclusive=false) public default float getIntrinsicZoomRatio();
+    method public default int getLensFacing();
+    method public int getSensorRotationDegrees();
+    method public int getSensorRotationDegrees(int);
+    method public default java.util.Set<android.util.Range<java.lang.Integer!>!> getSupportedFrameRateRanges();
+    method public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method public boolean hasFlashUnit();
+    method public default boolean isFocusMeteringSupported(androidx.camera.core.FocusMeteringAction);
+    method @androidx.camera.core.ExperimentalZeroShutterLag public default boolean isZslSupported();
+  }
+
+  @RequiresApi(21) public final class CameraInfoUnavailableException extends java.lang.Exception {
+  }
+
+  @RequiresApi(21) public interface CameraProvider {
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+  }
+
+  @RequiresApi(21) public final class CameraSelector {
+    method public java.util.List<androidx.camera.core.CameraInfo!> filter(java.util.List<androidx.camera.core.CameraInfo!>);
+    field public static final androidx.camera.core.CameraSelector DEFAULT_BACK_CAMERA;
+    field public static final androidx.camera.core.CameraSelector DEFAULT_FRONT_CAMERA;
+    field public static final int LENS_FACING_BACK = 1; // 0x1
+    field @androidx.camera.core.ExperimentalLensFacing public static final int LENS_FACING_EXTERNAL = 2; // 0x2
+    field public static final int LENS_FACING_FRONT = 0; // 0x0
+    field public static final int LENS_FACING_UNKNOWN = -1; // 0xffffffff
+  }
+
+  public static final class CameraSelector.Builder {
+    ctor public CameraSelector.Builder();
+    method public androidx.camera.core.CameraSelector.Builder addCameraFilter(androidx.camera.core.CameraFilter);
+    method public androidx.camera.core.CameraSelector build();
+    method public androidx.camera.core.CameraSelector.Builder requireLensFacing(int);
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class CameraState {
+    ctor public CameraState();
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type);
+    method public static androidx.camera.core.CameraState create(androidx.camera.core.CameraState.Type, androidx.camera.core.CameraState.StateError?);
+    method public abstract androidx.camera.core.CameraState.StateError? getError();
+    method public abstract androidx.camera.core.CameraState.Type getType();
+    field public static final int ERROR_CAMERA_DISABLED = 5; // 0x5
+    field public static final int ERROR_CAMERA_FATAL_ERROR = 6; // 0x6
+    field public static final int ERROR_CAMERA_IN_USE = 2; // 0x2
+    field public static final int ERROR_DO_NOT_DISTURB_MODE_ENABLED = 7; // 0x7
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 1; // 0x1
+    field public static final int ERROR_OTHER_RECOVERABLE_ERROR = 3; // 0x3
+    field public static final int ERROR_STREAM_CONFIG = 4; // 0x4
+  }
+
+  public enum CameraState.ErrorType {
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType CRITICAL;
+    enum_constant public static final androidx.camera.core.CameraState.ErrorType RECOVERABLE;
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class CameraState.StateError {
+    ctor public CameraState.StateError();
+    method public static androidx.camera.core.CameraState.StateError create(int);
+    method public static androidx.camera.core.CameraState.StateError create(int, Throwable?);
+    method public abstract Throwable? getCause();
+    method public abstract int getCode();
+    method public androidx.camera.core.CameraState.ErrorType getType();
+  }
+
+  public enum CameraState.Type {
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSED;
+    enum_constant public static final androidx.camera.core.CameraState.Type CLOSING;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPEN;
+    enum_constant public static final androidx.camera.core.CameraState.Type OPENING;
+    enum_constant public static final androidx.camera.core.CameraState.Type PENDING_OPEN;
+  }
+
+  @RequiresApi(21) public class CameraUnavailableException extends java.lang.Exception {
+    ctor public CameraUnavailableException(int);
+    ctor public CameraUnavailableException(int, String?);
+    ctor public CameraUnavailableException(int, String?, Throwable?);
+    ctor public CameraUnavailableException(int, Throwable?);
+    method public int getReason();
+    field public static final int CAMERA_DISABLED = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+    field public static final int CAMERA_IN_USE = 4; // 0x4
+    field public static final int CAMERA_MAX_IN_USE = 5; // 0x5
+    field public static final int CAMERA_UNAVAILABLE_DO_NOT_DISTURB = 6; // 0x6
+    field public static final int CAMERA_UNKNOWN_ERROR = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class CameraXConfig {
+    method public androidx.camera.core.CameraSelector? getAvailableCamerasLimiter(androidx.camera.core.CameraSelector?);
+    method public java.util.concurrent.Executor? getCameraExecutor(java.util.concurrent.Executor?);
+    method public int getMinimumLoggingLevel();
+    method public android.os.Handler? getSchedulerHandler(android.os.Handler?);
+  }
+
+  public static final class CameraXConfig.Builder {
+    method public androidx.camera.core.CameraXConfig build();
+    method public static androidx.camera.core.CameraXConfig.Builder fromConfig(androidx.camera.core.CameraXConfig);
+    method public androidx.camera.core.CameraXConfig.Builder setAvailableCamerasLimiter(androidx.camera.core.CameraSelector);
+    method public androidx.camera.core.CameraXConfig.Builder setCameraExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.CameraXConfig.Builder setMinimumLoggingLevel(@IntRange(from=android.util.Log.DEBUG, to=android.util.Log.ERROR) int);
+    method public androidx.camera.core.CameraXConfig.Builder setSchedulerHandler(android.os.Handler);
+  }
+
+  public static interface CameraXConfig.Provider {
+    method public androidx.camera.core.CameraXConfig getCameraXConfig();
+  }
+
+  @RequiresApi(21) public class ConcurrentCamera {
+    ctor public ConcurrentCamera(java.util.List<androidx.camera.core.Camera!>);
+    method public java.util.List<androidx.camera.core.Camera!> getCameras();
+  }
+
+  public static final class ConcurrentCamera.SingleCameraConfig {
+    ctor public ConcurrentCamera.SingleCameraConfig(androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup, androidx.lifecycle.LifecycleOwner);
+    method public androidx.camera.core.CameraSelector getCameraSelector();
+    method public androidx.lifecycle.LifecycleOwner getLifecycleOwner();
+    method public androidx.camera.core.UseCaseGroup getUseCaseGroup();
+  }
+
+  @RequiresApi(21) public final class DisplayOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public DisplayOrientedMeteringPointFactory(android.view.Display, androidx.camera.core.CameraInfo, float, float);
+  }
+
+  @RequiresApi(21) public final class DynamicRange {
+    ctor public DynamicRange(int, int);
+    method public int getBitDepth();
+    method public int getEncoding();
+    field public static final int BIT_DEPTH_10_BIT = 10; // 0xa
+    field public static final int BIT_DEPTH_8_BIT = 8; // 0x8
+    field public static final int BIT_DEPTH_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_10_BIT;
+    field public static final androidx.camera.core.DynamicRange DOLBY_VISION_8_BIT;
+    field public static final int ENCODING_DOLBY_VISION = 6; // 0x6
+    field public static final int ENCODING_HDR10 = 4; // 0x4
+    field public static final int ENCODING_HDR10_PLUS = 5; // 0x5
+    field public static final int ENCODING_HDR_UNSPECIFIED = 2; // 0x2
+    field public static final int ENCODING_HLG = 3; // 0x3
+    field public static final int ENCODING_SDR = 1; // 0x1
+    field public static final int ENCODING_UNSPECIFIED = 0; // 0x0
+    field public static final androidx.camera.core.DynamicRange HDR10_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR10_PLUS_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HDR_UNSPECIFIED_10_BIT;
+    field public static final androidx.camera.core.DynamicRange HLG_10_BIT;
+    field public static final androidx.camera.core.DynamicRange SDR;
+    field public static final androidx.camera.core.DynamicRange UNSPECIFIED;
+  }
+
+  @RequiresApi(21) @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalGetImage {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalLensFacing {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalUseCaseApi {
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalZeroShutterLag {
+  }
+
+  @RequiresApi(21) public interface ExposureState {
+    method public int getExposureCompensationIndex();
+    method public android.util.Range<java.lang.Integer!> getExposureCompensationRange();
+    method public android.util.Rational getExposureCompensationStep();
+    method public boolean isExposureCompensationSupported();
+  }
+
+  @RequiresApi(21) public interface ExtendableBuilder<T> {
+    method public T build();
+  }
+
+  @RequiresApi(21) public final class FocusMeteringAction {
+    method public long getAutoCancelDurationInMillis();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAe();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAf();
+    method public java.util.List<androidx.camera.core.MeteringPoint!> getMeteringPointsAwb();
+    method public boolean isAutoCancelEnabled();
+    field public static final int FLAG_AE = 2; // 0x2
+    field public static final int FLAG_AF = 1; // 0x1
+    field public static final int FLAG_AWB = 4; // 0x4
+  }
+
+  public static class FocusMeteringAction.Builder {
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint);
+    ctor public FocusMeteringAction.Builder(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint);
+    method public androidx.camera.core.FocusMeteringAction.Builder addPoint(androidx.camera.core.MeteringPoint, int);
+    method public androidx.camera.core.FocusMeteringAction build();
+    method public androidx.camera.core.FocusMeteringAction.Builder disableAutoCancel();
+    method public androidx.camera.core.FocusMeteringAction.Builder setAutoCancelDuration(@IntRange(from=1) long, java.util.concurrent.TimeUnit);
+  }
+
+  @RequiresApi(21) public final class FocusMeteringResult {
+    method public boolean isFocusSuccessful();
+  }
+
+  @RequiresApi(21) public final class ImageAnalysis extends androidx.camera.core.UseCase {
+    method public void clearAnalyzer();
+    method @androidx.camera.core.ExperimentalUseCaseApi public java.util.concurrent.Executor? getBackgroundExecutor();
+    method public int getBackpressureStrategy();
+    method public int getImageQueueDepth();
+    method public int getOutputImageFormat();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public boolean isOutputImageRotationEnabled();
+    method public void setAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method public void setTargetRotation(int);
+    field public static final int COORDINATE_SYSTEM_ORIGINAL = 0; // 0x0
+    field public static final int OUTPUT_IMAGE_FORMAT_RGBA_8888 = 2; // 0x2
+    field public static final int OUTPUT_IMAGE_FORMAT_YUV_420_888 = 1; // 0x1
+    field public static final int STRATEGY_BLOCK_PRODUCER = 1; // 0x1
+    field public static final int STRATEGY_KEEP_ONLY_LATEST = 0; // 0x0
+  }
+
+  public static interface ImageAnalysis.Analyzer {
+    method public void analyze(androidx.camera.core.ImageProxy);
+    method public default android.util.Size? getDefaultTargetResolution();
+    method public default int getTargetCoordinateSystem();
+    method public default void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class ImageAnalysis.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageAnalysis> {
+    ctor public ImageAnalysis.Builder();
+    method public androidx.camera.core.ImageAnalysis build();
+    method public androidx.camera.core.ImageAnalysis.Builder setBackgroundExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageAnalysis.Builder setBackpressureStrategy(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setImageQueueDepth(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setOutputImageFormat(int);
+    method @RequiresApi(23) public androidx.camera.core.ImageAnalysis.Builder setOutputImageRotationEnabled(boolean);
+    method public androidx.camera.core.ImageAnalysis.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageAnalysis.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageAnalysis.Builder setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public final class ImageCapture extends androidx.camera.core.UseCase {
+    method public int getCaptureMode();
+    method public int getFlashMode();
+    method @IntRange(from=1, to=100) public int getJpegQuality();
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public int getTargetRotation();
+    method public void setCropAspectRatio(android.util.Rational);
+    method public void setFlashMode(int);
+    method public void setTargetRotation(int);
+    method public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int CAPTURE_MODE_MAXIMIZE_QUALITY = 0; // 0x0
+    field public static final int CAPTURE_MODE_MINIMIZE_LATENCY = 1; // 0x1
+    field @androidx.camera.core.ExperimentalZeroShutterLag public static final int CAPTURE_MODE_ZERO_SHUTTER_LAG = 2; // 0x2
+    field public static final int ERROR_CAMERA_CLOSED = 3; // 0x3
+    field public static final int ERROR_CAPTURE_FAILED = 2; // 0x2
+    field public static final int ERROR_FILE_IO = 1; // 0x1
+    field public static final int ERROR_INVALID_CAMERA = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 0; // 0x0
+    field public static final int FLASH_MODE_AUTO = 0; // 0x0
+    field public static final int FLASH_MODE_OFF = 2; // 0x2
+    field public static final int FLASH_MODE_ON = 1; // 0x1
+  }
+
+  public static final class ImageCapture.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.ImageCapture> {
+    ctor public ImageCapture.Builder();
+    method public androidx.camera.core.ImageCapture build();
+    method public androidx.camera.core.ImageCapture.Builder setCaptureMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setFlashMode(int);
+    method public androidx.camera.core.ImageCapture.Builder setIoExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.core.ImageCapture.Builder setJpegQuality(@IntRange(from=1, to=100) int);
+    method public androidx.camera.core.ImageCapture.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.ImageCapture.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.ImageCapture.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.ImageCapture.Builder setTargetRotation(int);
+  }
+
+  public static final class ImageCapture.Metadata {
+    ctor public ImageCapture.Metadata();
+    method public android.location.Location? getLocation();
+    method public boolean isReversedHorizontal();
+    method public boolean isReversedVertical();
+    method public void setLocation(android.location.Location?);
+    method public void setReversedHorizontal(boolean);
+    method public void setReversedVertical(boolean);
+  }
+
+  public abstract static class ImageCapture.OnImageCapturedCallback {
+    ctor public ImageCapture.OnImageCapturedCallback();
+    method public void onCaptureSuccess(androidx.camera.core.ImageProxy);
+    method public void onError(androidx.camera.core.ImageCaptureException);
+  }
+
+  public static interface ImageCapture.OnImageSavedCallback {
+    method public void onError(androidx.camera.core.ImageCaptureException);
+    method public void onImageSaved(androidx.camera.core.ImageCapture.OutputFileResults);
+  }
+
+  public static final class ImageCapture.OutputFileOptions {
+  }
+
+  public static final class ImageCapture.OutputFileOptions.Builder {
+    ctor public ImageCapture.OutputFileOptions.Builder(android.content.ContentResolver, android.net.Uri, android.content.ContentValues);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.File);
+    ctor public ImageCapture.OutputFileOptions.Builder(java.io.OutputStream);
+    method public androidx.camera.core.ImageCapture.OutputFileOptions build();
+    method public androidx.camera.core.ImageCapture.OutputFileOptions.Builder setMetadata(androidx.camera.core.ImageCapture.Metadata);
+  }
+
+  public static class ImageCapture.OutputFileResults {
+    method public android.net.Uri? getSavedUri();
+  }
+
+  @RequiresApi(21) public class ImageCaptureException extends java.lang.Exception {
+    ctor public ImageCaptureException(int, String, Throwable?);
+    method public int getImageCaptureError();
+  }
+
+  @RequiresApi(21) public interface ImageInfo {
+    method public int getRotationDegrees();
+    method public default android.graphics.Matrix getSensorToBufferTransformMatrix();
+    method public long getTimestamp();
+  }
+
+  public interface ImageProcessor {
+    method public androidx.camera.core.ImageProcessor.Response process(androidx.camera.core.ImageProcessor.Request) throws androidx.camera.core.ProcessingException;
+  }
+
+  public static interface ImageProcessor.Request {
+    method public androidx.camera.core.ImageProxy getInputImage();
+    method public int getOutputFormat();
+  }
+
+  public static interface ImageProcessor.Response {
+    method public androidx.camera.core.ImageProxy getOutputImage();
+  }
+
+  @RequiresApi(21) public interface ImageProxy extends java.lang.AutoCloseable {
+    method public void close();
+    method public android.graphics.Rect getCropRect();
+    method public int getFormat();
+    method public int getHeight();
+    method @androidx.camera.core.ExperimentalGetImage public android.media.Image? getImage();
+    method public androidx.camera.core.ImageInfo getImageInfo();
+    method public androidx.camera.core.ImageProxy.PlaneProxy![] getPlanes();
+    method public int getWidth();
+    method public void setCropRect(android.graphics.Rect?);
+    method public default android.graphics.Bitmap toBitmap();
+  }
+
+  public static interface ImageProxy.PlaneProxy {
+    method public java.nio.ByteBuffer getBuffer();
+    method public int getPixelStride();
+    method public int getRowStride();
+  }
+
+  @RequiresApi(21) public class InitializationException extends java.lang.Exception {
+    ctor public InitializationException(String?);
+    ctor public InitializationException(String?, Throwable?);
+    ctor public InitializationException(Throwable?);
+  }
+
+  @RequiresApi(21) public class MeteringPoint {
+    method public float getSize();
+  }
+
+  @RequiresApi(21) public abstract class MeteringPointFactory {
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float);
+    method public final androidx.camera.core.MeteringPoint createPoint(float, float, float);
+    method public static float getDefaultPointSize();
+  }
+
+  @RequiresApi(21) public class MirrorMode {
+    field public static final int MIRROR_MODE_OFF = 0; // 0x0
+    field public static final int MIRROR_MODE_ON = 1; // 0x1
+    field public static final int MIRROR_MODE_ON_FRONT_ONLY = 2; // 0x2
+  }
+
+  @RequiresApi(21) public final class Preview extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.ResolutionInfo? getResolutionInfo();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector? getResolutionSelector();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method @UiThread public void setSurfaceProvider(androidx.camera.core.Preview.SurfaceProvider?);
+    method @UiThread public void setSurfaceProvider(java.util.concurrent.Executor, androidx.camera.core.Preview.SurfaceProvider?);
+    method public void setTargetRotation(int);
+  }
+
+  public static final class Preview.Builder implements androidx.camera.core.ExtendableBuilder<androidx.camera.core.Preview> {
+    ctor public Preview.Builder();
+    method public androidx.camera.core.Preview build();
+    method public androidx.camera.core.Preview.Builder setResolutionSelector(androidx.camera.core.resolutionselector.ResolutionSelector);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetAspectRatio(int);
+    method public androidx.camera.core.Preview.Builder setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.core.Preview.Builder setTargetName(String);
+    method @Deprecated public androidx.camera.core.Preview.Builder setTargetResolution(android.util.Size);
+    method public androidx.camera.core.Preview.Builder setTargetRotation(int);
+  }
+
+  public static interface Preview.SurfaceProvider {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  public class ProcessingException extends java.lang.Exception {
+    ctor public ProcessingException();
+  }
+
+  @RequiresApi(21) public class ResolutionInfo {
+    ctor public ResolutionInfo(android.util.Size, android.graphics.Rect, int);
+    method public android.graphics.Rect getCropRect();
+    method public android.util.Size getResolution();
+    method public int getRotationDegrees();
+  }
+
+  @RequiresApi(21) public class SurfaceOrientedMeteringPointFactory extends androidx.camera.core.MeteringPointFactory {
+    ctor public SurfaceOrientedMeteringPointFactory(float, float);
+    ctor public SurfaceOrientedMeteringPointFactory(float, float, androidx.camera.core.UseCase);
+  }
+
+  public interface SurfaceOutput extends java.io.Closeable {
+    method public void close();
+    method public android.util.Size getSize();
+    method public android.view.Surface getSurface(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceOutput.Event!>);
+    method public int getTargets();
+    method public void updateTransformMatrix(float[], float[]);
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceOutput.Event {
+    method public abstract int getEventCode();
+    method public abstract androidx.camera.core.SurfaceOutput getSurfaceOutput();
+    field public static final int EVENT_REQUEST_CLOSE = 0; // 0x0
+  }
+
+  public interface SurfaceProcessor {
+    method public void onInputSurface(androidx.camera.core.SurfaceRequest) throws androidx.camera.core.ProcessingException;
+    method public void onOutputSurface(androidx.camera.core.SurfaceOutput) throws androidx.camera.core.ProcessingException;
+  }
+
+  @RequiresApi(21) public final class SurfaceRequest {
+    method public void addRequestCancellationListener(java.util.concurrent.Executor, Runnable);
+    method public void clearTransformationInfoListener();
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public android.util.Size getResolution();
+    method public boolean invalidate();
+    method public void provideSurface(android.view.Surface, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.core.SurfaceRequest.Result!>);
+    method public void setTransformationInfoListener(java.util.concurrent.Executor, androidx.camera.core.SurfaceRequest.TransformationInfoListener);
+    method public boolean willNotProvideSurface();
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.Result {
+    method public abstract int getResultCode();
+    method public abstract android.view.Surface getSurface();
+    field public static final int RESULT_INVALID_SURFACE = 2; // 0x2
+    field public static final int RESULT_REQUEST_CANCELLED = 1; // 0x1
+    field public static final int RESULT_SURFACE_ALREADY_PROVIDED = 3; // 0x3
+    field public static final int RESULT_SURFACE_USED_SUCCESSFULLY = 0; // 0x0
+    field public static final int RESULT_WILL_NOT_PROVIDE_SURFACE = 4; // 0x4
+  }
+
+  @com.google.auto.value.AutoValue public abstract static class SurfaceRequest.TransformationInfo {
+    method public abstract android.graphics.Rect getCropRect();
+    method public abstract int getRotationDegrees();
+  }
+
+  public static interface SurfaceRequest.TransformationInfoListener {
+    method public void onTransformationInfoUpdate(androidx.camera.core.SurfaceRequest.TransformationInfo);
+  }
+
+  @RequiresApi(21) public class TorchState {
+    field public static final int OFF = 0; // 0x0
+    field public static final int ON = 1; // 0x1
+  }
+
+  @RequiresApi(21) public abstract class UseCase {
+    method public static int snapToSurfaceRotation(@IntRange(from=0, to=359) int);
+  }
+
+  @RequiresApi(21) public final class UseCaseGroup {
+    method public java.util.List<androidx.camera.core.CameraEffect!> getEffects();
+    method public java.util.List<androidx.camera.core.UseCase!> getUseCases();
+    method public androidx.camera.core.ViewPort? getViewPort();
+  }
+
+  public static final class UseCaseGroup.Builder {
+    ctor public UseCaseGroup.Builder();
+    method public androidx.camera.core.UseCaseGroup.Builder addEffect(androidx.camera.core.CameraEffect);
+    method public androidx.camera.core.UseCaseGroup.Builder addUseCase(androidx.camera.core.UseCase);
+    method public androidx.camera.core.UseCaseGroup build();
+    method public androidx.camera.core.UseCaseGroup.Builder setViewPort(androidx.camera.core.ViewPort);
+  }
+
+  @RequiresApi(21) public final class ViewPort {
+    method public android.util.Rational getAspectRatio();
+    method public int getLayoutDirection();
+    method public int getRotation();
+    method public int getScaleType();
+    field public static final int FILL_CENTER = 1; // 0x1
+    field public static final int FILL_END = 2; // 0x2
+    field public static final int FILL_START = 0; // 0x0
+    field public static final int FIT = 3; // 0x3
+  }
+
+  public static final class ViewPort.Builder {
+    ctor public ViewPort.Builder(android.util.Rational, int);
+    method public androidx.camera.core.ViewPort build();
+    method public androidx.camera.core.ViewPort.Builder setLayoutDirection(int);
+    method public androidx.camera.core.ViewPort.Builder setScaleType(int);
+  }
+
+  @RequiresApi(21) public interface ZoomState {
+    method public float getLinearZoom();
+    method public float getMaxZoomRatio();
+    method public float getMinZoomRatio();
+    method public float getZoomRatio();
+  }
+
+}
+
+package androidx.camera.core.resolutionselector {
+
+  @RequiresApi(21) public final class AspectRatioStrategy {
+    ctor public AspectRatioStrategy(int, int);
+    method public int getFallbackRule();
+    method public int getPreferredAspectRatio();
+    field public static final int FALLBACK_RULE_AUTO = 1; // 0x1
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_16_9_FALLBACK_AUTO_STRATEGY;
+    field public static final androidx.camera.core.resolutionselector.AspectRatioStrategy RATIO_4_3_FALLBACK_AUTO_STRATEGY;
+  }
+
+  @RequiresApi(21) public interface ResolutionFilter {
+    method public java.util.List<android.util.Size!> filter(java.util.List<android.util.Size!>, int);
+  }
+
+  @RequiresApi(21) public final class ResolutionSelector {
+    method public int getAllowedResolutionMode();
+    method public androidx.camera.core.resolutionselector.AspectRatioStrategy getAspectRatioStrategy();
+    method public androidx.camera.core.resolutionselector.ResolutionFilter? getResolutionFilter();
+    method public androidx.camera.core.resolutionselector.ResolutionStrategy? getResolutionStrategy();
+    field public static final int PREFER_CAPTURE_RATE_OVER_HIGHER_RESOLUTION = 0; // 0x0
+    field public static final int PREFER_HIGHER_RESOLUTION_OVER_CAPTURE_RATE = 1; // 0x1
+  }
+
+  public static final class ResolutionSelector.Builder {
+    ctor public ResolutionSelector.Builder();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector build();
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAllowedResolutionMode(int);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setAspectRatioStrategy(androidx.camera.core.resolutionselector.AspectRatioStrategy);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionFilter(androidx.camera.core.resolutionselector.ResolutionFilter);
+    method public androidx.camera.core.resolutionselector.ResolutionSelector.Builder setResolutionStrategy(androidx.camera.core.resolutionselector.ResolutionStrategy);
+  }
+
+  @RequiresApi(21) public final class ResolutionStrategy {
+    ctor public ResolutionStrategy(android.util.Size, int);
+    method public android.util.Size? getBoundSize();
+    method public int getFallbackRule();
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER = 2; // 0x2
+    field public static final int FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER = 1; // 0x1
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER = 4; // 0x4
+    field public static final int FALLBACK_RULE_CLOSEST_LOWER_THEN_HIGHER = 3; // 0x3
+    field public static final int FALLBACK_RULE_NONE = 0; // 0x0
+    field public static final androidx.camera.core.resolutionselector.ResolutionStrategy HIGHEST_AVAILABLE_STRATEGY;
+  }
+
+}
+
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
index b1020d6..6321d77 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/processing/DefaultSurfaceProcessorTest.kt
@@ -16,8 +16,10 @@
 
 package androidx.camera.core.processing
 
+import android.graphics.Bitmap.createBitmap
 import android.graphics.BitmapFactory
 import android.graphics.ImageFormat
+import android.graphics.Matrix
 import android.graphics.Rect
 import android.graphics.SurfaceTexture
 import android.hardware.camera2.CameraDevice.TEMPLATE_PREVIEW
@@ -427,7 +429,8 @@
             Rect(0, 0, WIDTH, HEIGHT),
             /*rotationDegrees=*/0,
             /*mirroring=*/false,
-            FakeCamera()
+            FakeCamera(),
+            Matrix()
         )
 
     private fun createCustomShaderProvider(
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
index 0cde5ad..a41d1a7 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/SurfaceOutput.java
@@ -18,7 +18,9 @@
 
 import static androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE;
 
+import android.graphics.Matrix;
 import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraCharacteristics;
 import android.util.Size;
 import android.view.Surface;
 
@@ -150,6 +152,33 @@
     void updateTransformMatrix(@NonNull float[] updated, @NonNull float[] original);
 
     /**
+     * Returns the sensor to image buffer transform matrix.
+     *
+     * <p>The value is a mapping from sensor coordinates to buffer coordinates, which is,
+     * from the rect of {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE} to the
+     * rect defined by {@code (0, 0, SurfaceRequest#getResolution#getWidth(),
+     * SurfaceRequest#getResolution#getHeight())}. The matrix can
+     * be used to map the coordinates from one {@link UseCase} to another. For example,
+     * detecting face with {@link ImageAnalysis}, and then highlighting the face in
+     * {@link Preview}.
+     *
+     * <p>Code sample
+     * <code><pre>
+     *  // Get the transformation from sensor to effect output.
+     *  Matrix sensorToEffect = surfaceOutput.getSensorToBufferTransform();
+     *  // Get the transformation from sensor to ImageAnalysis.
+     *  Matrix sensorToAnalysis = imageProxy.getSensorToBufferTransform();
+     *  // Concatenate the two matrices to get the transformation from ImageAnalysis to effect.
+     *  Matrix analysisToEffect = Matrix()
+     *  sensorToAnalysis.invert(analysisToEffect);
+     *  analysisToEffect.postConcat(sensorToEffect);
+     * </pre></code>
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @NonNull
+    Matrix getSensorToBufferTransform();
+
+    /**
      * Events of the {@link Surface} retrieved from
      * {@link SurfaceOutput#getSurface(Executor, Consumer)}.
      */
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/TransformUtils.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/TransformUtils.java
index 4454f71..2e41dc8 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/TransformUtils.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/utils/TransformUtils.java
@@ -141,6 +141,22 @@
     }
 
     /**
+     * Rotates {@link SizeF} according to the rotation degrees.
+     *
+     * <p> A 640, 480 rect rotated 90 degrees clockwise will become a 480, 640 rect.
+     */
+    @NonNull
+    public static RectF rotateRect(@NonNull RectF rect, int rotationDegrees) {
+        Preconditions.checkArgument(rotationDegrees % 90 == 0,
+                "Invalid rotation degrees: " + rotationDegrees);
+        if (is90or270(within360(rotationDegrees))) {
+            return new RectF(0, 0, /*right=*/rect.height(),  /*bottom=*/rect.width());
+        } else {
+            return rect;
+        }
+    }
+
+    /**
      * Gets the size after cropping and rotating.
      *
      * @return rotated size
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceEdge.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceEdge.java
index a7c936a..d237eda 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceEdge.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceEdge.java
@@ -320,7 +320,7 @@
                     }
                     SurfaceOutputImpl surfaceOutputImpl = new SurfaceOutputImpl(surface,
                             getTargets(), format, mStreamSpec.getResolution(), inputSize, cropRect,
-                            rotationDegrees, mirroring, cameraInternal);
+                            rotationDegrees, mirroring, cameraInternal, mSensorToBufferTransform);
                     surfaceOutputImpl.getCloseFuture().addListener(
                             settableSurface::decrementUseCount,
                             directExecutor());
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceOutputImpl.java b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceOutputImpl.java
index 8038235..aae6698 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceOutputImpl.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/processing/SurfaceOutputImpl.java
@@ -95,6 +95,8 @@
     private CallbackToFutureAdapter.Completer<Void> mCloseFutureCompleter;
     @Nullable
     private CameraInternal mCameraInternal;
+    @NonNull
+    private android.graphics.Matrix mSensorToBufferTransform;
 
     SurfaceOutputImpl(
             @NonNull Surface surface,
@@ -105,7 +107,8 @@
             @NonNull Rect inputCropRect,
             int rotationDegree,
             boolean mirroring,
-            @Nullable CameraInternal cameraInternal) {
+            @Nullable CameraInternal cameraInternal,
+            @NonNull android.graphics.Matrix sensorToBufferTransform) {
         mSurface = surface;
         mTargets = targets;
         mFormat = format;
@@ -115,6 +118,7 @@
         mMirroring = mirroring;
         mRotationDegrees = rotationDegree;
         mCameraInternal = cameraInternal;
+        mSensorToBufferTransform = sensorToBufferTransform;
         calculateAdditionalTransform();
         mCloseFuture = CallbackToFutureAdapter.getFuture(
                 completer -> {
@@ -264,6 +268,15 @@
     }
 
     /**
+     * @inheritDoc
+     */
+    @NonNull
+    @Override
+    public android.graphics.Matrix getSensorToBufferTransform() {
+        return new android.graphics.Matrix(mSensorToBufferTransform);
+    }
+
+    /**
      * Calculates the additional GL transform and saves it to {@link #mAdditionalTransform}.
      *
      * <p>The effect implementation needs to apply this value on top of texture transform obtained
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceEdgeTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceEdgeTest.kt
index eeda779..ad6dbd7 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceEdgeTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceEdgeTest.kt
@@ -293,25 +293,26 @@
 
     @Test
     fun createSurfaceOutputWithDisconnectedEdge_surfaceOutputNotCreated() {
-        // Arrange: create a SurfaceOutput future from a closed LinkableSurface
+        // Arrange: create a SurfaceOutput future from a closed Edge
+        surfaceEdge.setProvider(provider)
+        provider.setSurface(fakeSurface)
         surfaceEdge.disconnect()
-        val surfaceOutput = createSurfaceOutputFuture(surfaceEdge)
-
         // Act: wait for the SurfaceOutput to return.
-        var successful: Boolean? = null
-        Futures.addCallback(surfaceOutput, object : FutureCallback<SurfaceOutput> {
-            override fun onSuccess(result: SurfaceOutput?) {
-                successful = true
-            }
-
-            override fun onFailure(t: Throwable) {
-                successful = false
-            }
-        }, mainThreadExecutor())
-        shadowOf(getMainLooper()).idle()
+        val surfaceOutput = getSurfaceOutputFromFuture(createSurfaceOutputFuture(surfaceEdge))
 
         // Assert: the SurfaceOutput is not created.
-        assertThat(successful!!).isEqualTo(false)
+        assertThat(surfaceOutput).isNull()
+    }
+
+    @Test
+    fun createSurfaceOutput_inheritSurfaceEdgeTransformation() {
+        // Arrange: set the provider and create a SurfaceOutput future.
+        surfaceEdge.setProvider(provider)
+        provider.setSurface(fakeSurface)
+        // Act: create a SurfaceOutput from the SurfaceEdge
+        val surfaceOutput = getSurfaceOutputFromFuture(createSurfaceOutputFuture(surfaceEdge))
+        // Assert: the SurfaceOutput inherits the transformation from the SurfaceEdge.
+        assertThat(surfaceOutput!!.sensorToBufferTransform).isEqualTo(SENSOR_TO_BUFFER)
     }
 
     @Test
@@ -542,6 +543,22 @@
         assertThat(transformationInfo!!.rotationDegrees).isEqualTo(90)
     }
 
+    private fun getSurfaceOutputFromFuture(
+        future: ListenableFuture<SurfaceOutput>
+    ): SurfaceOutput? {
+        var surfaceOutput: SurfaceOutput? = null
+        Futures.addCallback(future, object : FutureCallback<SurfaceOutput> {
+            override fun onSuccess(result: SurfaceOutput?) {
+                surfaceOutput = result
+            }
+
+            override fun onFailure(t: Throwable) {
+            }
+        }, mainThreadExecutor())
+        shadowOf(getMainLooper()).idle()
+        return surfaceOutput
+    }
+
     private fun createSurfaceOutputFuture(surfaceEdge: SurfaceEdge) =
         surfaceEdge.createSurfaceOutputFuture(
             INPUT_SIZE,
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
index 21dd66c..2603f35 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
@@ -186,7 +186,8 @@
         sizeToRect(INPUT_SIZE),
         /*rotationDegrees=*/180,
         /*mirroring=*/false,
-        camera
+        camera,
+        android.graphics.Matrix()
     ).apply {
         surfaceOutputsToCleanup.add(this)
     }
diff --git a/camera/camera-core/src/test/resources/robolectric.properties b/camera/camera-core/src/test/resources/robolectric.properties
index 7946f01..69fde47 100644
--- a/camera/camera-core/src/test/resources/robolectric.properties
+++ b/camera/camera-core/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/camera/camera-effects-still-portrait/api/1.3.0-beta01.txt b/camera/camera-effects-still-portrait/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects-still-portrait/api/1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-effects-still-portrait/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-effects-still-portrait/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-effects-still-portrait/api/restricted_1.3.0-beta01.txt b/camera/camera-effects-still-portrait/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects-still-portrait/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-effects/api/1.3.0-beta01.txt b/camera/camera-effects/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects/api/1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-effects/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-effects/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-effects/api/restricted_1.3.0-beta01.txt b/camera/camera-effects/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-effects/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-extensions/api/1.3.0-beta01.txt b/camera/camera-extensions/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..5c6e740
--- /dev/null
+++ b/camera/camera-extensions/api/1.3.0-beta01.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.camera.extensions {
+
+  @RequiresApi(21) public final class ExtensionMode {
+    field public static final int AUTO = 5; // 0x5
+    field public static final int BOKEH = 1; // 0x1
+    field public static final int FACE_RETOUCH = 4; // 0x4
+    field public static final int HDR = 2; // 0x2
+    field public static final int NIGHT = 3; // 0x3
+    field public static final int NONE = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class ExtensionsManager {
+    method public android.util.Range<java.lang.Long!>? getEstimatedCaptureLatencyRange(androidx.camera.core.CameraSelector, int);
+    method public androidx.camera.core.CameraSelector getExtensionEnabledCameraSelector(androidx.camera.core.CameraSelector, int);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.extensions.ExtensionsManager!> getInstanceAsync(android.content.Context, androidx.camera.core.CameraProvider);
+    method public boolean isExtensionAvailable(androidx.camera.core.CameraSelector, int);
+    method public boolean isImageAnalysisSupported(androidx.camera.core.CameraSelector, int);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-extensions/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-extensions/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-extensions/api/restricted_1.3.0-beta01.txt b/camera/camera-extensions/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..5c6e740
--- /dev/null
+++ b/camera/camera-extensions/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.camera.extensions {
+
+  @RequiresApi(21) public final class ExtensionMode {
+    field public static final int AUTO = 5; // 0x5
+    field public static final int BOKEH = 1; // 0x1
+    field public static final int FACE_RETOUCH = 4; // 0x4
+    field public static final int HDR = 2; // 0x2
+    field public static final int NIGHT = 3; // 0x3
+    field public static final int NONE = 0; // 0x0
+  }
+
+  @RequiresApi(21) public final class ExtensionsManager {
+    method public android.util.Range<java.lang.Long!>? getEstimatedCaptureLatencyRange(androidx.camera.core.CameraSelector, int);
+    method public androidx.camera.core.CameraSelector getExtensionEnabledCameraSelector(androidx.camera.core.CameraSelector, int);
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.extensions.ExtensionsManager!> getInstanceAsync(android.content.Context, androidx.camera.core.CameraProvider);
+    method public boolean isExtensionAvailable(androidx.camera.core.CameraSelector, int);
+    method public boolean isImageAnalysisSupported(androidx.camera.core.CameraSelector, int);
+  }
+
+}
+
diff --git a/camera/camera-lifecycle/api/1.3.0-beta01.txt b/camera/camera-lifecycle/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..606a816
--- /dev/null
+++ b/camera/camera-lifecycle/api/1.3.0-beta01.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.camera.lifecycle {
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCameraProviderConfiguration {
+  }
+
+  @RequiresApi(21) public final class ProcessCameraProvider implements androidx.camera.core.CameraProvider {
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCase!...);
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup);
+    method @MainThread public androidx.camera.core.ConcurrentCamera bindToLifecycle(java.util.List<androidx.camera.core.ConcurrentCamera.SingleCameraConfig!>);
+    method @androidx.camera.lifecycle.ExperimentalCameraProviderConfiguration public static void configureInstance(androidx.camera.core.CameraXConfig);
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public java.util.List<java.util.List<androidx.camera.core.CameraInfo!>!> getAvailableConcurrentCameraInfos();
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.lifecycle.ProcessCameraProvider!> getInstance(android.content.Context);
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+    method public boolean isBound(androidx.camera.core.UseCase);
+    method @MainThread public boolean isConcurrentCameraModeOn();
+    method @MainThread public void unbind(androidx.camera.core.UseCase!...);
+    method @MainThread public void unbindAll();
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-lifecycle/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-lifecycle/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-lifecycle/api/restricted_1.3.0-beta01.txt b/camera/camera-lifecycle/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..606a816
--- /dev/null
+++ b/camera/camera-lifecycle/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.camera.lifecycle {
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface ExperimentalCameraProviderConfiguration {
+  }
+
+  @RequiresApi(21) public final class ProcessCameraProvider implements androidx.camera.core.CameraProvider {
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCase!...);
+    method @MainThread public androidx.camera.core.Camera bindToLifecycle(androidx.lifecycle.LifecycleOwner, androidx.camera.core.CameraSelector, androidx.camera.core.UseCaseGroup);
+    method @MainThread public androidx.camera.core.ConcurrentCamera bindToLifecycle(java.util.List<androidx.camera.core.ConcurrentCamera.SingleCameraConfig!>);
+    method @androidx.camera.lifecycle.ExperimentalCameraProviderConfiguration public static void configureInstance(androidx.camera.core.CameraXConfig);
+    method public java.util.List<androidx.camera.core.CameraInfo!> getAvailableCameraInfos();
+    method public java.util.List<java.util.List<androidx.camera.core.CameraInfo!>!> getAvailableConcurrentCameraInfos();
+    method public static com.google.common.util.concurrent.ListenableFuture<androidx.camera.lifecycle.ProcessCameraProvider!> getInstance(android.content.Context);
+    method public boolean hasCamera(androidx.camera.core.CameraSelector) throws androidx.camera.core.CameraInfoUnavailableException;
+    method public boolean isBound(androidx.camera.core.UseCase);
+    method @MainThread public boolean isConcurrentCameraModeOn();
+    method @MainThread public void unbind(androidx.camera.core.UseCase!...);
+    method @MainThread public void unbindAll();
+  }
+
+}
+
diff --git a/camera/camera-mlkit-vision/api/1.3.0-beta01.txt b/camera/camera-mlkit-vision/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..0599c25
--- /dev/null
+++ b/camera/camera-mlkit-vision/api/1.3.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.camera.mlkit.vision {
+
+  @RequiresApi(21) public class MlKitAnalyzer implements androidx.camera.core.ImageAnalysis.Analyzer {
+    ctor public MlKitAnalyzer(java.util.List<com.google.mlkit.vision.interfaces.Detector<?>!>, int, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.mlkit.vision.MlKitAnalyzer.Result!>);
+    method public final void analyze(androidx.camera.core.ImageProxy);
+    method public final android.util.Size getDefaultTargetResolution();
+    method public final int getTargetCoordinateSystem();
+    method public final void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class MlKitAnalyzer.Result {
+    ctor public MlKitAnalyzer.Result(java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Object!>, long, java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Throwable!>);
+    method public Throwable? getThrowable(com.google.mlkit.vision.interfaces.Detector<?>);
+    method public long getTimestamp();
+    method public <T> T? getValue(com.google.mlkit.vision.interfaces.Detector<T!>);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-mlkit-vision/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-mlkit-vision/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-mlkit-vision/api/restricted_1.3.0-beta01.txt b/camera/camera-mlkit-vision/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..0599c25
--- /dev/null
+++ b/camera/camera-mlkit-vision/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.camera.mlkit.vision {
+
+  @RequiresApi(21) public class MlKitAnalyzer implements androidx.camera.core.ImageAnalysis.Analyzer {
+    ctor public MlKitAnalyzer(java.util.List<com.google.mlkit.vision.interfaces.Detector<?>!>, int, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.mlkit.vision.MlKitAnalyzer.Result!>);
+    method public final void analyze(androidx.camera.core.ImageProxy);
+    method public final android.util.Size getDefaultTargetResolution();
+    method public final int getTargetCoordinateSystem();
+    method public final void updateTransform(android.graphics.Matrix?);
+  }
+
+  public static final class MlKitAnalyzer.Result {
+    ctor public MlKitAnalyzer.Result(java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Object!>, long, java.util.Map<com.google.mlkit.vision.interfaces.Detector<?>!,java.lang.Throwable!>);
+    method public Throwable? getThrowable(com.google.mlkit.vision.interfaces.Detector<?>);
+    method public long getTimestamp();
+    method public <T> T? getValue(com.google.mlkit.vision.interfaces.Detector<T!>);
+  }
+
+}
+
diff --git a/camera/camera-mlkit-vision/src/main/java/androidx/camera/mlkit/vision/MlKitAnalyzer.java b/camera/camera-mlkit-vision/src/main/java/androidx/camera/mlkit/vision/MlKitAnalyzer.java
index 55b0cfd..605c78a 100644
--- a/camera/camera-mlkit-vision/src/main/java/androidx/camera/mlkit/vision/MlKitAnalyzer.java
+++ b/camera/camera-mlkit-vision/src/main/java/androidx/camera/mlkit/vision/MlKitAnalyzer.java
@@ -16,6 +16,8 @@
 package androidx.camera.mlkit.vision;
 
 import static androidx.camera.core.ImageAnalysis.COORDINATE_SYSTEM_ORIGINAL;
+import static androidx.camera.core.impl.utils.TransformUtils.getRectToRect;
+import static androidx.camera.core.impl.utils.TransformUtils.rotateRect;
 
 import static com.google.android.gms.common.internal.Preconditions.checkArgument;
 import static com.google.mlkit.vision.interfaces.Detector.TYPE_BARCODE_SCANNING;
@@ -23,6 +25,7 @@
 import static com.google.mlkit.vision.interfaces.Detector.TYPE_TEXT_RECOGNITION;
 
 import android.graphics.Matrix;
+import android.graphics.RectF;
 import android.media.Image;
 import android.util.Size;
 
@@ -35,9 +38,7 @@
 import androidx.camera.core.ImageProxy;
 import androidx.camera.core.Logger;
 import androidx.camera.view.TransformExperimental;
-import androidx.camera.view.transform.CoordinateTransform;
 import androidx.camera.view.transform.ImageProxyTransformFactory;
-import androidx.camera.view.transform.OutputTransform;
 import androidx.core.util.Consumer;
 
 import com.google.android.gms.tasks.Task;
@@ -61,8 +62,8 @@
  * <p> This class handles the coordinate transformation between ML Kit output and the target
  * coordinate system. Using the {@code targetCoordinateSystem} set in the constructor, it
  * calculates the {@link Matrix} with the value provided by CameraX via
- * {@link ImageAnalysis.Analyzer#updateTransform} and forwards it to the ML Kit {@code Detector}. The
- * coordinates returned by MLKit will be in the specified coordinate system.
+ * {@link ImageAnalysis.Analyzer#updateTransform} and forwards it to the ML Kit {@code Detector}.
+ * The coordinates returned by MLKit will be in the specified coordinate system.
  *
  * <p> This class is designed to work seamlessly with the {@code CameraController} class in
  * camera-view. When used with {@link ImageAnalysis} in camera-core, the following scenarios may
@@ -155,7 +156,7 @@
     @OptIn(markerClass = TransformExperimental.class)
     public final void analyze(@NonNull ImageProxy imageProxy) {
         // By default, the matrix is identity for COORDINATE_SYSTEM_ORIGINAL.
-        Matrix transform = new Matrix();
+        Matrix analysisToTarget = new Matrix();
         if (mTargetCoordinateSystem != COORDINATE_SYSTEM_ORIGINAL) {
             // Calculate the transform if not COORDINATE_SYSTEM_ORIGINAL.
             Matrix sensorToTarget = mSensorToTarget;
@@ -166,16 +167,24 @@
                 imageProxy.close();
                 return;
             }
-            OutputTransform analysisTransform =
-                    mImageAnalysisTransformFactory.getOutputTransform(imageProxy);
-            Size cropRectSize = new Size(imageProxy.getCropRect().width(),
-                    imageProxy.getCropRect().height());
-            CoordinateTransform coordinateTransform = new CoordinateTransform(analysisTransform,
-                    new OutputTransform(sensorToTarget, cropRectSize));
-            coordinateTransform.transform(transform);
+            Matrix sensorToAnalysis =
+                    new Matrix(imageProxy.getImageInfo().getSensorToBufferTransformMatrix());
+            // Calculate the rotation added by ML Kit.
+            RectF sourceRect = new RectF(0, 0, imageProxy.getWidth(),
+                    imageProxy.getHeight());
+            RectF bufferRect = rotateRect(sourceRect,
+                    imageProxy.getImageInfo().getRotationDegrees());
+            Matrix analysisToMlKitRotation = getRectToRect(sourceRect, bufferRect,
+                    imageProxy.getImageInfo().getRotationDegrees());
+            // Concat the MLKit transformation with sensor to Analysis.
+            sensorToAnalysis.postConcat(analysisToMlKitRotation);
+            // Invert to get analysis to sensor.
+            sensorToAnalysis.invert(analysisToTarget);
+            // Concat sensor to target to get analysisToTarget.
+            analysisToTarget.postConcat(sensorToTarget);
         }
         // Detect the image recursively, starting from index 0.
-        detectRecursively(imageProxy, 0, transform, new HashMap<>(), new HashMap<>());
+        detectRecursively(imageProxy, 0, analysisToTarget, new HashMap<>(), new HashMap<>());
     }
 
     /**
diff --git a/camera/camera-mlkit-vision/src/test/java/androidx/camera/mlkit/vision/MlKitAnalyzerTest.kt b/camera/camera-mlkit-vision/src/test/java/androidx/camera/mlkit/vision/MlKitAnalyzerTest.kt
index c4dcc0f..73919a9 100644
--- a/camera/camera-mlkit-vision/src/test/java/androidx/camera/mlkit/vision/MlKitAnalyzerTest.kt
+++ b/camera/camera-mlkit-vision/src/test/java/androidx/camera/mlkit/vision/MlKitAnalyzerTest.kt
@@ -16,13 +16,14 @@
 
 package androidx.camera.mlkit.vision
 
-import android.graphics.Matrix
 import android.graphics.Rect
+import android.graphics.RectF
 import android.media.Image
 import android.os.Build
 import android.util.Size
 import androidx.camera.core.ImageAnalysis
 import androidx.camera.core.ImageProxy
+import androidx.camera.core.impl.utils.TransformUtils.getRectToRect
 import androidx.camera.core.impl.utils.executor.CameraXExecutors.directExecutor
 import androidx.camera.testing.fakes.FakeImageInfo
 import androidx.camera.testing.fakes.FakeImageProxy
@@ -51,7 +52,14 @@
         private const val RETURN_VALUE = "return value"
         private const val TIMESTAMP = 100L
         private const val ROTATION_DEGREES = 180
-        private val CROP_RECT = Rect(0, 0, 640, 480)
+        private val SENSOR_RECT = Rect(0, 0, 4000, 3000)
+        private val VIEW_RECT = Rect(0, 0, 1024, 768)
+        private val IMAGE_ANALYSIS_RECT = Rect(0, 0, 640, 480)
+        private val SENSOR_TO_BUFFER = getRectToRect(
+            RectF(SENSOR_RECT),
+            RectF(IMAGE_ANALYSIS_RECT),
+            0
+        )
     }
 
     @Test
@@ -150,7 +158,7 @@
     @Test
     fun transformationAndRotationIsCorrect() {
         // Arrange.
-        val additionalTransform = Matrix()
+        val additionalTransform = getRectToRect(RectF(SENSOR_RECT), RectF(VIEW_RECT), 0)
         additionalTransform.setScale(2F, 2F)
         val detector = FakeDetector(RETURN_VALUE, TYPE_BARCODE_SCANNING)
         val analyzer = MlKitAnalyzer(
@@ -165,25 +173,23 @@
         analyzer.analyze(createFakeImageProxy())
 
         // Assert that the matrix is passed to the MLKit detector.
-        val expected = floatArrayOf(-0.00625F, 0F, 2.0F, 0F, -0.0083333F, 2.0F, 0.0F, 0.0F, 1.0F)
+        val expected = floatArrayOf(-12.5F, 0F, 8000F, 0F, -12.5F, 6000F, 0F, 0F, 1F)
         val actual = FloatArray(9)
         detector.latestMatrix!!.getValues(actual)
-        actual.forEachIndexed { i, element ->
-            // Assert allowing float rounding error.
-            assertThat(expected[i]).isWithin(1E-4F).of(element)
-        }
+        assertThat(actual).usingTolerance(1E-3).containsExactly(expected).inOrder()
     }
 
     private fun createFakeImageProxy(): ImageProxy {
         val imageInfo = FakeImageInfo()
         imageInfo.timestamp = TIMESTAMP
         imageInfo.rotationDegrees = ROTATION_DEGREES
+        imageInfo.sensorToBufferTransformMatrix = SENSOR_TO_BUFFER
 
         val imageProxy = FakeImageProxy(imageInfo)
         imageProxy.image = mock(Image::class.java)
-        imageProxy.width = CROP_RECT.width()
-        imageProxy.height = CROP_RECT.height()
-        imageProxy.setCropRect(CROP_RECT)
+        imageProxy.width = IMAGE_ANALYSIS_RECT.width()
+        imageProxy.height = IMAGE_ANALYSIS_RECT.height()
+        imageProxy.setCropRect(IMAGE_ANALYSIS_RECT)
 
         return imageProxy
     }
diff --git a/camera/camera-testing/src/main/AndroidManifest.xml b/camera/camera-testing/src/main/AndroidManifest.xml
index 6fc9159..d88d24c 100644
--- a/camera/camera-testing/src/main/AndroidManifest.xml
+++ b/camera/camera-testing/src/main/AndroidManifest.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
   Copyright 2019 The Android Open Source Project
 
   Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,32 +22,21 @@
     <application>
         <activity
             android:name="androidx.camera.testing.activity.ForegroundTestActivity"
-            android:exported="true"
             android:configChanges="orientation|screenSize"
-            android:label="ForegroundTestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
+            android:exported="true"
+            android:label="ForegroundTestActivity" />
         <activity
             android:name="androidx.camera.testing.activity.CameraXTestActivity"
             android:exported="true"
-            android:label="CameraX TestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
+            android:label="CameraX TestActivity" />
         <activity
             android:name="androidx.camera.testing.activity.Camera2TestActivity"
             android:exported="true"
-            android:label="Camera2 TestActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
+            android:label="Camera2 TestActivity" />
+        <activity
+            android:name="androidx.camera.testing.activity.EmptyActivity"
+            android:exported="true"
+            android:label="EmptyActivity" />
     </application>
 </manifest>
 
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/WakelockEmptyActivityRule.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/WakelockEmptyActivityRule.kt
new file mode 100644
index 0000000..036c35f
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/WakelockEmptyActivityRule.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.camera.testing
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.os.Build
+import android.view.WindowManager
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.camera.core.Logger
+import androidx.camera.testing.Api27Impl.setShowWhenLocked
+import androidx.camera.testing.Api27Impl.setTurnScreenOn
+import androidx.camera.testing.activity.EmptyActivity
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.platform.app.InstrumentationRegistry
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * A rule that opens an empty Activity and wakes the device to prevent test failures.
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class WakelockEmptyActivityRule : TestRule {
+    override fun apply(base: Statement, description: Description): Statement =
+        object : Statement() {
+            override fun evaluate() {
+                val instrumentation = InstrumentationRegistry.getInstrumentation()
+                var activityRef: EmptyActivity? = null
+                try {
+                    activityRef = CoreAppTestUtil.launchActivity(
+                        instrumentation,
+                        EmptyActivity::class.java,
+                        Intent(Intent.ACTION_MAIN).apply {
+                            setClassName(
+                                ApplicationProvider.getApplicationContext<Context>().packageName,
+                                EmptyActivity::class.java.name
+                            )
+                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                        }
+                    )?.also { activity ->
+                        instrumentation.runOnMainSync {
+                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
+                                activity.setShowWhenLocked()
+                                activity.setTurnScreenOn()
+                                activity.window.addFlags(
+                                    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                                )
+                            } else {
+                                @Suppress("DEPRECATION")
+                                activity.window.addFlags(
+                                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                                        or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                                        or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                                )
+                            }
+                        }
+                    }
+                } catch (exception: Exception) {
+                    Logger.w("WakelockEmptyActivityRule", "Fail to open Activity + wakelock")
+                }
+
+                base.evaluate()
+
+                if (activityRef != null) {
+                    instrumentation.runOnMainSync { activityRef.finish() }
+                    instrumentation.waitForIdleSync()
+                }
+            }
+        }
+}
+
+@RequiresApi(Build.VERSION_CODES.O_MR1)
+object Api27Impl {
+    @DoNotInline
+    fun Activity.setShowWhenLocked() {
+        setShowWhenLocked(true)
+    }
+
+    @DoNotInline
+    fun Activity.setTurnScreenOn() {
+        setTurnScreenOn(true)
+    }
+}
\ No newline at end of file
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/activity/EmptyActivity.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/EmptyActivity.kt
new file mode 100644
index 0000000..01d6002
--- /dev/null
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/activity/EmptyActivity.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.camera.testing.activity
+
+import androidx.appcompat.app.AppCompatActivity
+
+/**
+ * An empty Activity.
+ */
+class EmptyActivity : AppCompatActivity()
\ No newline at end of file
diff --git a/camera/camera-video/api/1.3.0-beta01.txt b/camera/camera-video/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..fb0f4c7
--- /dev/null
+++ b/camera/camera-video/api/1.3.0-beta01.txt
@@ -0,0 +1,202 @@
+// Signature format: 4.0
+package androidx.camera.video {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class AudioStats {
+    method public abstract int getAudioState();
+    method public abstract Throwable? getErrorCause();
+    method public boolean hasAudio();
+    method public boolean hasError();
+    field public static final int AUDIO_STATE_ACTIVE = 0; // 0x0
+    field public static final int AUDIO_STATE_DISABLED = 1; // 0x1
+    field public static final int AUDIO_STATE_ENCODER_ERROR = 3; // 0x3
+    field public static final int AUDIO_STATE_MUTED = 5; // 0x5
+    field public static final int AUDIO_STATE_SOURCE_ERROR = 4; // 0x4
+    field public static final int AUDIO_STATE_SOURCE_SILENCED = 2; // 0x2
+  }
+
+  @RequiresApi(21) public class FallbackStrategy {
+    method public static androidx.camera.video.FallbackStrategy higherQualityOrLowerThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy higherQualityThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityOrHigherThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityThan(androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class FileDescriptorOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.os.ParcelFileDescriptor getParcelFileDescriptor();
+  }
+
+  @RequiresApi(21) public static final class FileDescriptorOutputOptions.Builder {
+    ctor public FileDescriptorOutputOptions.Builder(android.os.ParcelFileDescriptor);
+    method public androidx.camera.video.FileDescriptorOutputOptions build();
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class FileOutputOptions extends androidx.camera.video.OutputOptions {
+    method public java.io.File getFile();
+  }
+
+  @RequiresApi(21) public static final class FileOutputOptions.Builder {
+    ctor public FileOutputOptions.Builder(java.io.File);
+    method public androidx.camera.video.FileOutputOptions build();
+    method public androidx.camera.video.FileOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class MediaStoreOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.net.Uri getCollectionUri();
+    method public android.content.ContentResolver getContentResolver();
+    method public android.content.ContentValues getContentValues();
+    field public static final android.content.ContentValues EMPTY_CONTENT_VALUES;
+  }
+
+  public static final class MediaStoreOutputOptions.Builder {
+    ctor public MediaStoreOutputOptions.Builder(android.content.ContentResolver, android.net.Uri);
+    method public androidx.camera.video.MediaStoreOutputOptions build();
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setContentValues(android.content.ContentValues);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public abstract class OutputOptions {
+    method @IntRange(from=0) public long getDurationLimitMillis();
+    method @IntRange(from=0) public long getFileSizeLimit();
+    method public android.location.Location? getLocation();
+    field public static final int DURATION_UNLIMITED = 0; // 0x0
+    field public static final int FILE_SIZE_UNLIMITED = 0; // 0x0
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class OutputResults {
+    ctor public OutputResults();
+    method public abstract android.net.Uri getOutputUri();
+  }
+
+  @RequiresApi(21) public final class PendingRecording {
+    method @CheckResult public androidx.camera.video.Recording start(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public androidx.camera.video.PendingRecording withAudioEnabled();
+  }
+
+  @RequiresApi(21) public class Quality {
+    field public static final androidx.camera.video.Quality FHD;
+    field public static final androidx.camera.video.Quality HD;
+    field public static final androidx.camera.video.Quality HIGHEST;
+    field public static final androidx.camera.video.Quality LOWEST;
+    field public static final androidx.camera.video.Quality SD;
+    field public static final androidx.camera.video.Quality UHD;
+  }
+
+  @RequiresApi(21) public final class QualitySelector {
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality);
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality, androidx.camera.video.FallbackStrategy);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>, androidx.camera.video.FallbackStrategy);
+    method public static android.util.Size? getResolution(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+    method @Deprecated public static java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.CameraInfo);
+    method @Deprecated public static boolean isQualitySupported(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class Recorder implements androidx.camera.video.VideoOutput {
+    method public int getAspectRatio();
+    method public java.util.concurrent.Executor? getExecutor();
+    method public androidx.camera.video.QualitySelector getQualitySelector();
+    method public int getTargetVideoEncodingBitRate();
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo);
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+    method @RequiresApi(26) public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileDescriptorOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.MediaStoreOutputOptions);
+    field public static final androidx.camera.video.QualitySelector DEFAULT_QUALITY_SELECTOR;
+  }
+
+  @RequiresApi(21) public static final class Recorder.Builder {
+    ctor public Recorder.Builder();
+    method public androidx.camera.video.Recorder build();
+    method public androidx.camera.video.Recorder.Builder setAspectRatio(int);
+    method public androidx.camera.video.Recorder.Builder setExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.video.Recorder.Builder setQualitySelector(androidx.camera.video.QualitySelector);
+    method public androidx.camera.video.Recorder.Builder setTargetVideoEncodingBitRate(@IntRange(from=1) int);
+  }
+
+  @RequiresApi(21) public final class Recording implements java.lang.AutoCloseable {
+    method public void close();
+    method public void mute(boolean);
+    method public void pause();
+    method public void resume();
+    method public void stop();
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class RecordingStats {
+    method public abstract androidx.camera.video.AudioStats getAudioStats();
+    method public abstract long getNumBytesRecorded();
+    method public abstract long getRecordedDurationNanos();
+  }
+
+  @RequiresApi(21) public interface VideoCapabilities {
+    method public java.util.Set<androidx.camera.core.DynamicRange!> getSupportedDynamicRanges();
+    method public java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.DynamicRange);
+    method public boolean isQualitySupported(androidx.camera.video.Quality, androidx.camera.core.DynamicRange);
+  }
+
+  @RequiresApi(21) public final class VideoCapture<T extends androidx.camera.video.VideoOutput> extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public int getMirrorMode();
+    method public T getOutput();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public void setTargetRotation(int);
+    method public static <T extends androidx.camera.video.VideoOutput> androidx.camera.video.VideoCapture<T!> withOutput(T);
+  }
+
+  @RequiresApi(21) public static final class VideoCapture.Builder<T extends androidx.camera.video.VideoOutput> implements androidx.camera.core.ExtendableBuilder<androidx.camera.video.VideoCapture> {
+    ctor public VideoCapture.Builder(T);
+    method public androidx.camera.video.VideoCapture<T!> build();
+    method public androidx.camera.video.VideoCapture.Builder<T!> setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setMirrorMode(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public interface VideoOutput {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public abstract class VideoRecordEvent {
+    method public androidx.camera.video.OutputOptions getOutputOptions();
+    method public androidx.camera.video.RecordingStats getRecordingStats();
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Finalize extends androidx.camera.video.VideoRecordEvent {
+    method public Throwable? getCause();
+    method public int getError();
+    method public androidx.camera.video.OutputResults getOutputResults();
+    method public boolean hasError();
+    field public static final int ERROR_DURATION_LIMIT_REACHED = 9; // 0x9
+    field public static final int ERROR_ENCODING_FAILED = 6; // 0x6
+    field public static final int ERROR_FILE_SIZE_LIMIT_REACHED = 2; // 0x2
+    field public static final int ERROR_INSUFFICIENT_STORAGE = 3; // 0x3
+    field public static final int ERROR_INVALID_OUTPUT_OPTIONS = 5; // 0x5
+    field public static final int ERROR_NONE = 0; // 0x0
+    field public static final int ERROR_NO_VALID_DATA = 8; // 0x8
+    field public static final int ERROR_RECORDER_ERROR = 7; // 0x7
+    field public static final int ERROR_RECORDING_GARBAGE_COLLECTED = 10; // 0xa
+    field public static final int ERROR_SOURCE_INACTIVE = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Pause extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Resume extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Start extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Status extends androidx.camera.video.VideoRecordEvent {
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-video/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-video/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-video/api/restricted_1.3.0-beta01.txt b/camera/camera-video/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..fb0f4c7
--- /dev/null
+++ b/camera/camera-video/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,202 @@
+// Signature format: 4.0
+package androidx.camera.video {
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class AudioStats {
+    method public abstract int getAudioState();
+    method public abstract Throwable? getErrorCause();
+    method public boolean hasAudio();
+    method public boolean hasError();
+    field public static final int AUDIO_STATE_ACTIVE = 0; // 0x0
+    field public static final int AUDIO_STATE_DISABLED = 1; // 0x1
+    field public static final int AUDIO_STATE_ENCODER_ERROR = 3; // 0x3
+    field public static final int AUDIO_STATE_MUTED = 5; // 0x5
+    field public static final int AUDIO_STATE_SOURCE_ERROR = 4; // 0x4
+    field public static final int AUDIO_STATE_SOURCE_SILENCED = 2; // 0x2
+  }
+
+  @RequiresApi(21) public class FallbackStrategy {
+    method public static androidx.camera.video.FallbackStrategy higherQualityOrLowerThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy higherQualityThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityOrHigherThan(androidx.camera.video.Quality);
+    method public static androidx.camera.video.FallbackStrategy lowerQualityThan(androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class FileDescriptorOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.os.ParcelFileDescriptor getParcelFileDescriptor();
+  }
+
+  @RequiresApi(21) public static final class FileDescriptorOutputOptions.Builder {
+    ctor public FileDescriptorOutputOptions.Builder(android.os.ParcelFileDescriptor);
+    method public androidx.camera.video.FileDescriptorOutputOptions build();
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileDescriptorOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class FileOutputOptions extends androidx.camera.video.OutputOptions {
+    method public java.io.File getFile();
+  }
+
+  @RequiresApi(21) public static final class FileOutputOptions.Builder {
+    ctor public FileOutputOptions.Builder(java.io.File);
+    method public androidx.camera.video.FileOutputOptions build();
+    method public androidx.camera.video.FileOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.FileOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public final class MediaStoreOutputOptions extends androidx.camera.video.OutputOptions {
+    method public android.net.Uri getCollectionUri();
+    method public android.content.ContentResolver getContentResolver();
+    method public android.content.ContentValues getContentValues();
+    field public static final android.content.ContentValues EMPTY_CONTENT_VALUES;
+  }
+
+  public static final class MediaStoreOutputOptions.Builder {
+    ctor public MediaStoreOutputOptions.Builder(android.content.ContentResolver, android.net.Uri);
+    method public androidx.camera.video.MediaStoreOutputOptions build();
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setContentValues(android.content.ContentValues);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setDurationLimitMillis(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setFileSizeLimit(@IntRange(from=0) long);
+    method public androidx.camera.video.MediaStoreOutputOptions.Builder setLocation(android.location.Location?);
+  }
+
+  @RequiresApi(21) public abstract class OutputOptions {
+    method @IntRange(from=0) public long getDurationLimitMillis();
+    method @IntRange(from=0) public long getFileSizeLimit();
+    method public android.location.Location? getLocation();
+    field public static final int DURATION_UNLIMITED = 0; // 0x0
+    field public static final int FILE_SIZE_UNLIMITED = 0; // 0x0
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class OutputResults {
+    ctor public OutputResults();
+    method public abstract android.net.Uri getOutputUri();
+  }
+
+  @RequiresApi(21) public final class PendingRecording {
+    method @CheckResult public androidx.camera.video.Recording start(java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public androidx.camera.video.PendingRecording withAudioEnabled();
+  }
+
+  @RequiresApi(21) public class Quality {
+    field public static final androidx.camera.video.Quality FHD;
+    field public static final androidx.camera.video.Quality HD;
+    field public static final androidx.camera.video.Quality HIGHEST;
+    field public static final androidx.camera.video.Quality LOWEST;
+    field public static final androidx.camera.video.Quality SD;
+    field public static final androidx.camera.video.Quality UHD;
+  }
+
+  @RequiresApi(21) public final class QualitySelector {
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality);
+    method public static androidx.camera.video.QualitySelector from(androidx.camera.video.Quality, androidx.camera.video.FallbackStrategy);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>);
+    method public static androidx.camera.video.QualitySelector fromOrderedList(java.util.List<androidx.camera.video.Quality!>, androidx.camera.video.FallbackStrategy);
+    method public static android.util.Size? getResolution(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+    method @Deprecated public static java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.CameraInfo);
+    method @Deprecated public static boolean isQualitySupported(androidx.camera.core.CameraInfo, androidx.camera.video.Quality);
+  }
+
+  @RequiresApi(21) public final class Recorder implements androidx.camera.video.VideoOutput {
+    method public int getAspectRatio();
+    method public java.util.concurrent.Executor? getExecutor();
+    method public androidx.camera.video.QualitySelector getQualitySelector();
+    method public int getTargetVideoEncodingBitRate();
+    method public static androidx.camera.video.VideoCapabilities getVideoCapabilities(androidx.camera.core.CameraInfo);
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+    method @RequiresApi(26) public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileDescriptorOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.FileOutputOptions);
+    method public androidx.camera.video.PendingRecording prepareRecording(android.content.Context, androidx.camera.video.MediaStoreOutputOptions);
+    field public static final androidx.camera.video.QualitySelector DEFAULT_QUALITY_SELECTOR;
+  }
+
+  @RequiresApi(21) public static final class Recorder.Builder {
+    ctor public Recorder.Builder();
+    method public androidx.camera.video.Recorder build();
+    method public androidx.camera.video.Recorder.Builder setAspectRatio(int);
+    method public androidx.camera.video.Recorder.Builder setExecutor(java.util.concurrent.Executor);
+    method public androidx.camera.video.Recorder.Builder setQualitySelector(androidx.camera.video.QualitySelector);
+    method public androidx.camera.video.Recorder.Builder setTargetVideoEncodingBitRate(@IntRange(from=1) int);
+  }
+
+  @RequiresApi(21) public final class Recording implements java.lang.AutoCloseable {
+    method public void close();
+    method public void mute(boolean);
+    method public void pause();
+    method public void resume();
+    method public void stop();
+  }
+
+  @RequiresApi(21) @com.google.auto.value.AutoValue public abstract class RecordingStats {
+    method public abstract androidx.camera.video.AudioStats getAudioStats();
+    method public abstract long getNumBytesRecorded();
+    method public abstract long getRecordedDurationNanos();
+  }
+
+  @RequiresApi(21) public interface VideoCapabilities {
+    method public java.util.Set<androidx.camera.core.DynamicRange!> getSupportedDynamicRanges();
+    method public java.util.List<androidx.camera.video.Quality!> getSupportedQualities(androidx.camera.core.DynamicRange);
+    method public boolean isQualitySupported(androidx.camera.video.Quality, androidx.camera.core.DynamicRange);
+  }
+
+  @RequiresApi(21) public final class VideoCapture<T extends androidx.camera.video.VideoOutput> extends androidx.camera.core.UseCase {
+    method public androidx.camera.core.DynamicRange getDynamicRange();
+    method public int getMirrorMode();
+    method public T getOutput();
+    method public android.util.Range<java.lang.Integer!> getTargetFrameRate();
+    method public int getTargetRotation();
+    method public void setTargetRotation(int);
+    method public static <T extends androidx.camera.video.VideoOutput> androidx.camera.video.VideoCapture<T!> withOutput(T);
+  }
+
+  @RequiresApi(21) public static final class VideoCapture.Builder<T extends androidx.camera.video.VideoOutput> implements androidx.camera.core.ExtendableBuilder<androidx.camera.video.VideoCapture> {
+    ctor public VideoCapture.Builder(T);
+    method public androidx.camera.video.VideoCapture<T!> build();
+    method public androidx.camera.video.VideoCapture.Builder<T!> setDynamicRange(androidx.camera.core.DynamicRange);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setMirrorMode(int);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetFrameRate(android.util.Range<java.lang.Integer!>);
+    method public androidx.camera.video.VideoCapture.Builder<T!> setTargetRotation(int);
+  }
+
+  @RequiresApi(21) public interface VideoOutput {
+    method public void onSurfaceRequested(androidx.camera.core.SurfaceRequest);
+  }
+
+  @RequiresApi(21) public abstract class VideoRecordEvent {
+    method public androidx.camera.video.OutputOptions getOutputOptions();
+    method public androidx.camera.video.RecordingStats getRecordingStats();
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Finalize extends androidx.camera.video.VideoRecordEvent {
+    method public Throwable? getCause();
+    method public int getError();
+    method public androidx.camera.video.OutputResults getOutputResults();
+    method public boolean hasError();
+    field public static final int ERROR_DURATION_LIMIT_REACHED = 9; // 0x9
+    field public static final int ERROR_ENCODING_FAILED = 6; // 0x6
+    field public static final int ERROR_FILE_SIZE_LIMIT_REACHED = 2; // 0x2
+    field public static final int ERROR_INSUFFICIENT_STORAGE = 3; // 0x3
+    field public static final int ERROR_INVALID_OUTPUT_OPTIONS = 5; // 0x5
+    field public static final int ERROR_NONE = 0; // 0x0
+    field public static final int ERROR_NO_VALID_DATA = 8; // 0x8
+    field public static final int ERROR_RECORDER_ERROR = 7; // 0x7
+    field public static final int ERROR_RECORDING_GARBAGE_COLLECTED = 10; // 0xa
+    field public static final int ERROR_SOURCE_INACTIVE = 4; // 0x4
+    field public static final int ERROR_UNKNOWN = 1; // 0x1
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Pause extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Resume extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Start extends androidx.camera.video.VideoRecordEvent {
+  }
+
+  @RequiresApi(21) public static final class VideoRecordEvent.Status extends androidx.camera.video.VideoRecordEvent {
+  }
+
+}
+
diff --git a/camera/camera-video/lint-baseline.xml b/camera/camera-video/lint-baseline.xml
index e8b6b9c..303aa35 100644
--- a/camera/camera-video/lint-baseline.xml
+++ b/camera/camera-video/lint-baseline.xml
@@ -37,4 +37,13 @@
             file="src/androidTest/java/androidx/camera/video/internal/encoder/VideoEncoderTest.kt"/>
     </issue>
 
+    <issue
+        id="IgnoreClassLevelDetector"
+        message="@Ignore should not be used at the class level. Move the annotation to each test individually."
+        errorLine1="@Ignore(&quot;b/274840083&quot;)"
+        errorLine2="~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/test/java/androidx/camera/video/internal/audio/AudioSourceTest.kt"/>
+    </issue>
+
 </issues>
diff --git a/camera/camera-view/api/1.3.0-beta01.txt b/camera/camera-view/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..ed1e846
--- /dev/null
+++ b/camera/camera-view/api/1.3.0-beta01.txt
@@ -0,0 +1,173 @@
+// Signature format: 4.0
+package androidx.camera.view {
+
+  @RequiresApi(21) public abstract class CameraController {
+    method @MainThread public void clearEffects();
+    method @MainThread public void clearImageAnalysisAnalyzer();
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method @MainThread public androidx.camera.core.CameraControl? getCameraControl();
+    method @MainThread public androidx.camera.core.CameraInfo? getCameraInfo();
+    method @MainThread public androidx.camera.core.CameraSelector getCameraSelector();
+    method @MainThread public java.util.concurrent.Executor? getImageAnalysisBackgroundExecutor();
+    method @MainThread public int getImageAnalysisBackpressureStrategy();
+    method @MainThread public int getImageAnalysisImageQueueDepth();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getImageAnalysisTargetSize();
+    method @MainThread public int getImageCaptureFlashMode();
+    method @MainThread public java.util.concurrent.Executor? getImageCaptureIoExecutor();
+    method @MainThread public int getImageCaptureMode();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getImageCaptureTargetSize();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> getInitializationFuture();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getPreviewTargetSize();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTapToFocusState();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method @MainThread public androidx.camera.video.QualitySelector getVideoCaptureQualitySelector();
+    method @MainThread public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method @MainThread public boolean hasCamera(androidx.camera.core.CameraSelector);
+    method @MainThread public boolean isImageAnalysisEnabled();
+    method @MainThread public boolean isImageCaptureEnabled();
+    method @MainThread public boolean isPinchToZoomEnabled();
+    method @MainThread public boolean isRecording();
+    method @MainThread public boolean isTapToFocusEnabled();
+    method @MainThread public boolean isVideoCaptureEnabled();
+    method @MainThread public void setCameraSelector(androidx.camera.core.CameraSelector);
+    method @MainThread public void setEffects(java.util.Set<androidx.camera.core.CameraEffect!>);
+    method @MainThread public void setEnabledUseCases(int);
+    method @MainThread public void setImageAnalysisAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method @MainThread public void setImageAnalysisBackgroundExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageAnalysisBackpressureStrategy(int);
+    method @MainThread public void setImageAnalysisImageQueueDepth(int);
+    method @MainThread public void setImageAnalysisTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setImageCaptureFlashMode(int);
+    method @MainThread public void setImageCaptureIoExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageCaptureMode(int);
+    method @MainThread public void setImageCaptureTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method @MainThread public void setPinchToZoomEnabled(boolean);
+    method @MainThread public void setPreviewTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setTapToFocusEnabled(boolean);
+    method @MainThread public void setVideoCaptureQualitySelector(androidx.camera.video.QualitySelector);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method @MainThread @RequiresApi(26) public androidx.camera.video.Recording startRecording(androidx.camera.video.FileDescriptorOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.FileOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.MediaStoreOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method @MainThread public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int COORDINATE_SYSTEM_VIEW_REFERENCED = 1; // 0x1
+    field public static final int IMAGE_ANALYSIS = 2; // 0x2
+    field public static final int IMAGE_CAPTURE = 1; // 0x1
+    field public static final int TAP_TO_FOCUS_FAILED = 4; // 0x4
+    field public static final int TAP_TO_FOCUS_FOCUSED = 2; // 0x2
+    field public static final int TAP_TO_FOCUS_NOT_FOCUSED = 3; // 0x3
+    field public static final int TAP_TO_FOCUS_NOT_STARTED = 0; // 0x0
+    field public static final int TAP_TO_FOCUS_STARTED = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 4; // 0x4
+  }
+
+  @RequiresApi(21) public static final class CameraController.OutputSize {
+    ctor public CameraController.OutputSize(android.util.Size);
+    ctor public CameraController.OutputSize(int);
+    method public int getAspectRatio();
+    method public android.util.Size? getResolution();
+    field public static final int UNASSIGNED_ASPECT_RATIO = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public final class LifecycleCameraController extends androidx.camera.view.CameraController {
+    ctor public LifecycleCameraController(android.content.Context);
+    method @MainThread public void bindToLifecycle(androidx.lifecycle.LifecycleOwner);
+    method @MainThread public void unbind();
+  }
+
+  @RequiresApi(21) public final class PreviewView extends android.widget.FrameLayout {
+    ctor @UiThread public PreviewView(android.content.Context);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.view.CameraController? getController();
+    method @UiThread public androidx.camera.view.PreviewView.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.core.MeteringPointFactory getMeteringPointFactory();
+    method public androidx.camera.view.transform.OutputTransform? getOutputTransform();
+    method public androidx.lifecycle.LiveData<androidx.camera.view.PreviewView.StreamState!> getPreviewStreamState();
+    method @UiThread public androidx.camera.view.PreviewView.ScaleType getScaleType();
+    method @UiThread public androidx.camera.core.Preview.SurfaceProvider getSurfaceProvider();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort(int);
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setImplementationMode(androidx.camera.view.PreviewView.ImplementationMode);
+    method @UiThread public void setScaleType(androidx.camera.view.PreviewView.ScaleType);
+  }
+
+  @RequiresApi(21) public enum PreviewView.ImplementationMode {
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum PreviewView.ScaleType {
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_START;
+  }
+
+  public enum PreviewView.StreamState {
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState IDLE;
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
+  }
+
+  @RequiresApi(21) public final class RotationProvider {
+    ctor public RotationProvider(android.content.Context);
+    method @CheckResult public boolean addListener(java.util.concurrent.Executor, androidx.camera.view.RotationProvider.Listener);
+    method public void removeListener(androidx.camera.view.RotationProvider.Listener);
+  }
+
+  public static interface RotationProvider.Listener {
+    method public void onRotationChanged(int);
+  }
+
+}
+
+package androidx.camera.view.transform {
+
+  @RequiresApi(21) public final class CoordinateTransform {
+    ctor public CoordinateTransform(androidx.camera.view.transform.OutputTransform, androidx.camera.view.transform.OutputTransform);
+    method public void mapPoint(android.graphics.PointF);
+    method public void mapPoints(float[]);
+    method public void mapRect(android.graphics.RectF);
+    method public void transform(android.graphics.Matrix);
+  }
+
+  @RequiresApi(21) public final class FileTransformFactory {
+    ctor public FileTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(android.content.ContentResolver, android.net.Uri) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.File) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.InputStream) throws java.io.IOException;
+    method public boolean isUsingExifOrientation();
+    method public void setUsingExifOrientation(boolean);
+  }
+
+  @RequiresApi(21) public final class ImageProxyTransformFactory {
+    ctor public ImageProxyTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(androidx.camera.core.ImageProxy);
+    method public boolean isUsingCropRect();
+    method public boolean isUsingRotationDegrees();
+    method public void setUsingCropRect(boolean);
+    method public void setUsingRotationDegrees(boolean);
+  }
+
+  @RequiresApi(21) public final class OutputTransform {
+  }
+
+}
+
+package androidx.camera.view.video {
+
+  @RequiresApi(21) public class AudioConfig {
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public static androidx.camera.view.video.AudioConfig create(boolean);
+    method public boolean getAudioEnabled();
+    field public static final androidx.camera.view.video.AudioConfig AUDIO_DISABLED;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-view/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-view/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-view/api/restricted_1.3.0-beta01.txt b/camera/camera-view/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..ed1e846
--- /dev/null
+++ b/camera/camera-view/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,173 @@
+// Signature format: 4.0
+package androidx.camera.view {
+
+  @RequiresApi(21) public abstract class CameraController {
+    method @MainThread public void clearEffects();
+    method @MainThread public void clearImageAnalysisAnalyzer();
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> enableTorch(boolean);
+    method @MainThread public androidx.camera.core.CameraControl? getCameraControl();
+    method @MainThread public androidx.camera.core.CameraInfo? getCameraInfo();
+    method @MainThread public androidx.camera.core.CameraSelector getCameraSelector();
+    method @MainThread public java.util.concurrent.Executor? getImageAnalysisBackgroundExecutor();
+    method @MainThread public int getImageAnalysisBackpressureStrategy();
+    method @MainThread public int getImageAnalysisImageQueueDepth();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getImageAnalysisTargetSize();
+    method @MainThread public int getImageCaptureFlashMode();
+    method @MainThread public java.util.concurrent.Executor? getImageCaptureIoExecutor();
+    method @MainThread public int getImageCaptureMode();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getImageCaptureTargetSize();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> getInitializationFuture();
+    method @MainThread public androidx.camera.view.CameraController.OutputSize? getPreviewTargetSize();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTapToFocusState();
+    method @MainThread public androidx.lifecycle.LiveData<java.lang.Integer!> getTorchState();
+    method @MainThread public androidx.camera.video.QualitySelector getVideoCaptureQualitySelector();
+    method @MainThread public androidx.lifecycle.LiveData<androidx.camera.core.ZoomState!> getZoomState();
+    method @MainThread public boolean hasCamera(androidx.camera.core.CameraSelector);
+    method @MainThread public boolean isImageAnalysisEnabled();
+    method @MainThread public boolean isImageCaptureEnabled();
+    method @MainThread public boolean isPinchToZoomEnabled();
+    method @MainThread public boolean isRecording();
+    method @MainThread public boolean isTapToFocusEnabled();
+    method @MainThread public boolean isVideoCaptureEnabled();
+    method @MainThread public void setCameraSelector(androidx.camera.core.CameraSelector);
+    method @MainThread public void setEffects(java.util.Set<androidx.camera.core.CameraEffect!>);
+    method @MainThread public void setEnabledUseCases(int);
+    method @MainThread public void setImageAnalysisAnalyzer(java.util.concurrent.Executor, androidx.camera.core.ImageAnalysis.Analyzer);
+    method @MainThread public void setImageAnalysisBackgroundExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageAnalysisBackpressureStrategy(int);
+    method @MainThread public void setImageAnalysisImageQueueDepth(int);
+    method @MainThread public void setImageAnalysisTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setImageCaptureFlashMode(int);
+    method @MainThread public void setImageCaptureIoExecutor(java.util.concurrent.Executor?);
+    method @MainThread public void setImageCaptureMode(int);
+    method @MainThread public void setImageCaptureTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setLinearZoom(@FloatRange(from=0.0f, to=1.0f) float);
+    method @MainThread public void setPinchToZoomEnabled(boolean);
+    method @MainThread public void setPreviewTargetSize(androidx.camera.view.CameraController.OutputSize?);
+    method @MainThread public void setTapToFocusEnabled(boolean);
+    method @MainThread public void setVideoCaptureQualitySelector(androidx.camera.video.QualitySelector);
+    method @MainThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setZoomRatio(float);
+    method @MainThread @RequiresApi(26) public androidx.camera.video.Recording startRecording(androidx.camera.video.FileDescriptorOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.FileOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public androidx.camera.video.Recording startRecording(androidx.camera.video.MediaStoreOutputOptions, androidx.camera.view.video.AudioConfig, java.util.concurrent.Executor, androidx.core.util.Consumer<androidx.camera.video.VideoRecordEvent!>);
+    method @MainThread public void takePicture(androidx.camera.core.ImageCapture.OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageSavedCallback);
+    method @MainThread public void takePicture(java.util.concurrent.Executor, androidx.camera.core.ImageCapture.OnImageCapturedCallback);
+    field public static final int COORDINATE_SYSTEM_VIEW_REFERENCED = 1; // 0x1
+    field public static final int IMAGE_ANALYSIS = 2; // 0x2
+    field public static final int IMAGE_CAPTURE = 1; // 0x1
+    field public static final int TAP_TO_FOCUS_FAILED = 4; // 0x4
+    field public static final int TAP_TO_FOCUS_FOCUSED = 2; // 0x2
+    field public static final int TAP_TO_FOCUS_NOT_FOCUSED = 3; // 0x3
+    field public static final int TAP_TO_FOCUS_NOT_STARTED = 0; // 0x0
+    field public static final int TAP_TO_FOCUS_STARTED = 1; // 0x1
+    field public static final int VIDEO_CAPTURE = 4; // 0x4
+  }
+
+  @RequiresApi(21) public static final class CameraController.OutputSize {
+    ctor public CameraController.OutputSize(android.util.Size);
+    ctor public CameraController.OutputSize(int);
+    method public int getAspectRatio();
+    method public android.util.Size? getResolution();
+    field public static final int UNASSIGNED_ASPECT_RATIO = -1; // 0xffffffff
+  }
+
+  @RequiresApi(21) public final class LifecycleCameraController extends androidx.camera.view.CameraController {
+    ctor public LifecycleCameraController(android.content.Context);
+    method @MainThread public void bindToLifecycle(androidx.lifecycle.LifecycleOwner);
+    method @MainThread public void unbind();
+  }
+
+  @RequiresApi(21) public final class PreviewView extends android.widget.FrameLayout {
+    ctor @UiThread public PreviewView(android.content.Context);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public PreviewView(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.view.CameraController? getController();
+    method @UiThread public androidx.camera.view.PreviewView.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.core.MeteringPointFactory getMeteringPointFactory();
+    method public androidx.camera.view.transform.OutputTransform? getOutputTransform();
+    method public androidx.lifecycle.LiveData<androidx.camera.view.PreviewView.StreamState!> getPreviewStreamState();
+    method @UiThread public androidx.camera.view.PreviewView.ScaleType getScaleType();
+    method @UiThread public androidx.camera.core.Preview.SurfaceProvider getSurfaceProvider();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort();
+    method @UiThread public androidx.camera.core.ViewPort? getViewPort(int);
+    method @UiThread public void setController(androidx.camera.view.CameraController?);
+    method @UiThread public void setImplementationMode(androidx.camera.view.PreviewView.ImplementationMode);
+    method @UiThread public void setScaleType(androidx.camera.view.PreviewView.ScaleType);
+  }
+
+  @RequiresApi(21) public enum PreviewView.ImplementationMode {
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.view.PreviewView.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum PreviewView.ScaleType {
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.view.PreviewView.ScaleType FIT_START;
+  }
+
+  public enum PreviewView.StreamState {
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState IDLE;
+    enum_constant public static final androidx.camera.view.PreviewView.StreamState STREAMING;
+  }
+
+  @RequiresApi(21) public final class RotationProvider {
+    ctor public RotationProvider(android.content.Context);
+    method @CheckResult public boolean addListener(java.util.concurrent.Executor, androidx.camera.view.RotationProvider.Listener);
+    method public void removeListener(androidx.camera.view.RotationProvider.Listener);
+  }
+
+  public static interface RotationProvider.Listener {
+    method public void onRotationChanged(int);
+  }
+
+}
+
+package androidx.camera.view.transform {
+
+  @RequiresApi(21) public final class CoordinateTransform {
+    ctor public CoordinateTransform(androidx.camera.view.transform.OutputTransform, androidx.camera.view.transform.OutputTransform);
+    method public void mapPoint(android.graphics.PointF);
+    method public void mapPoints(float[]);
+    method public void mapRect(android.graphics.RectF);
+    method public void transform(android.graphics.Matrix);
+  }
+
+  @RequiresApi(21) public final class FileTransformFactory {
+    ctor public FileTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(android.content.ContentResolver, android.net.Uri) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.File) throws java.io.IOException;
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(java.io.InputStream) throws java.io.IOException;
+    method public boolean isUsingExifOrientation();
+    method public void setUsingExifOrientation(boolean);
+  }
+
+  @RequiresApi(21) public final class ImageProxyTransformFactory {
+    ctor public ImageProxyTransformFactory();
+    method public androidx.camera.view.transform.OutputTransform getOutputTransform(androidx.camera.core.ImageProxy);
+    method public boolean isUsingCropRect();
+    method public boolean isUsingRotationDegrees();
+    method public void setUsingCropRect(boolean);
+    method public void setUsingRotationDegrees(boolean);
+  }
+
+  @RequiresApi(21) public final class OutputTransform {
+  }
+
+}
+
+package androidx.camera.view.video {
+
+  @RequiresApi(21) public class AudioConfig {
+    method @RequiresPermission(android.Manifest.permission.RECORD_AUDIO) public static androidx.camera.view.video.AudioConfig create(boolean);
+    method public boolean getAudioEnabled();
+    field public static final androidx.camera.view.video.AudioConfig AUDIO_DISABLED;
+  }
+
+}
+
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
index 9c2f968..d935dd4 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraController.java
@@ -80,7 +80,6 @@
 import androidx.camera.video.Recording;
 import androidx.camera.video.VideoCapture;
 import androidx.camera.video.VideoRecordEvent;
-import androidx.camera.view.transform.OutputTransform;
 import androidx.camera.view.video.AudioConfig;
 import androidx.core.content.PermissionChecker;
 import androidx.core.util.Consumer;
@@ -1098,16 +1097,16 @@
 
     @OptIn(markerClass = {TransformExperimental.class})
     @MainThread
-    void updatePreviewViewTransform(@Nullable OutputTransform outputTransform) {
+    void updatePreviewViewTransform(@Nullable Matrix matrix) {
         checkMainThread();
         if (mAnalysisAnalyzer == null) {
             return;
         }
-        if (outputTransform == null) {
+        if (matrix == null) {
             mAnalysisAnalyzer.updateTransform(null);
         } else if (mAnalysisAnalyzer.getTargetCoordinateSystem()
                 == COORDINATE_SYSTEM_VIEW_REFERENCED) {
-            mAnalysisAnalyzer.updateTransform(outputTransform.getMatrix());
+            mAnalysisAnalyzer.updateTransform(matrix);
         }
     }
 
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
index f2a95b5..cb853a1 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
@@ -660,7 +660,7 @@
         mPreviewViewMeteringPointFactory.recalculate(new Size(getWidth(), getHeight()),
                 getLayoutDirection());
         if (mCameraController != null) {
-            mCameraController.updatePreviewViewTransform(getOutputTransform());
+            mCameraController.updatePreviewViewTransform(getSensorToViewTransform());
         }
     }
 
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
index 22a51d3..5ac8b85 100644
--- a/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
+++ b/camera/camera-view/src/test/java/androidx/camera/view/CameraControllerTest.kt
@@ -44,7 +44,6 @@
 import androidx.camera.video.Quality
 import androidx.camera.video.QualitySelector
 import androidx.camera.view.CameraController.COORDINATE_SYSTEM_VIEW_REFERENCED
-import androidx.camera.view.transform.OutputTransform
 import androidx.concurrent.futures.CallbackToFutureAdapter
 import androidx.test.annotation.UiThreadTest
 import androidx.test.core.app.ApplicationProvider
@@ -277,10 +276,7 @@
             }
         }
         controller.setImageAnalysisAnalyzer(mainThreadExecutor(), analyzer)
-        val outputTransform = previewTransform?.let {
-            OutputTransform(it, Size(1, 1))
-        }
-        controller.updatePreviewViewTransform(outputTransform)
+        controller.updatePreviewViewTransform(previewTransform)
         return matrix
     }
 
diff --git a/camera/camera-view/src/test/resources/robolectric.properties b/camera/camera-view/src/test/resources/robolectric.properties
index 7946f01..69fde47 100644
--- a/camera/camera-view/src/test/resources/robolectric.properties
+++ b/camera/camera-view/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/camera/camera-viewfinder-compose/api/1.3.0-beta01.txt b/camera/camera-viewfinder-compose/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-viewfinder-compose/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-viewfinder-compose/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-viewfinder-compose/api/restricted_1.3.0-beta01.txt b/camera/camera-viewfinder-compose/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-viewfinder-core/api/1.3.0-beta01.txt b/camera/camera-viewfinder-core/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-core/api/1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-viewfinder-core/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-viewfinder-core/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-viewfinder-core/api/restricted_1.3.0-beta01.txt b/camera/camera-viewfinder-core/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-core/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-viewfinder/api/1.3.0-beta01.txt b/camera/camera-viewfinder/api/1.3.0-beta01.txt
new file mode 100644
index 0000000..a7333d7
--- /dev/null
+++ b/camera/camera-viewfinder/api/1.3.0-beta01.txt
@@ -0,0 +1,58 @@
+// Signature format: 4.0
+package androidx.camera.viewfinder {
+
+  @RequiresApi(21) public final class CameraViewfinder extends android.widget.FrameLayout {
+    ctor @UiThread public CameraViewfinder(android.content.Context);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.viewfinder.CameraViewfinder.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.viewfinder.CameraViewfinder.ScaleType getScaleType();
+    method @UiThread public com.google.common.util.concurrent.ListenableFuture<android.view.Surface!> requestSurfaceAsync(androidx.camera.viewfinder.ViewfinderSurfaceRequest);
+    method @UiThread public void setScaleType(androidx.camera.viewfinder.CameraViewfinder.ScaleType);
+  }
+
+  @RequiresApi(21) public enum CameraViewfinder.ImplementationMode {
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum CameraViewfinder.ScaleType {
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_START;
+  }
+
+  @RequiresApi(21) public final class CameraViewfinderExt {
+    method public suspend Object? requestSurface(androidx.camera.viewfinder.CameraViewfinder, androidx.camera.viewfinder.ViewfinderSurfaceRequest viewfinderSurfaceRequest, kotlin.coroutines.Continuation<? super android.view.Surface>);
+    field public static final androidx.camera.viewfinder.CameraViewfinderExt INSTANCE;
+  }
+
+  @RequiresApi(21) public class ViewfinderSurfaceRequest {
+    method public androidx.camera.viewfinder.CameraViewfinder.ImplementationMode? getImplementationMode();
+    method public int getLensFacing();
+    method public android.util.Size getResolution();
+    method public int getSensorOrientation();
+    method public void markSurfaceSafeToRelease();
+  }
+
+  public static final class ViewfinderSurfaceRequest.Builder {
+    ctor public ViewfinderSurfaceRequest.Builder(android.util.Size);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.ViewfinderSurfaceRequest);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest build();
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setImplementationMode(androidx.camera.viewfinder.CameraViewfinder.ImplementationMode?);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setLensFacing(int);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setSensorOrientation(int);
+  }
+
+  public final class ViewfinderSurfaceRequestUtil {
+    method @RequiresApi(21) public static androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder populateFromCharacteristics(androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder, android.hardware.camera2.CameraCharacteristics cameraCharacteristics);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/camera/camera-viewfinder/api/res-1.3.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to camera/camera-viewfinder/api/res-1.3.0-beta01.txt
diff --git a/camera/camera-viewfinder/api/restricted_1.3.0-beta01.txt b/camera/camera-viewfinder/api/restricted_1.3.0-beta01.txt
new file mode 100644
index 0000000..a7333d7
--- /dev/null
+++ b/camera/camera-viewfinder/api/restricted_1.3.0-beta01.txt
@@ -0,0 +1,58 @@
+// Signature format: 4.0
+package androidx.camera.viewfinder {
+
+  @RequiresApi(21) public final class CameraViewfinder extends android.widget.FrameLayout {
+    ctor @UiThread public CameraViewfinder(android.content.Context);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?, int);
+    ctor @UiThread public CameraViewfinder(android.content.Context, android.util.AttributeSet?, int, int);
+    method @UiThread public android.graphics.Bitmap? getBitmap();
+    method @UiThread public androidx.camera.viewfinder.CameraViewfinder.ImplementationMode getImplementationMode();
+    method @UiThread public androidx.camera.viewfinder.CameraViewfinder.ScaleType getScaleType();
+    method @UiThread public com.google.common.util.concurrent.ListenableFuture<android.view.Surface!> requestSurfaceAsync(androidx.camera.viewfinder.ViewfinderSurfaceRequest);
+    method @UiThread public void setScaleType(androidx.camera.viewfinder.CameraViewfinder.ScaleType);
+  }
+
+  @RequiresApi(21) public enum CameraViewfinder.ImplementationMode {
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ImplementationMode COMPATIBLE;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ImplementationMode PERFORMANCE;
+  }
+
+  @RequiresApi(21) public enum CameraViewfinder.ScaleType {
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_CENTER;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_END;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FILL_START;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_CENTER;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_END;
+    enum_constant public static final androidx.camera.viewfinder.CameraViewfinder.ScaleType FIT_START;
+  }
+
+  @RequiresApi(21) public final class CameraViewfinderExt {
+    method public suspend Object? requestSurface(androidx.camera.viewfinder.CameraViewfinder, androidx.camera.viewfinder.ViewfinderSurfaceRequest viewfinderSurfaceRequest, kotlin.coroutines.Continuation<? super android.view.Surface>);
+    field public static final androidx.camera.viewfinder.CameraViewfinderExt INSTANCE;
+  }
+
+  @RequiresApi(21) public class ViewfinderSurfaceRequest {
+    method public androidx.camera.viewfinder.CameraViewfinder.ImplementationMode? getImplementationMode();
+    method public int getLensFacing();
+    method public android.util.Size getResolution();
+    method public int getSensorOrientation();
+    method public void markSurfaceSafeToRelease();
+  }
+
+  public static final class ViewfinderSurfaceRequest.Builder {
+    ctor public ViewfinderSurfaceRequest.Builder(android.util.Size);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.ViewfinderSurfaceRequest);
+    ctor public ViewfinderSurfaceRequest.Builder(androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest build();
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setImplementationMode(androidx.camera.viewfinder.CameraViewfinder.ImplementationMode?);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setLensFacing(int);
+    method public androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder setSensorOrientation(int);
+  }
+
+  public final class ViewfinderSurfaceRequestUtil {
+    method @RequiresApi(21) public static androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder populateFromCharacteristics(androidx.camera.viewfinder.ViewfinderSurfaceRequest.Builder, android.hardware.camera2.CameraCharacteristics cameraCharacteristics);
+  }
+
+}
+
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BindUnbindUseCasesStressTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BindUnbindUseCasesStressTest.kt
index c84c865..3094788 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BindUnbindUseCasesStressTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BindUnbindUseCasesStressTest.kt
@@ -46,6 +46,7 @@
 import androidx.camera.testing.LabTestRule
 import androidx.camera.testing.StressTestRule
 import androidx.camera.testing.SurfaceTextureProvider
+import androidx.camera.testing.WakelockEmptyActivityRule
 import androidx.camera.testing.fakes.FakeLifecycleOwner
 import androidx.camera.video.FileOutputOptions
 import androidx.camera.video.Recorder
@@ -104,6 +105,9 @@
     @get:Rule
     val repeatRule = RepeatRule()
 
+    @get:Rule
+    val wakelockEmptyActivityRule = WakelockEmptyActivityRule()
+
     private val context = ApplicationProvider.getApplicationContext<Context>()
 
     private lateinit var cameraProvider: ProcessCameraProvider
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
index 67a1fec..f93db30 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
@@ -70,6 +70,7 @@
 import androidx.camera.testing.CameraUtil
 import androidx.camera.testing.CoreAppTestUtil
 import androidx.camera.testing.SurfaceTextureProvider
+import androidx.camera.testing.WakelockEmptyActivityRule
 import androidx.camera.testing.fakes.FakeLifecycleOwner
 import androidx.camera.testing.fakes.FakeSessionProcessor
 import androidx.camera.video.Recorder
@@ -134,6 +135,9 @@
     val temporaryFolder =
         TemporaryFolder(ApplicationProvider.getApplicationContext<Context>().cacheDir)
 
+    @get:Rule
+    val wakelockEmptyActivityRule = WakelockEmptyActivityRule()
+
     companion object {
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
index 7ed59c5..26c6fd4 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ZoomControlDeviceTest.kt
@@ -38,6 +38,7 @@
 import androidx.camera.lifecycle.ProcessCameraProvider
 import androidx.camera.testing.CameraPipeConfigTestRule
 import androidx.camera.testing.CameraUtil
+import androidx.camera.testing.WakelockEmptyActivityRule
 import androidx.camera.testing.fakes.FakeLifecycleOwner
 import androidx.concurrent.futures.await
 import androidx.lifecycle.LiveData
@@ -89,6 +90,9 @@
         CameraUtil.PreTestCameraIdList(cameraConfig)
     )
 
+    @get:Rule
+    val wakelockEmptyActivityRule = WakelockEmptyActivityRule()
+
     private val context = ApplicationProvider.getApplicationContext<Context>()
     private lateinit var camera: Camera
     private lateinit var cameraProvider: ProcessCameraProvider
diff --git a/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml b/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml
new file mode 100644
index 0000000..85f7f92
--- /dev/null
+++ b/camera/integration-tests/uiwidgetstestapp/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ImageCaptureScreen has parameter &apos;onLinearZoomChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onLinearZoomChange: (Float) -> Unit,"
+        errorLine2="                        ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreen.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VideoCaptureScreen has parameter &apos;onLinearZoomChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onLinearZoomChange: (Float) -> Unit,"
+        errorLine2="                        ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreen.kt"/>
+    </issue>
+
+</issues>
diff --git a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreen.kt b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreen.kt
index b74e4c2..4b4ed18 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreen.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/imagecapture/ImageCaptureScreen.kt
@@ -111,7 +111,6 @@
     modifier: Modifier,
     zoomRatio: Float,
     linearZoom: Float,
-    @Suppress("PrimitiveInLambda")
     onLinearZoomChange: (Float) -> Unit,
     isCameraReady: Boolean,
     hasFlashUnit: Boolean,
diff --git a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreen.kt b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreen.kt
index 282d17a..5bb0aae 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreen.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/main/java/androidx/camera/integration/uiwidgets/compose/ui/screen/videocapture/VideoCaptureScreen.kt
@@ -90,7 +90,6 @@
     modifier: Modifier = Modifier,
     zoomRatio: Float,
     linearZoom: Float,
-    @Suppress("PrimitiveInLambda")
     onLinearZoomChange: (Float) -> Unit,
     isCameraReady: Boolean,
     recordState: VideoCaptureScreenState.RecordState,
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
index ac558e5..1aabfee8 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/CameraControllerFragment.java
@@ -579,21 +579,29 @@
     // For testing
     // -----------------
 
+    /**
+     */
     @VisibleForTesting
     LifecycleCameraController getCameraController() {
         return mCameraController;
     }
 
+    /**
+     */
     @VisibleForTesting
     void setWrappedAnalyzer(@Nullable ImageAnalysis.Analyzer analyzer) {
         mWrappedAnalyzer = analyzer;
     }
 
+    /**
+     */
     @VisibleForTesting
     PreviewView getPreviewView() {
         return mPreviewView;
     }
 
+    /**
+     */
     @VisibleForTesting
     int getSensorRotation() {
         return mRotation;
diff --git a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
index d250fc8..4f5c8ae7 100644
--- a/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
+++ b/camera/integration-tests/viewtestapp/src/main/java/androidx/camera/integration/view/ToneMappingSurfaceEffect.kt
@@ -32,4 +32,4 @@
     fun release() {
         processor.release()
     }
-}
\ No newline at end of file
+}
diff --git a/camera/integration-tests/viewtestapp/src/main/res/layout/camera_controller_view.xml b/camera/integration-tests/viewtestapp/src/main/res/layout/camera_controller_view.xml
index d605440..648cf04 100644
--- a/camera/integration-tests/viewtestapp/src/main/res/layout/camera_controller_view.xml
+++ b/camera/integration-tests/viewtestapp/src/main/res/layout/camera_controller_view.xml
@@ -167,4 +167,4 @@
         android:id="@+id/torch_state_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/camera/integration-tests/viewtestapp/src/main/res/menu/actionbar_menu.xml b/camera/integration-tests/viewtestapp/src/main/res/menu/actionbar_menu.xml
index b850fd4..d16f41d 100644
--- a/camera/integration-tests/viewtestapp/src/main/res/menu/actionbar_menu.xml
+++ b/camera/integration-tests/viewtestapp/src/main/res/menu/actionbar_menu.xml
@@ -40,4 +40,4 @@
         android:id="@+id/mlkit"
         android:title="@string/mlkit"
         app:showAsAction="never" />
-</menu>
\ No newline at end of file
+</menu>
diff --git a/car/app/app-automotive/src/main/java/androidx/car/app/activity/BaseCarAppActivity.java b/car/app/app-automotive/src/main/java/androidx/car/app/activity/BaseCarAppActivity.java
index b2e52f4..2ccd6f3 100644
--- a/car/app/app-automotive/src/main/java/androidx/car/app/activity/BaseCarAppActivity.java
+++ b/car/app/app-automotive/src/main/java/androidx/car/app/activity/BaseCarAppActivity.java
@@ -35,7 +35,6 @@
 import android.util.Log;
 import android.view.PixelCopy;
 import android.view.View;
-import android.view.Window;
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.widget.ImageView;
@@ -63,6 +62,7 @@
 import androidx.car.app.serialization.BundlerException;
 import androidx.car.app.utils.ThreadUtils;
 import androidx.core.view.DisplayCutoutCompat;
+import androidx.core.view.WindowCompat;
 import androidx.core.view.WindowInsetsCompat;
 import androidx.fragment.app.FragmentActivity;
 import androidx.lifecycle.Lifecycle;
@@ -251,11 +251,6 @@
             return new WindowInsets.Builder(insets).setInsets(
                     WindowInsets.Type.displayCutout(), Insets.NONE).build();
         }
-
-        @DoNotInline
-        static void setDecorFitsSystemWindows(Window window, boolean decorFitsSystemWindows) {
-            window.setDecorFitsSystemWindows(decorFitsSystemWindows);
-        }
     }
 
     @Override
@@ -336,11 +331,11 @@
             return view.onApplyWindowInsets(insets);
         });
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-            Api30Impl.setDecorFitsSystemWindows(getWindow(), false);
-        } else {
-            getWindow().getDecorView().setFitsSystemWindows(false);
-        }
+        // IMPORTANT: The SystemUiVisibility applied here must match the insets provided to the
+        // host in OnApplyWindowInsetsListener above. Failing to do so would cause a mismatch
+        // between the insets applied to the content on the hosts side vs. the actual visible
+        // window available on the client side.
+        WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
         mActivityContainerView.requestApplyInsets();
     }
 
diff --git a/car/app/app-automotive/src/test/java/androidx/car/app/activity/CarAppActivityTest.java b/car/app/app-automotive/src/test/java/androidx/car/app/activity/CarAppActivityTest.java
index 1d56b43..02804af 100644
--- a/car/app/app-automotive/src/test/java/androidx/car/app/activity/CarAppActivityTest.java
+++ b/car/app/app-automotive/src/test/java/androidx/car/app/activity/CarAppActivityTest.java
@@ -42,7 +42,6 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
-import android.os.Build;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
@@ -75,11 +74,9 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.Config;
 import org.robolectric.annotation.internal.DoNotInstrument;
 import org.robolectric.shadows.ShadowApplication;
 import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.shadows.ShadowPhoneWindow;
 
 /** Tests for {@link CarAppActivity}. */
 @RunWith(RobolectricTestRunner.class)
@@ -399,41 +396,6 @@
 
     }
 
-    @Test
-    @Config(maxSdk = Build.VERSION_CODES.Q)
-    public void testFitsSystemWindows_whenQAndBelow_shouldSetFitsSystemWindowsToFalse() {
-        Intent newIntent = new Intent(getApplicationContext(), CarAppActivity.class);
-        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(newIntent)) {
-            scenario.onActivity(activity -> {
-                try {
-                    assertThat(
-                            activity.getWindow().getDecorView().getFitsSystemWindows()).isFalse();
-                } catch (Exception e) {
-                    fail(Log.getStackTraceString(e));
-                }
-            });
-
-        }
-    }
-
-    @Test
-    @Config(minSdk = Build.VERSION_CODES.R)
-    public void testDecorFitsSystemWindows_whenRAndAbove_shouldSetDecorFitsSystemWindowsToFalse() {
-        Intent newIntent = new Intent(getApplicationContext(), CarAppActivity.class);
-        try (ActivityScenario<CarAppActivity> scenario = ActivityScenario.launch(newIntent)) {
-            scenario.onActivity(activity -> {
-                try {
-                    ShadowPhoneWindow shadowPhoneWindow = (ShadowPhoneWindow) shadowOf(
-                            activity.getWindow());
-                    assertThat(shadowPhoneWindow.getDecorFitsSystemWindows()).isFalse();
-                } catch (Exception e) {
-                    fail(Log.getStackTraceString(e));
-                }
-            });
-
-        }
-    }
-
     interface CarActivityAction {
         void accept(ActivityScenario<CarAppActivity> scenario, CarAppActivity activity)
                 throws Exception;
diff --git a/car/app/app-automotive/src/test/resources/robolectric.properties b/car/app/app-automotive/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/car/app/app-automotive/src/test/resources/robolectric.properties
+++ b/car/app/app-automotive/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/car/app/app-projected/src/test/resources/robolectric.properties b/car/app/app-projected/src/test/resources/robolectric.properties
index 7946f01..69fde47 100644
--- a/car/app/app-projected/src/test/resources/robolectric.properties
+++ b/car/app/app-projected/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/car/app/app-testing/src/test/resources/robolectric.properties b/car/app/app-testing/src/test/resources/robolectric.properties
index 71111c5..69fde47 100644
--- a/car/app/app-testing/src/test/resources/robolectric.properties
+++ b/car/app/app-testing/src/test/resources/robolectric.properties
@@ -1,17 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index fd934ef..8d416e1 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -1852,7 +1852,7 @@
   @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(7) public final class MapWithContentTemplate implements androidx.car.app.model.Template {
     method public androidx.car.app.model.ActionStrip? getActionStrip();
     method public androidx.car.app.navigation.model.MapController? getMapController();
-    method public androidx.car.app.model.Template? getTemplate();
+    method public androidx.car.app.model.Template getTemplate();
   }
 
   public static final class MapWithContentTemplate.Builder {
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index fd934ef..8d416e1 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -1852,7 +1852,7 @@
   @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.ExperimentalCarApi @androidx.car.app.annotations.RequiresCarApi(7) public final class MapWithContentTemplate implements androidx.car.app.model.Template {
     method public androidx.car.app.model.ActionStrip? getActionStrip();
     method public androidx.car.app.navigation.model.MapController? getMapController();
-    method public androidx.car.app.model.Template? getTemplate();
+    method public androidx.car.app.model.Template getTemplate();
   }
 
   public static final class MapWithContentTemplate.Builder {
diff --git a/car/app/app/src/main/java/androidx/car/app/navigation/model/MapWithContentTemplate.java b/car/app/app/src/main/java/androidx/car/app/navigation/model/MapWithContentTemplate.java
index aeb25a7..45f4f6a 100644
--- a/car/app/app/src/main/java/androidx/car/app/navigation/model/MapWithContentTemplate.java
+++ b/car/app/app/src/main/java/androidx/car/app/navigation/model/MapWithContentTemplate.java
@@ -46,7 +46,7 @@
 public final class MapWithContentTemplate implements Template {
     @Nullable
     private final MapController mMapController;
-    @Nullable
+    @NonNull
     private final Template mTemplate;
     @Nullable
     private final ActionStrip mActionStrip;
@@ -64,7 +64,12 @@
     /** Constructs an empty instance, used by serialization code. */
     private MapWithContentTemplate() {
         mMapController = null;
-        mTemplate = null;
+        mTemplate = new Template() {
+            @Override
+            public int hashCode() {
+                return super.hashCode();
+            }
+        };
         mActionStrip = null;
     }
 
@@ -83,7 +88,7 @@
      *
      * @see Builder#setTemplate(Template)
      */
-    @Nullable
+    @NonNull
     public Template getTemplate() {
         return mTemplate;
     }
@@ -122,8 +127,8 @@
     public static final class Builder {
         @Nullable
         MapController mMapController;
-        @Nullable
-        Template mTemplate;
+        @NonNull
+        Template mTemplate = new Template() {};
         @Nullable
         ActionStrip mActionStrip;
 
@@ -187,7 +192,7 @@
         @NonNull
         public MapWithContentTemplate build() {
             ContentTemplateConstraints.MAP_WITH_CONTENT_TEMPLATE_CONSTRAINTS
-                    .validateOrThrow(requireNonNull(mTemplate));
+                    .validateOrThrow(mTemplate);
 
             return new MapWithContentTemplate(this);
         }
diff --git a/car/app/app/src/main/java/androidx/car/app/navigation/model/constraints/ContentTemplateConstraints.java b/car/app/app/src/main/java/androidx/car/app/navigation/model/constraints/ContentTemplateConstraints.java
index 5ee9c5b..4ee8883 100644
--- a/car/app/app/src/main/java/androidx/car/app/navigation/model/constraints/ContentTemplateConstraints.java
+++ b/car/app/app/src/main/java/androidx/car/app/navigation/model/constraints/ContentTemplateConstraints.java
@@ -29,7 +29,7 @@
 import com.google.common.collect.ImmutableSet;
 
 /**
- * Encapsulates the constraints to apply when creating a Content [Template] within a parent
+ * Encapsulates the constraints to apply when creating a Content {@link Template} within a parent
  * template.
  */
 @ExperimentalCarApi
@@ -56,7 +56,7 @@
     private ImmutableSet<Class<? extends Template>> mAllowedTemplateTypes;
 
     /**
-     * Returns {@code true} if the {@link ContentTemplate} meets the constraint's requirement(s).
+     * Checks if the {@link ContentTemplate} meets the constraint's requirement(s).
      *
      * @throws IllegalArgumentException if any types are not allowed
      */
diff --git a/car/app/app/src/test/java/androidx/car/app/navigation/model/MapWithContentTemplateTest.java b/car/app/app/src/test/java/androidx/car/app/navigation/model/MapWithContentTemplateTest.java
index 383b08a..03a9cfb 100644
--- a/car/app/app/src/test/java/androidx/car/app/navigation/model/MapWithContentTemplateTest.java
+++ b/car/app/app/src/test/java/androidx/car/app/navigation/model/MapWithContentTemplateTest.java
@@ -69,7 +69,7 @@
 
     @Test
     public void createInstance_noTemplate_throws() {
-        assertThrows(NullPointerException.class, () -> new MapWithContentTemplate.Builder()
+        assertThrows(IllegalArgumentException.class, () -> new MapWithContentTemplate.Builder()
                 .build());
     }
 
diff --git a/car/app/app/src/test/resources/robolectric.properties b/car/app/app/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/car/app/app/src/test/resources/robolectric.properties
+++ b/car/app/app/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/collection/collection/build.gradle b/collection/collection/build.gradle
index 47b1d5e..b69575e 100644
--- a/collection/collection/build.gradle
+++ b/collection/collection/build.gradle
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
 import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
@@ -37,6 +37,8 @@
     linux()
     ios()
 
+    defaultPlatform(PlatformIdentifier.JVM)
+
     sourceSets {
         all {
             languageSettings.optIn("kotlin.RequiresOptIn")
@@ -46,6 +48,7 @@
         commonMain {
             dependencies {
                 api(libs.kotlinStdlib)
+                api(project(":annotation:annotation"))
             }
         }
 
@@ -57,12 +60,6 @@
             }
         }
 
-        jvmMain {
-            dependencies {
-                api("androidx.annotation:annotation:1.3.0")
-            }
-        }
-
         jvmTest {
             dependencies {
                 implementation(libs.kotlinTestJunit)
diff --git a/collection/collection/src/commonMain/kotlin/androidx/collection/LruCache.kt b/collection/collection/src/commonMain/kotlin/androidx/collection/LruCache.kt
index 9c4b106..689e5c3 100644
--- a/collection/collection/src/commonMain/kotlin/androidx/collection/LruCache.kt
+++ b/collection/collection/src/commonMain/kotlin/androidx/collection/LruCache.kt
@@ -16,7 +16,7 @@
 
 package androidx.collection
 
-import androidx.collection.internal.IntRangeKmp
+import androidx.annotation.IntRange
 import androidx.collection.internal.Lock
 import androidx.collection.internal.LruHashMap
 import androidx.collection.internal.synchronized
@@ -34,7 +34,7 @@
  * cache.
  */
 public open class LruCache<K : Any, V : Any>
-public constructor(@IntRangeKmp(from = 1, to = MAX_VALUE) private var maxSize: Int) {
+public constructor(@IntRange(from = 1, to = MAX_VALUE) private var maxSize: Int) {
 
     init {
         require(maxSize > 0) { "maxSize <= 0" }
@@ -59,7 +59,7 @@
      *
      * @param maxSize The new maximum size.
      */
-    public open fun resize(@IntRangeKmp(from = 1, to = MAX_VALUE) maxSize: Int) {
+    public open fun resize(@IntRange(from = 1, to = MAX_VALUE) maxSize: Int) {
         require(maxSize > 0) { "maxSize <= 0" }
 
         lock.synchronized {
diff --git a/collection/collection/src/commonMain/kotlin/androidx/collection/internal/IntRangeKmp.kt b/collection/collection/src/commonMain/kotlin/androidx/collection/internal/IntRangeKmp.kt
deleted file mode 100644
index 61e9a1d..0000000
--- a/collection/collection/src/commonMain/kotlin/androidx/collection/internal/IntRangeKmp.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.collection.internal
-
-/*
- * OptionalExpectation is experimental, should be compile-time safe.
- * Without OptionalExpectation we have to add actual annotation class to nativeMain,
- * which in turn leads to the annotation being removed from api files.
- */
-@OptIn(ExperimentalMultiplatform::class)
-@OptionalExpectation
-internal expect annotation class IntRangeKmp(
-    val from: Long = Long.MIN_VALUE,
-    val to: Long = Long.MAX_VALUE,
-)
diff --git a/collection/collection/src/jvmMain/kotlin/androidx/collection/internal/IntRangeKmp.jvm.kt b/collection/collection/src/jvmMain/kotlin/androidx/collection/internal/IntRangeKmp.jvm.kt
deleted file mode 100644
index 7894d67..0000000
--- a/collection/collection/src/jvmMain/kotlin/androidx/collection/internal/IntRangeKmp.jvm.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:RestrictTo(RestrictTo.Scope.LIBRARY)
-
-package androidx.collection.internal
-
-import androidx.annotation.RestrictTo
-
-@Suppress("ACTUAL_WITHOUT_EXPECT") // https://youtrack.jetbrains.com/issue/KT-37316
-internal actual typealias IntRangeKmp = androidx.annotation.IntRange
diff --git a/compose/animation/animation-core/api/1.5.0-beta01.txt b/compose/animation/animation-core/api/1.5.0-beta01.txt
index 595b3e9..1bb4425 100644
--- a/compose/animation/animation-core/api/1.5.0-beta01.txt
+++ b/compose/animation/animation-core/api/1.5.0-beta01.txt
@@ -333,9 +333,6 @@
     property public static final androidx.compose.animation.core.Easing LinearOutSlowInEasing;
   }
 
-  @kotlin.RequiresOptIn(message="This is an experimental animation API for Transition. It may change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTransitionApi {
-  }
-
   public interface FiniteAnimationSpec<T> extends androidx.compose.animation.core.AnimationSpec<T> {
     method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
   }
@@ -435,9 +432,6 @@
     method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface InternalAnimationApi {
-  }
-
   @androidx.compose.runtime.Immutable public final class KeyframesSpec<T> implements androidx.compose.animation.core.DurationBasedAnimationSpec<T> {
     ctor public KeyframesSpec(androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> config);
     method public androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> getConfig();
@@ -621,7 +615,6 @@
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRect(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Rect>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Rect> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
-    method @androidx.compose.animation.core.ExperimentalTransitionApi @androidx.compose.runtime.Composable public static inline <S, T> androidx.compose.animation.core.Transition<T> createChildTransition(androidx.compose.animation.core.Transition<S>, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> transformToChildState);
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional String? label);
   }
diff --git a/compose/animation/animation-core/api/public_plus_experimental_1.5.0-beta01.txt b/compose/animation/animation-core/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..595b3e9
--- /dev/null
+++ b/compose/animation/animation-core/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,768 @@
+// Signature format: 4.0
+package androidx.compose.animation.core {
+
+  public final class Animatable<T, V extends androidx.compose.animation.core.AnimationVector> {
+    ctor @Deprecated public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold);
+    ctor public Animatable(T initialValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional T? visibilityThreshold, optional String label);
+    method public suspend Object? animateDecay(T initialVelocity, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+    method public suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T initialVelocity, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Animatable<T,V>,kotlin.Unit>? block, optional kotlin.coroutines.Continuation<? super androidx.compose.animation.core.AnimationResult<T,V>>);
+    method public androidx.compose.runtime.State<T> asState();
+    method public String getLabel();
+    method public T? getLowerBound();
+    method public T getTargetValue();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T? getUpperBound();
+    method public T getValue();
+    method public T getVelocity();
+    method public V getVelocityVector();
+    method public boolean isRunning();
+    method public suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? stop(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public void updateBounds(optional T? lowerBound, optional T? upperBound);
+    property public final boolean isRunning;
+    property public final String label;
+    property public final T? lowerBound;
+    property public final T targetValue;
+    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+    property public final T? upperBound;
+    property public final T value;
+    property public final T velocity;
+    property public final V velocityVector;
+  }
+
+  public final class AnimatableKt {
+    method public static androidx.compose.animation.core.Animatable<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> Animatable(float initialValue, optional float visibilityThreshold);
+  }
+
+  public final class AnimateAsStateKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDpAsState(float targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.Dp> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Dp,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDpAsState(float targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.Dp> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Dp,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloatAsState(float targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional float visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloatAsState(float targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional float visibilityThreshold, optional kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Integer> animateIntAsState(int targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Integer> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Integer> animateIntAsState(int targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Integer> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.IntOffset> animateIntOffsetAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntOffset,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.IntOffset> animateIntOffsetAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntOffset,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.IntSize> animateIntSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.unit.IntSize> animateIntSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Offset> animateOffsetAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Offset> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Offset> animateOffsetAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Offset> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRectAsState(androidx.compose.ui.geometry.Rect targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Rect> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Rect,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRectAsState(androidx.compose.ui.geometry.Rect targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Rect> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Rect,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSizeAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Size> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Size,kotlin.Unit>? finishedListener);
+    method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional String label, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValueAsState(T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional T? visibilityThreshold, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? finishedListener);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface Animation<T, V extends androidx.compose.animation.core.AnimationVector> {
+    method public long getDurationNanos();
+    method public T getTargetValue();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValueFromNanos(long playTimeNanos);
+    method public V getVelocityVectorFromNanos(long playTimeNanos);
+    method public default boolean isFinishedFromNanos(long playTimeNanos);
+    method public boolean isInfinite();
+    property public abstract long durationNanos;
+    property public abstract boolean isInfinite;
+    property public abstract T targetValue;
+    property public abstract androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+  }
+
+  public final class AnimationConstants {
+    field public static final int DefaultDurationMillis = 300; // 0x12c
+    field public static final androidx.compose.animation.core.AnimationConstants INSTANCE;
+    field public static final long UnspecifiedTime = -9223372036854775808L; // 0x8000000000000000L
+  }
+
+  public enum AnimationEndReason {
+    method public static androidx.compose.animation.core.AnimationEndReason valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.animation.core.AnimationEndReason[] values();
+    enum_constant public static final androidx.compose.animation.core.AnimationEndReason BoundReached;
+    enum_constant public static final androidx.compose.animation.core.AnimationEndReason Finished;
+  }
+
+  public final class AnimationKt {
+    method public static androidx.compose.animation.core.DecayAnimation<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> DecayAnimation(androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, float initialValue, optional float initialVelocity);
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TargetBasedAnimation<T,V> TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, T initialVelocity);
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> T getVelocityFromNanos(androidx.compose.animation.core.Animation<T,V>, long playTimeNanos);
+  }
+
+  public final class AnimationResult<T, V extends androidx.compose.animation.core.AnimationVector> {
+    ctor public AnimationResult(androidx.compose.animation.core.AnimationState<T,V> endState, androidx.compose.animation.core.AnimationEndReason endReason);
+    method public androidx.compose.animation.core.AnimationEndReason getEndReason();
+    method public androidx.compose.animation.core.AnimationState<T,V> getEndState();
+    property public final androidx.compose.animation.core.AnimationEndReason endReason;
+    property public final androidx.compose.animation.core.AnimationState<T,V> endState;
+  }
+
+  public final class AnimationScope<T, V extends androidx.compose.animation.core.AnimationVector> {
+    method public void cancelAnimation();
+    method public long getFinishedTimeNanos();
+    method public long getLastFrameTimeNanos();
+    method public long getStartTimeNanos();
+    method public T getTargetValue();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValue();
+    method public T getVelocity();
+    method public V getVelocityVector();
+    method public boolean isRunning();
+    method public androidx.compose.animation.core.AnimationState<T,V> toAnimationState();
+    property public final long finishedTimeNanos;
+    property public final boolean isRunning;
+    property public final long lastFrameTimeNanos;
+    property public final long startTimeNanos;
+    property public final T targetValue;
+    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+    property public final T value;
+    property public final T velocity;
+    property public final V velocityVector;
+  }
+
+  public interface AnimationSpec<T> {
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+  }
+
+  public final class AnimationSpecKt {
+    method @Deprecated @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.InfiniteRepeatableSpec<T> infiniteRepeatable(androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.InfiniteRepeatableSpec<T> infiniteRepeatable(androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.KeyframesSpec<T> keyframes(kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T>,kotlin.Unit> init);
+    method @Deprecated @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.RepeatableSpec<T> repeatable(int iterations, androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.RepeatableSpec<T> repeatable(int iterations, androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.SnapSpec<T> snap(optional int delayMillis);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.SpringSpec<T> spring(optional float dampingRatio, optional float stiffness, optional T? visibilityThreshold);
+    method @androidx.compose.runtime.Stable public static <T> androidx.compose.animation.core.TweenSpec<T> tween(optional int durationMillis, optional int delayMillis, optional androidx.compose.animation.core.Easing easing);
+  }
+
+  public final class AnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
+    ctor public AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, optional V? initialVelocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+    method public long getFinishedTimeNanos();
+    method public long getLastFrameTimeNanos();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValue();
+    method public T getVelocity();
+    method public V getVelocityVector();
+    method public boolean isRunning();
+    property public final long finishedTimeNanos;
+    property public final boolean isRunning;
+    property public final long lastFrameTimeNanos;
+    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+    property public T value;
+    property public final T velocity;
+    property public final V velocityVector;
+  }
+
+  public final class AnimationStateKt {
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> AnimationState(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+    method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> AnimationState(float initialValue, optional float initialVelocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+    method public static androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> copy(androidx.compose.animation.core.AnimationState<java.lang.Float,androidx.compose.animation.core.AnimationVector1D>, optional float value, optional float velocity, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.AnimationState<T,V> copy(androidx.compose.animation.core.AnimationState<T,V>, optional T value, optional V? velocityVector, optional long lastFrameTimeNanos, optional long finishedTimeNanos, optional boolean isRunning);
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> V createZeroVectorFrom(androidx.compose.animation.core.TwoWayConverter<T,V>, T value);
+    method public static boolean isFinished(androidx.compose.animation.core.AnimationState<?,?>);
+  }
+
+  public abstract sealed class AnimationVector {
+  }
+
+  public final class AnimationVector1D extends androidx.compose.animation.core.AnimationVector {
+    ctor public AnimationVector1D(float initVal);
+    method public float getValue();
+    property public final float value;
+  }
+
+  public final class AnimationVector2D extends androidx.compose.animation.core.AnimationVector {
+    ctor public AnimationVector2D(float v1, float v2);
+    method public float getV1();
+    method public float getV2();
+    property public final float v1;
+    property public final float v2;
+  }
+
+  public final class AnimationVector3D extends androidx.compose.animation.core.AnimationVector {
+    ctor public AnimationVector3D(float v1, float v2, float v3);
+    method public float getV1();
+    method public float getV2();
+    method public float getV3();
+    property public final float v1;
+    property public final float v2;
+    property public final float v3;
+  }
+
+  public final class AnimationVector4D extends androidx.compose.animation.core.AnimationVector {
+    ctor public AnimationVector4D(float v1, float v2, float v3, float v4);
+    method public float getV1();
+    method public float getV2();
+    method public float getV3();
+    method public float getV4();
+    property public final float v1;
+    property public final float v2;
+    property public final float v3;
+    property public final float v4;
+  }
+
+  public final class AnimationVectorsKt {
+    method public static androidx.compose.animation.core.AnimationVector1D AnimationVector(float v1);
+    method public static androidx.compose.animation.core.AnimationVector2D AnimationVector(float v1, float v2);
+    method public static androidx.compose.animation.core.AnimationVector3D AnimationVector(float v1, float v2, float v3);
+    method public static androidx.compose.animation.core.AnimationVector4D AnimationVector(float v1, float v2, float v3, float v4);
+  }
+
+  @androidx.compose.runtime.Immutable public final class CubicBezierEasing implements androidx.compose.animation.core.Easing {
+    ctor public CubicBezierEasing(float a, float b, float c, float d);
+    method public float transform(float fraction);
+  }
+
+  public final class DecayAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
+    ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
+    ctor public DecayAnimation(androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+    ctor public DecayAnimation(androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, V initialVelocityVector);
+    method public long getDurationNanos();
+    method public T getInitialValue();
+    method public V getInitialVelocityVector();
+    method public T getTargetValue();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValueFromNanos(long playTimeNanos);
+    method public V getVelocityVectorFromNanos(long playTimeNanos);
+    method public boolean isInfinite();
+    property public long durationNanos;
+    property public final T initialValue;
+    property public final V initialVelocityVector;
+    property public boolean isInfinite;
+    property public T targetValue;
+    property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+  }
+
+  public interface DecayAnimationSpec<T> {
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedDecayAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter);
+  }
+
+  public final class DecayAnimationSpecKt {
+    method public static float calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float>, float initialValue, float initialVelocity);
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> T calculateTargetValue(androidx.compose.animation.core.DecayAnimationSpec<T>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T initialVelocity);
+    method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> exponentialDecay(optional float frictionMultiplier, optional float absVelocityThreshold);
+    method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> generateDecayAnimationSpec(androidx.compose.animation.core.FloatDecayAnimationSpec);
+  }
+
+  public interface DurationBasedAnimationSpec<T> extends androidx.compose.animation.core.FiniteAnimationSpec<T> {
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+  }
+
+  @androidx.compose.runtime.Stable public fun interface Easing {
+    method public float transform(float fraction);
+  }
+
+  public final class EasingFunctionsKt {
+    method public static androidx.compose.animation.core.Easing getEase();
+    method public static androidx.compose.animation.core.Easing getEaseIn();
+    method public static androidx.compose.animation.core.Easing getEaseInBack();
+    method public static androidx.compose.animation.core.Easing getEaseInBounce();
+    method public static androidx.compose.animation.core.Easing getEaseInCirc();
+    method public static androidx.compose.animation.core.Easing getEaseInCubic();
+    method public static androidx.compose.animation.core.Easing getEaseInElastic();
+    method public static androidx.compose.animation.core.Easing getEaseInExpo();
+    method public static androidx.compose.animation.core.Easing getEaseInOut();
+    method public static androidx.compose.animation.core.Easing getEaseInOutBack();
+    method public static androidx.compose.animation.core.Easing getEaseInOutBounce();
+    method public static androidx.compose.animation.core.Easing getEaseInOutCirc();
+    method public static androidx.compose.animation.core.Easing getEaseInOutCubic();
+    method public static androidx.compose.animation.core.Easing getEaseInOutElastic();
+    method public static androidx.compose.animation.core.Easing getEaseInOutExpo();
+    method public static androidx.compose.animation.core.Easing getEaseInOutQuad();
+    method public static androidx.compose.animation.core.Easing getEaseInOutQuart();
+    method public static androidx.compose.animation.core.Easing getEaseInOutQuint();
+    method public static androidx.compose.animation.core.Easing getEaseInOutSine();
+    method public static androidx.compose.animation.core.Easing getEaseInQuad();
+    method public static androidx.compose.animation.core.Easing getEaseInQuart();
+    method public static androidx.compose.animation.core.Easing getEaseInQuint();
+    method public static androidx.compose.animation.core.Easing getEaseInSine();
+    method public static androidx.compose.animation.core.Easing getEaseOut();
+    method public static androidx.compose.animation.core.Easing getEaseOutBack();
+    method public static androidx.compose.animation.core.Easing getEaseOutBounce();
+    method public static androidx.compose.animation.core.Easing getEaseOutCirc();
+    method public static androidx.compose.animation.core.Easing getEaseOutCubic();
+    method public static androidx.compose.animation.core.Easing getEaseOutElastic();
+    method public static androidx.compose.animation.core.Easing getEaseOutExpo();
+    method public static androidx.compose.animation.core.Easing getEaseOutQuad();
+    method public static androidx.compose.animation.core.Easing getEaseOutQuart();
+    method public static androidx.compose.animation.core.Easing getEaseOutQuint();
+    method public static androidx.compose.animation.core.Easing getEaseOutSine();
+    property public static final androidx.compose.animation.core.Easing Ease;
+    property public static final androidx.compose.animation.core.Easing EaseIn;
+    property public static final androidx.compose.animation.core.Easing EaseInBack;
+    property public static final androidx.compose.animation.core.Easing EaseInBounce;
+    property public static final androidx.compose.animation.core.Easing EaseInCirc;
+    property public static final androidx.compose.animation.core.Easing EaseInCubic;
+    property public static final androidx.compose.animation.core.Easing EaseInElastic;
+    property public static final androidx.compose.animation.core.Easing EaseInExpo;
+    property public static final androidx.compose.animation.core.Easing EaseInOut;
+    property public static final androidx.compose.animation.core.Easing EaseInOutBack;
+    property public static final androidx.compose.animation.core.Easing EaseInOutBounce;
+    property public static final androidx.compose.animation.core.Easing EaseInOutCirc;
+    property public static final androidx.compose.animation.core.Easing EaseInOutCubic;
+    property public static final androidx.compose.animation.core.Easing EaseInOutElastic;
+    property public static final androidx.compose.animation.core.Easing EaseInOutExpo;
+    property public static final androidx.compose.animation.core.Easing EaseInOutQuad;
+    property public static final androidx.compose.animation.core.Easing EaseInOutQuart;
+    property public static final androidx.compose.animation.core.Easing EaseInOutQuint;
+    property public static final androidx.compose.animation.core.Easing EaseInOutSine;
+    property public static final androidx.compose.animation.core.Easing EaseInQuad;
+    property public static final androidx.compose.animation.core.Easing EaseInQuart;
+    property public static final androidx.compose.animation.core.Easing EaseInQuint;
+    property public static final androidx.compose.animation.core.Easing EaseInSine;
+    property public static final androidx.compose.animation.core.Easing EaseOut;
+    property public static final androidx.compose.animation.core.Easing EaseOutBack;
+    property public static final androidx.compose.animation.core.Easing EaseOutBounce;
+    property public static final androidx.compose.animation.core.Easing EaseOutCirc;
+    property public static final androidx.compose.animation.core.Easing EaseOutCubic;
+    property public static final androidx.compose.animation.core.Easing EaseOutElastic;
+    property public static final androidx.compose.animation.core.Easing EaseOutExpo;
+    property public static final androidx.compose.animation.core.Easing EaseOutQuad;
+    property public static final androidx.compose.animation.core.Easing EaseOutQuart;
+    property public static final androidx.compose.animation.core.Easing EaseOutQuint;
+    property public static final androidx.compose.animation.core.Easing EaseOutSine;
+  }
+
+  public final class EasingKt {
+    method public static androidx.compose.animation.core.Easing getFastOutLinearInEasing();
+    method public static androidx.compose.animation.core.Easing getFastOutSlowInEasing();
+    method public static androidx.compose.animation.core.Easing getLinearEasing();
+    method public static androidx.compose.animation.core.Easing getLinearOutSlowInEasing();
+    property public static final androidx.compose.animation.core.Easing FastOutLinearInEasing;
+    property public static final androidx.compose.animation.core.Easing FastOutSlowInEasing;
+    property public static final androidx.compose.animation.core.Easing LinearEasing;
+    property public static final androidx.compose.animation.core.Easing LinearOutSlowInEasing;
+  }
+
+  @kotlin.RequiresOptIn(message="This is an experimental animation API for Transition. It may change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTransitionApi {
+  }
+
+  public interface FiniteAnimationSpec<T> extends androidx.compose.animation.core.AnimationSpec<T> {
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface FloatAnimationSpec extends androidx.compose.animation.core.AnimationSpec<java.lang.Float> {
+    method public long getDurationNanos(float initialValue, float targetValue, float initialVelocity);
+    method public default float getEndVelocity(float initialValue, float targetValue, float initialVelocity);
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    method public default <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedFloatAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<java.lang.Float,V> converter);
+  }
+
+  public interface FloatDecayAnimationSpec {
+    method public float getAbsVelocityThreshold();
+    method public long getDurationNanos(float initialValue, float initialVelocity);
+    method public float getTargetValue(float initialValue, float initialVelocity);
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    property public abstract float absVelocityThreshold;
+  }
+
+  public final class FloatExponentialDecaySpec implements androidx.compose.animation.core.FloatDecayAnimationSpec {
+    ctor public FloatExponentialDecaySpec(optional float frictionMultiplier, optional float absVelocityThreshold);
+    method public float getAbsVelocityThreshold();
+    method public long getDurationNanos(float initialValue, float initialVelocity);
+    method public float getTargetValue(float initialValue, float initialVelocity);
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    property public float absVelocityThreshold;
+  }
+
+  public final class FloatSpringSpec implements androidx.compose.animation.core.FloatAnimationSpec {
+    ctor public FloatSpringSpec(optional float dampingRatio, optional float stiffness, optional float visibilityThreshold);
+    method public float getDampingRatio();
+    method public long getDurationNanos(float initialValue, float targetValue, float initialVelocity);
+    method public float getStiffness();
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    property public final float dampingRatio;
+    property public final float stiffness;
+  }
+
+  public final class FloatTweenSpec implements androidx.compose.animation.core.FloatAnimationSpec {
+    ctor public FloatTweenSpec(optional int duration, optional int delay, optional androidx.compose.animation.core.Easing easing);
+    method public int getDelay();
+    method public int getDuration();
+    method public long getDurationNanos(float initialValue, float targetValue, float initialVelocity);
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float targetValue, float initialVelocity);
+    property public final int delay;
+    property public final int duration;
+  }
+
+  public final class InfiniteAnimationPolicyKt {
+    method public static suspend inline <R> Object? withInfiniteAnimationFrameMillis(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend <R> Object? withInfiniteAnimationFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+  }
+
+  public final class InfiniteRepeatableSpec<T> implements androidx.compose.animation.core.AnimationSpec<T> {
+    ctor @Deprecated public InfiniteRepeatableSpec(androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    ctor public InfiniteRepeatableSpec(androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method public androidx.compose.animation.core.DurationBasedAnimationSpec<T> getAnimation();
+    method public long getInitialStartOffset();
+    method public androidx.compose.animation.core.RepeatMode getRepeatMode();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation;
+    property public final long initialStartOffset;
+    property public final androidx.compose.animation.core.RepeatMode repeatMode;
+  }
+
+  public final class InfiniteTransition {
+    method public java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<?,?>> getAnimations();
+    method public String getLabel();
+    property public final java.util.List<androidx.compose.animation.core.InfiniteTransition.TransitionAnimationState<?,?>> animations;
+    property public final String label;
+  }
+
+  public final class InfiniteTransition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
+    method public androidx.compose.animation.core.TargetBasedAnimation<T,V> getAnimation();
+    method public androidx.compose.animation.core.AnimationSpec<T> getAnimationSpec();
+    method public String getLabel();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValue();
+    property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
+    property public final androidx.compose.animation.core.AnimationSpec<T> animationSpec;
+    property public final String label;
+    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+    property public T value;
+  }
+
+  public final class InfiniteTransitionKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.InfiniteTransition, float initialValue, float targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<java.lang.Float> animationSpec, optional String label);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec);
+    method @androidx.compose.runtime.Composable public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.InfiniteTransition, T initialValue, T targetValue, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, androidx.compose.animation.core.InfiniteRepeatableSpec<T> animationSpec, optional String label);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition();
+    method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
+  }
+
+  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface InternalAnimationApi {
+  }
+
+  @androidx.compose.runtime.Immutable public final class KeyframesSpec<T> implements androidx.compose.animation.core.DurationBasedAnimationSpec<T> {
+    ctor public KeyframesSpec(androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> config);
+    method public androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> getConfig();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedKeyframesSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> config;
+  }
+
+  public static final class KeyframesSpec.KeyframeEntity<T> {
+  }
+
+  public static final class KeyframesSpec.KeyframesSpecConfig<T> {
+    ctor public KeyframesSpec.KeyframesSpecConfig();
+    method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> at(T, int timeStamp);
+    method public infix androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T> atFraction(T, float fraction);
+    method public int getDelayMillis();
+    method public int getDurationMillis();
+    method public void setDelayMillis(int);
+    method public void setDurationMillis(int);
+    method public infix void with(androidx.compose.animation.core.KeyframesSpec.KeyframeEntity<T>, androidx.compose.animation.core.Easing easing);
+    property public final int delayMillis;
+    property public final int durationMillis;
+  }
+
+  public final class MutableTransitionState<S> {
+    ctor public MutableTransitionState(S initialState);
+    method public S getCurrentState();
+    method public S getTargetState();
+    method public boolean isIdle();
+    method public void setTargetState(S!);
+    property public final S currentState;
+    property public final boolean isIdle;
+    property public final S targetState;
+  }
+
+  public enum RepeatMode {
+    method public static androidx.compose.animation.core.RepeatMode valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.animation.core.RepeatMode[] values();
+    enum_constant public static final androidx.compose.animation.core.RepeatMode Restart;
+    enum_constant public static final androidx.compose.animation.core.RepeatMode Reverse;
+  }
+
+  @androidx.compose.runtime.Immutable public final class RepeatableSpec<T> implements androidx.compose.animation.core.FiniteAnimationSpec<T> {
+    ctor @Deprecated public RepeatableSpec(int iterations, androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    ctor public RepeatableSpec(int iterations, androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method public androidx.compose.animation.core.DurationBasedAnimationSpec<T> getAnimation();
+    method public long getInitialStartOffset();
+    method public int getIterations();
+    method public androidx.compose.animation.core.RepeatMode getRepeatMode();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final androidx.compose.animation.core.DurationBasedAnimationSpec<T> animation;
+    property public final long initialStartOffset;
+    property public final int iterations;
+    property public final androidx.compose.animation.core.RepeatMode repeatMode;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SnapSpec<T> implements androidx.compose.animation.core.DurationBasedAnimationSpec<T> {
+    ctor public SnapSpec(optional int delay);
+    method public int getDelay();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final int delay;
+  }
+
+  public final class Spring {
+    field public static final float DampingRatioHighBouncy = 0.2f;
+    field public static final float DampingRatioLowBouncy = 0.75f;
+    field public static final float DampingRatioMediumBouncy = 0.5f;
+    field public static final float DampingRatioNoBouncy = 1.0f;
+    field public static final float DefaultDisplacementThreshold = 0.01f;
+    field public static final androidx.compose.animation.core.Spring INSTANCE;
+    field public static final float StiffnessHigh = 10000.0f;
+    field public static final float StiffnessLow = 200.0f;
+    field public static final float StiffnessMedium = 1500.0f;
+    field public static final float StiffnessMediumLow = 400.0f;
+    field public static final float StiffnessVeryLow = 50.0f;
+  }
+
+  public final class SpringEstimationKt {
+  }
+
+  @androidx.compose.runtime.Immutable public final class SpringSpec<T> implements androidx.compose.animation.core.FiniteAnimationSpec<T> {
+    ctor public SpringSpec(optional float dampingRatio, optional float stiffness, optional T? visibilityThreshold);
+    method public float getDampingRatio();
+    method public float getStiffness();
+    method public T? getVisibilityThreshold();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedSpringSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final float dampingRatio;
+    property public final float stiffness;
+    property public final T? visibilityThreshold;
+  }
+
+  @kotlin.jvm.JvmInline public final value class StartOffset {
+    ctor public StartOffset(int offsetMillis, optional int offsetType);
+    method public int getOffsetMillis();
+    method public int getOffsetType();
+    property public final int offsetMillis;
+    property public final int offsetType;
+  }
+
+  @kotlin.jvm.JvmInline public final value class StartOffsetType {
+    field public static final androidx.compose.animation.core.StartOffsetType.Companion Companion;
+  }
+
+  public static final class StartOffsetType.Companion {
+    method public int getDelay();
+    method public int getFastForward();
+    property public final int Delay;
+    property public final int FastForward;
+  }
+
+  public final class SuspendAnimationKt {
+    method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animate(androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional T? initialVelocity, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, kotlin.jvm.functions.Function2<? super T,? super T,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? animate(float initialValue, float targetValue, optional float initialVelocity, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateDecay(androidx.compose.animation.core.AnimationState<T,V>, androidx.compose.animation.core.DecayAnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? animateDecay(float initialValue, float initialVelocity, androidx.compose.animation.core.FloatDecayAnimationSpec animationSpec, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend <T, V extends androidx.compose.animation.core.AnimationVector> Object? animateTo(androidx.compose.animation.core.AnimationState<T,V>, T targetValue, optional androidx.compose.animation.core.AnimationSpec<T> animationSpec, optional boolean sequentialAnimation, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.AnimationScope<T,V>,kotlin.Unit> block, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class TargetBasedAnimation<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.Animation<T,V> {
+    ctor public TargetBasedAnimation(androidx.compose.animation.core.AnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, T initialValue, T targetValue, optional V? initialVelocityVector);
+    method public long getDurationNanos();
+    method public T getInitialValue();
+    method public T getTargetValue();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValueFromNanos(long playTimeNanos);
+    method public V getVelocityVectorFromNanos(long playTimeNanos);
+    method public boolean isInfinite();
+    property public long durationNanos;
+    property public final T initialValue;
+    property public boolean isInfinite;
+    property public T targetValue;
+    property public androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+  }
+
+  @androidx.compose.runtime.Stable public final class Transition<S> {
+    method public java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<?,?>> getAnimations();
+    method public S getCurrentState();
+    method public String? getLabel();
+    method public androidx.compose.animation.core.Transition.Segment<S> getSegment();
+    method public S getTargetState();
+    method public long getTotalDurationNanos();
+    method public java.util.List<androidx.compose.animation.core.Transition<?>> getTransitions();
+    method public boolean isRunning();
+    property public final java.util.List<androidx.compose.animation.core.Transition<S>.TransitionAnimationState<?,?>> animations;
+    property public final S currentState;
+    property public final boolean isRunning;
+    property public final String? label;
+    property public final androidx.compose.animation.core.Transition.Segment<S> segment;
+    property public final S targetState;
+    property public final long totalDurationNanos;
+    property public final java.util.List<androidx.compose.animation.core.Transition<?>> transitions;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface Transition.Segment<S> {
+    method public S getInitialState();
+    method public S getTargetState();
+    method public default infix boolean isTransitioningTo(S, S targetState);
+    property public abstract S initialState;
+    property public abstract S targetState;
+  }
+
+  @androidx.compose.runtime.Stable public final class Transition.TransitionAnimationState<T, V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.runtime.State<T> {
+    method public androidx.compose.animation.core.TargetBasedAnimation<T,V> getAnimation();
+    method public androidx.compose.animation.core.FiniteAnimationSpec<T> getAnimationSpec();
+    method public String getLabel();
+    method public androidx.compose.animation.core.TwoWayConverter<T,V> getTypeConverter();
+    method public T getValue();
+    property public final androidx.compose.animation.core.TargetBasedAnimation<T,V> animation;
+    property public final androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec;
+    property public final String label;
+    property public final androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter;
+    property public T value;
+  }
+
+  public final class TransitionKt {
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> animateDp(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.Dp>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.Dp> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<java.lang.Float> animateFloat(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,java.lang.Float> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<java.lang.Integer> animateInt(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Integer>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,java.lang.Integer> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.IntOffset> animateIntOffset(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.IntOffset> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.unit.IntSize> animateIntSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.unit.IntSize> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Offset> animateOffset(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Offset>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Offset> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRect(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Rect>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Rect> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
+    method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
+    method @androidx.compose.animation.core.ExperimentalTransitionApi @androidx.compose.runtime.Composable public static inline <S, T> androidx.compose.animation.core.Transition<T> createChildTransition(androidx.compose.animation.core.Transition<S>, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> transformToChildState);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(T targetState, optional String? label);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TweenSpec<T> implements androidx.compose.animation.core.DurationBasedAnimationSpec<T> {
+    ctor public TweenSpec(optional int durationMillis, optional int delay, optional androidx.compose.animation.core.Easing easing);
+    method public int getDelay();
+    method public int getDurationMillis();
+    method public androidx.compose.animation.core.Easing getEasing();
+    method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedTweenSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
+    property public final int delay;
+    property public final int durationMillis;
+    property public final androidx.compose.animation.core.Easing easing;
+  }
+
+  public interface TwoWayConverter<T, V extends androidx.compose.animation.core.AnimationVector> {
+    method public kotlin.jvm.functions.Function1<V,T> getConvertFromVector();
+    method public kotlin.jvm.functions.Function1<T,V> getConvertToVector();
+    property public abstract kotlin.jvm.functions.Function1<V,T> convertFromVector;
+    property public abstract kotlin.jvm.functions.Function1<T,V> convertToVector;
+  }
+
+  public final class VectorConvertersKt {
+    method public static <T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.TwoWayConverter<T,V> TwoWayConverter(kotlin.jvm.functions.Function1<? super T,? extends V> convertToVector, kotlin.jvm.functions.Function1<? super V,? extends T> convertFromVector);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.geometry.Offset,androidx.compose.animation.core.AnimationVector2D> getVectorConverter(androidx.compose.ui.geometry.Offset.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.geometry.Rect,androidx.compose.animation.core.AnimationVector4D> getVectorConverter(androidx.compose.ui.geometry.Rect.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.geometry.Size,androidx.compose.animation.core.AnimationVector2D> getVectorConverter(androidx.compose.ui.geometry.Size.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.unit.Dp,androidx.compose.animation.core.AnimationVector1D> getVectorConverter(androidx.compose.ui.unit.Dp.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.unit.DpOffset,androidx.compose.animation.core.AnimationVector2D> getVectorConverter(androidx.compose.ui.unit.DpOffset.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.unit.IntOffset,androidx.compose.animation.core.AnimationVector2D> getVectorConverter(androidx.compose.ui.unit.IntOffset.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.unit.IntSize,androidx.compose.animation.core.AnimationVector2D> getVectorConverter(androidx.compose.ui.unit.IntSize.Companion);
+    method public static androidx.compose.animation.core.TwoWayConverter<java.lang.Float,androidx.compose.animation.core.AnimationVector1D> getVectorConverter(kotlin.jvm.internal.FloatCompanionObject);
+    method public static androidx.compose.animation.core.TwoWayConverter<java.lang.Integer,androidx.compose.animation.core.AnimationVector1D> getVectorConverter(kotlin.jvm.internal.IntCompanionObject);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorizedAnimationSpec<V extends androidx.compose.animation.core.AnimationVector> {
+    method public long getDurationNanos(V initialValue, V targetValue, V initialVelocity);
+    method public default V getEndVelocity(V initialValue, V targetValue, V initialVelocity);
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public boolean isInfinite();
+    property public abstract boolean isInfinite;
+  }
+
+  public interface VectorizedDecayAnimationSpec<V extends androidx.compose.animation.core.AnimationVector> {
+    method public float getAbsVelocityThreshold();
+    method public long getDurationNanos(V initialValue, V initialVelocity);
+    method public V getTargetValue(V initialValue, V initialVelocity);
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V initialVelocity);
+    property public abstract float absVelocityThreshold;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorizedDurationBasedAnimationSpec<V extends androidx.compose.animation.core.AnimationVector> extends androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> {
+    method public int getDelayMillis();
+    method public int getDurationMillis();
+    method public default long getDurationNanos(V initialValue, V targetValue, V initialVelocity);
+    property public abstract int delayMillis;
+    property public abstract int durationMillis;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorizedFiniteAnimationSpec<V extends androidx.compose.animation.core.AnimationVector> extends androidx.compose.animation.core.VectorizedAnimationSpec<V> {
+    method public default boolean isInfinite();
+    property public default boolean isInfinite;
+  }
+
+  public final class VectorizedFloatAnimationSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> {
+    ctor public VectorizedFloatAnimationSpec(androidx.compose.animation.core.FloatAnimationSpec anim);
+    method public long getDurationNanos(V initialValue, V targetValue, V initialVelocity);
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+  }
+
+  public final class VectorizedInfiniteRepeatableSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedAnimationSpec<V> {
+    ctor @Deprecated public VectorizedInfiniteRepeatableSpec(androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    ctor public VectorizedInfiniteRepeatableSpec(androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method public long getDurationNanos(V initialValue, V targetValue, V initialVelocity);
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public boolean isInfinite();
+    property public boolean isInfinite;
+  }
+
+  public final class VectorizedKeyframesSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> {
+    ctor public VectorizedKeyframesSpec(java.util.Map<java.lang.Integer,? extends kotlin.Pair<? extends V,? extends androidx.compose.animation.core.Easing>> keyframes, int durationMillis, optional int delayMillis);
+    method public int getDelayMillis();
+    method public int getDurationMillis();
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    property public int delayMillis;
+    property public int durationMillis;
+  }
+
+  public final class VectorizedRepeatableSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> {
+    ctor @Deprecated public VectorizedRepeatableSpec(int iterations, androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> animation, optional androidx.compose.animation.core.RepeatMode repeatMode);
+    ctor public VectorizedRepeatableSpec(int iterations, androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> animation, optional androidx.compose.animation.core.RepeatMode repeatMode, optional long initialStartOffset);
+    method public long getDurationNanos(V initialValue, V targetValue, V initialVelocity);
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+  }
+
+  public final class VectorizedSnapSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> {
+    ctor public VectorizedSnapSpec(optional int delayMillis);
+    method public int getDelayMillis();
+    method public int getDurationMillis();
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    property public int delayMillis;
+    property public int durationMillis;
+  }
+
+  public final class VectorizedSpringSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> {
+    ctor public VectorizedSpringSpec(optional float dampingRatio, optional float stiffness, optional V? visibilityThreshold);
+    method public float getDampingRatio();
+    method public float getStiffness();
+    property public final float dampingRatio;
+    property public final float stiffness;
+  }
+
+  public final class VectorizedTweenSpec<V extends androidx.compose.animation.core.AnimationVector> implements androidx.compose.animation.core.VectorizedDurationBasedAnimationSpec<V> {
+    ctor public VectorizedTweenSpec(optional int durationMillis, optional int delayMillis, optional androidx.compose.animation.core.Easing easing);
+    method public int getDelayMillis();
+    method public int getDurationMillis();
+    method public androidx.compose.animation.core.Easing getEasing();
+    method public V getValueFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    method public V getVelocityFromNanos(long playTimeNanos, V initialValue, V targetValue, V initialVelocity);
+    property public int delayMillis;
+    property public int durationMillis;
+    property public final androidx.compose.animation.core.Easing easing;
+  }
+
+  public final class VisibilityThresholdsKt {
+    method public static long getVisibilityThreshold(androidx.compose.ui.geometry.Offset.Companion);
+    method public static androidx.compose.ui.geometry.Rect getVisibilityThreshold(androidx.compose.ui.geometry.Rect.Companion);
+    method public static long getVisibilityThreshold(androidx.compose.ui.geometry.Size.Companion);
+    method public static float getVisibilityThreshold(androidx.compose.ui.unit.Dp.Companion);
+    method public static long getVisibilityThreshold(androidx.compose.ui.unit.DpOffset.Companion);
+    method public static long getVisibilityThreshold(androidx.compose.ui.unit.IntOffset.Companion);
+    method public static long getVisibilityThreshold(androidx.compose.ui.unit.IntSize.Companion);
+    method public static int getVisibilityThreshold(kotlin.jvm.internal.IntCompanionObject);
+  }
+
+}
+
diff --git a/compose/animation/animation-core/api/restricted_1.5.0-beta01.txt b/compose/animation/animation-core/api/restricted_1.5.0-beta01.txt
index b96faf7..0d3bd05 100644
--- a/compose/animation/animation-core/api/restricted_1.5.0-beta01.txt
+++ b/compose/animation/animation-core/api/restricted_1.5.0-beta01.txt
@@ -333,9 +333,6 @@
     property public static final androidx.compose.animation.core.Easing LinearOutSlowInEasing;
   }
 
-  @kotlin.RequiresOptIn(message="This is an experimental animation API for Transition. It may change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTransitionApi {
-  }
-
   public interface FiniteAnimationSpec<T> extends androidx.compose.animation.core.AnimationSpec<T> {
     method public <V extends androidx.compose.animation.core.AnimationVector> androidx.compose.animation.core.VectorizedFiniteAnimationSpec<V> vectorize(androidx.compose.animation.core.TwoWayConverter<T,V> converter);
   }
@@ -435,9 +432,6 @@
     method @androidx.compose.runtime.Composable public static androidx.compose.animation.core.InfiniteTransition rememberInfiniteTransition(optional String label);
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface InternalAnimationApi {
-  }
-
   @androidx.compose.runtime.Immutable public final class KeyframesSpec<T> implements androidx.compose.animation.core.DurationBasedAnimationSpec<T> {
     ctor public KeyframesSpec(androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> config);
     method public androidx.compose.animation.core.KeyframesSpec.KeyframesSpecConfig<T> getConfig();
@@ -622,7 +616,6 @@
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Rect> animateRect(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Rect>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Rect> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.geometry.Size> animateSize(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.geometry.Size>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.geometry.Size> targetValueByState);
     method @androidx.compose.runtime.Composable public static inline <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> animateValue(androidx.compose.animation.core.Transition<S>, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<T>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> targetValueByState);
-    method @androidx.compose.animation.core.ExperimentalTransitionApi @androidx.compose.runtime.Composable public static inline <S, T> androidx.compose.animation.core.Transition<T> createChildTransition(androidx.compose.animation.core.Transition<S>, optional String label, kotlin.jvm.functions.Function1<? super S,? extends T> transformToChildState);
     method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T> androidx.compose.animation.core.Transition<T> createChildTransitionInternal(androidx.compose.animation.core.Transition<S>, T initialState, T targetState, String childLabel);
     method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static <S, T, V extends androidx.compose.animation.core.AnimationVector> androidx.compose.runtime.State<T> createTransitionAnimation(androidx.compose.animation.core.Transition<S>, T initialValue, T targetValue, androidx.compose.animation.core.FiniteAnimationSpec<T> animationSpec, androidx.compose.animation.core.TwoWayConverter<T,V> typeConverter, String label);
     method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.Transition<T> updateTransition(androidx.compose.animation.core.MutableTransitionState<T> transitionState, optional String? label);
diff --git a/compose/animation/animation-core/build.gradle b/compose/animation/animation-core/build.gradle
index 4777d20..1af0fb2 100644
--- a/compose/animation/animation-core/build.gradle
+++ b/compose/animation/animation-core/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -30,6 +31,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/animation/animation-core/lint-baseline.xml b/compose/animation/animation-core/lint-baseline.xml
new file mode 100644
index 0000000..b433430
--- /dev/null
+++ b/compose/animation/animation-core/lint-baseline.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateFloatAsState has parameter &apos;finishedListener&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    finishedListener: ((Float) -> Unit)? = null"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateIntAsState has parameter &apos;finishedListener&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    finishedListener: ((Int) -> Unit)? = null"
+        errorLine2="                      ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateFloatAsState has parameter &apos;finishedListener&apos; with type Function1&lt;? super Float, ? extends Unit>."
+        errorLine1="    finishedListener: ((Float) -> Unit)? = null"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateIntAsState has parameter &apos;finishedListener&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    finishedListener: ((Int) -> Unit)? = null"
+        errorLine2="                      ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method withInfiniteAnimationFrameNanos has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="suspend fun &lt;R> withInfiniteAnimationFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R ="
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/InfiniteAnimationPolicy.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animate has parameter &apos;block&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="    block: (value: Float, velocity: Float) -> Unit"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateDecay has parameter &apos;block&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="    block: (value: Float, velocity: Float) -> Unit"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method callWithFrameNanos has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="    onFrame: (frameTimeNanos: Long) -> R"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
index e67068d..debf3c6 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/AnimateAsState.kt
@@ -65,7 +65,6 @@
     animationSpec: AnimationSpec<Float> = defaultAnimation,
     visibilityThreshold: Float = 0.01f,
     label: String = "FloatAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Float) -> Unit)? = null
 ): State<Float> {
     val resolvedAnimSpec =
@@ -111,7 +110,6 @@
     targetValue: Dp,
     animationSpec: AnimationSpec<Dp> = dpDefaultSpring,
     label: String = "DpAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Dp) -> Unit)? = null
 ): State<Dp> {
     return animateValueAsState(
@@ -153,7 +151,6 @@
     targetValue: Size,
     animationSpec: AnimationSpec<Size> = sizeDefaultSpring,
     label: String = "SizeAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Size) -> Unit)? = null
 ): State<Size> {
     return animateValueAsState(
@@ -194,7 +191,6 @@
     targetValue: Offset,
     animationSpec: AnimationSpec<Offset> = offsetDefaultSpring,
     label: String = "OffsetAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Offset) -> Unit)? = null
 ): State<Offset> {
     return animateValueAsState(
@@ -274,7 +270,6 @@
     targetValue: Int,
     animationSpec: AnimationSpec<Int> = intDefaultSpring,
     label: String = "IntAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Int) -> Unit)? = null
 ): State<Int> {
     return animateValueAsState(
@@ -315,7 +310,6 @@
     targetValue: IntOffset,
     animationSpec: AnimationSpec<IntOffset> = intOffsetDefaultSpring,
     label: String = "IntOffsetAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((IntOffset) -> Unit)? = null
 ): State<IntOffset> {
     return animateValueAsState(
@@ -354,7 +348,6 @@
     targetValue: IntSize,
     animationSpec: AnimationSpec<IntSize> = intSizeDefaultSpring,
     label: String = "IntSizeAnimation",
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((IntSize) -> Unit)? = null
 ): State<IntSize> {
     return animateValueAsState(
@@ -450,7 +443,6 @@
     targetValue: Float,
     animationSpec: AnimationSpec<Float> = defaultAnimation,
     visibilityThreshold: Float = 0.01f,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Float) -> Unit)? = null
 ): State<Float> = animateFloatAsState(
         targetValue,
@@ -467,7 +459,6 @@
 fun animateDpAsState(
     targetValue: Dp,
     animationSpec: AnimationSpec<Dp> = dpDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Dp) -> Unit)? = null
 ): State<Dp> {
     return animateValueAsState(
@@ -486,7 +477,6 @@
 fun animateSizeAsState(
     targetValue: Size,
     animationSpec: AnimationSpec<Size> = sizeDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Size) -> Unit)? = null
 ): State<Size> {
     return animateValueAsState(
@@ -505,7 +495,6 @@
 fun animateOffsetAsState(
     targetValue: Offset,
     animationSpec: AnimationSpec<Offset> = offsetDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Offset) -> Unit)? = null
 ): State<Offset> {
     return animateValueAsState(
@@ -536,7 +525,6 @@
 fun animateIntAsState(
     targetValue: Int,
     animationSpec: AnimationSpec<Int> = intDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((Int) -> Unit)? = null
 ): State<Int> {
     return animateValueAsState(
@@ -552,7 +540,6 @@
 fun animateIntOffsetAsState(
     targetValue: IntOffset,
     animationSpec: AnimationSpec<IntOffset> = intOffsetDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((IntOffset) -> Unit)? = null
 ): State<IntOffset> {
     return animateValueAsState(
@@ -568,7 +555,6 @@
 fun animateIntSizeAsState(
     targetValue: IntSize,
     animationSpec: AnimationSpec<IntSize> = intSizeDefaultSpring,
-    @Suppress("PrimitiveInLambda")
     finishedListener: ((IntSize) -> Unit)? = null
 ): State<IntSize> {
     return animateValueAsState(
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InfiniteAnimationPolicy.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InfiniteAnimationPolicy.kt
index 88ea9a3..930a05b 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InfiniteAnimationPolicy.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/InfiniteAnimationPolicy.kt
@@ -25,10 +25,7 @@
  * Like [withFrameNanos], but applies the [InfiniteAnimationPolicy] from the calling
  * [CoroutineContext] if there is one.
  */
-suspend fun <R> withInfiniteAnimationFrameNanos(
-    @Suppress("PrimitiveInLambda")
-    onFrame: (frameTimeNanos: Long) -> R
-): R =
+suspend fun <R> withInfiniteAnimationFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R =
     when (val policy = coroutineContext[InfiniteAnimationPolicy]) {
         null -> withFrameNanos(onFrame)
         else -> policy.onInfiniteOperation { withFrameNanos(onFrame) }
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt
index 3f8535c..8316bd1 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SuspendAnimation.kt
@@ -44,7 +44,6 @@
     targetValue: Float,
     initialVelocity: Float = 0f,
     animationSpec: AnimationSpec<Float> = spring(),
-    @Suppress("PrimitiveInLambda")
     block: (value: Float, velocity: Float) -> Unit
 ) {
     animate(
@@ -76,7 +75,6 @@
     initialValue: Float,
     initialVelocity: Float,
     animationSpec: FloatDecayAnimationSpec,
-    @Suppress("PrimitiveInLambda")
     block: (value: Float, velocity: Float) -> Unit
 ) {
     val anim = DecayAnimation(animationSpec, initialValue, initialVelocity)
@@ -297,7 +295,6 @@
  * variant of `withFrameNanos`, depending on the value of [Animation.isInfinite].
  */
 private suspend fun <R, T, V : AnimationVector> Animation<T, V>.callWithFrameNanos(
-    @Suppress("PrimitiveInLambda")
     onFrame: (frameTimeNanos: Long) -> R
 ): R {
     return if (isInfinite) {
diff --git a/compose/animation/animation-graphics/api/1.5.0-beta01.txt b/compose/animation/animation-graphics/api/1.5.0-beta01.txt
index cf4d086..e6f50d0 100644
--- a/compose/animation/animation-graphics/api/1.5.0-beta01.txt
+++ b/compose/animation/animation-graphics/api/1.5.0-beta01.txt
@@ -1,35 +1 @@
 // Signature format: 4.0
-package androidx.compose.animation.graphics {
-
-  @kotlin.RequiresOptIn(message="This is an experimental animation graphics API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface ExperimentalAnimationGraphicsApi {
-  }
-
-}
-
-package androidx.compose.animation.graphics.res {
-
-  public final class AnimatedVectorPainterResources_androidKt {
-    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.painter.Painter rememberAnimatedVectorPainter(androidx.compose.animation.graphics.vector.AnimatedImageVector animatedImageVector, boolean atEnd);
-  }
-
-  public final class AnimatedVectorResources_androidKt {
-    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.animation.graphics.vector.AnimatedImageVector animatedVectorResource(androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion, @DrawableRes int id);
-  }
-
-}
-
-package androidx.compose.animation.graphics.vector {
-
-  @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Immutable public final class AnimatedImageVector {
-    method public androidx.compose.ui.graphics.vector.ImageVector getImageVector();
-    method public int getTotalDuration();
-    property public final androidx.compose.ui.graphics.vector.ImageVector imageVector;
-    property public final int totalDuration;
-    field public static final androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion Companion;
-  }
-
-  public static final class AnimatedImageVector.Companion {
-  }
-
-}
-
diff --git a/compose/animation/animation-graphics/api/public_plus_experimental_1.5.0-beta01.txt b/compose/animation/animation-graphics/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..cf4d086
--- /dev/null
+++ b/compose/animation/animation-graphics/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.compose.animation.graphics {
+
+  @kotlin.RequiresOptIn(message="This is an experimental animation graphics API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface ExperimentalAnimationGraphicsApi {
+  }
+
+}
+
+package androidx.compose.animation.graphics.res {
+
+  public final class AnimatedVectorPainterResources_androidKt {
+    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.painter.Painter rememberAnimatedVectorPainter(androidx.compose.animation.graphics.vector.AnimatedImageVector animatedImageVector, boolean atEnd);
+  }
+
+  public final class AnimatedVectorResources_androidKt {
+    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.animation.graphics.vector.AnimatedImageVector animatedVectorResource(androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion, @DrawableRes int id);
+  }
+
+}
+
+package androidx.compose.animation.graphics.vector {
+
+  @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Immutable public final class AnimatedImageVector {
+    method public androidx.compose.ui.graphics.vector.ImageVector getImageVector();
+    method public int getTotalDuration();
+    property public final androidx.compose.ui.graphics.vector.ImageVector imageVector;
+    property public final int totalDuration;
+    field public static final androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion Companion;
+  }
+
+  public static final class AnimatedImageVector.Companion {
+  }
+
+}
+
diff --git a/compose/animation/animation-graphics/api/restricted_1.5.0-beta01.txt b/compose/animation/animation-graphics/api/restricted_1.5.0-beta01.txt
index cf4d086..e6f50d0 100644
--- a/compose/animation/animation-graphics/api/restricted_1.5.0-beta01.txt
+++ b/compose/animation/animation-graphics/api/restricted_1.5.0-beta01.txt
@@ -1,35 +1 @@
 // Signature format: 4.0
-package androidx.compose.animation.graphics {
-
-  @kotlin.RequiresOptIn(message="This is an experimental animation graphics API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface ExperimentalAnimationGraphicsApi {
-  }
-
-}
-
-package androidx.compose.animation.graphics.res {
-
-  public final class AnimatedVectorPainterResources_androidKt {
-    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.painter.Painter rememberAnimatedVectorPainter(androidx.compose.animation.graphics.vector.AnimatedImageVector animatedImageVector, boolean atEnd);
-  }
-
-  public final class AnimatedVectorResources_androidKt {
-    method @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Composable public static androidx.compose.animation.graphics.vector.AnimatedImageVector animatedVectorResource(androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion, @DrawableRes int id);
-  }
-
-}
-
-package androidx.compose.animation.graphics.vector {
-
-  @androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi @androidx.compose.runtime.Immutable public final class AnimatedImageVector {
-    method public androidx.compose.ui.graphics.vector.ImageVector getImageVector();
-    method public int getTotalDuration();
-    property public final androidx.compose.ui.graphics.vector.ImageVector imageVector;
-    property public final int totalDuration;
-    field public static final androidx.compose.animation.graphics.vector.AnimatedImageVector.Companion Companion;
-  }
-
-  public static final class AnimatedImageVector.Companion {
-  }
-
-}
-
diff --git a/compose/animation/animation-graphics/build.gradle b/compose/animation/animation-graphics/build.gradle
index bb4c4c1..dacdfee 100644
--- a/compose/animation/animation-graphics/build.gradle
+++ b/compose/animation/animation-graphics/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
@@ -31,6 +32,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/animation/animation-tooling-internal/api/public_plus_experimental_1.5.0-beta01.txt b/compose/animation/animation-tooling-internal/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..50e70a5
--- /dev/null
+++ b/compose/animation/animation-tooling-internal/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,57 @@
+// Signature format: 4.0
+package androidx.compose.animation.tooling {
+
+  public final class ComposeAnimatedProperty {
+    ctor public ComposeAnimatedProperty(String label, Object value);
+    method public String component1();
+    method public Object component2();
+    method public androidx.compose.animation.tooling.ComposeAnimatedProperty copy(String label, Object value);
+    method public String getLabel();
+    method public Object getValue();
+    property public final String label;
+    property public final Object value;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ComposeAnimation {
+    method public Object getAnimationObject();
+    method public default String? getLabel();
+    method public default java.util.Set<java.lang.Object> getStates();
+    method public androidx.compose.animation.tooling.ComposeAnimationType getType();
+    property public abstract Object animationObject;
+    property public default String? label;
+    property public default java.util.Set<java.lang.Object> states;
+    property public abstract androidx.compose.animation.tooling.ComposeAnimationType type;
+  }
+
+  public enum ComposeAnimationType {
+    method public static androidx.compose.animation.tooling.ComposeAnimationType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.animation.tooling.ComposeAnimationType[] values();
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATABLE;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATED_CONTENT;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATED_VALUE;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATED_VISIBILITY;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATE_CONTENT_SIZE;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType ANIMATE_X_AS_STATE;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType DECAY_ANIMATION;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType INFINITE_TRANSITION;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType TARGET_BASED_ANIMATION;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType TRANSITION_ANIMATION;
+    enum_constant public static final androidx.compose.animation.tooling.ComposeAnimationType UNSUPPORTED;
+  }
+
+  public final class TransitionInfo {
+    ctor public TransitionInfo(String label, String specType, long startTimeMillis, long endTimeMillis, java.util.Map<java.lang.Long,?> values);
+    method public long getEndTimeMillis();
+    method public String getLabel();
+    method public String getSpecType();
+    method public long getStartTimeMillis();
+    method public java.util.Map<java.lang.Long,java.lang.Object> getValues();
+    property public final long endTimeMillis;
+    property public final String label;
+    property public final String specType;
+    property public final long startTimeMillis;
+    property public final java.util.Map<java.lang.Long,java.lang.Object> values;
+  }
+
+}
+
diff --git a/compose/animation/animation/api/1.5.0-beta01.txt b/compose/animation/animation/api/1.5.0-beta01.txt
index 21baa95..f8122ac 100644
--- a/compose/animation/animation/api/1.5.0-beta01.txt
+++ b/compose/animation/animation/api/1.5.0-beta01.txt
@@ -10,7 +10,6 @@
     method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
     method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
     method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
-    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi public static infix androidx.compose.animation.ContentTransform with(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
   }
 
   public sealed interface AnimatedContentScope extends androidx.compose.animation.AnimatedVisibilityScope {
@@ -43,19 +42,14 @@
 
   public final class AnimatedVisibilityKt {
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void AnimatedVisibility(androidx.compose.animation.core.Transition<T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, androidx.compose.animation.EnterTransition enter, androidx.compose.animation.ExitTransition exit, boolean initiallyVisible, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface AnimatedVisibilityScope {
-    method @androidx.compose.animation.ExperimentalAnimationApi public default androidx.compose.ui.Modifier animateEnterExit(androidx.compose.ui.Modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label);
-    method @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> getTransition();
-    property @androidx.compose.animation.ExperimentalAnimationApi public abstract androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> transition;
   }
 
   public final class AnimationModifierKt {
@@ -80,19 +74,10 @@
   }
 
   public final class CrossfadeKt {
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void Crossfade(androidx.compose.animation.core.Transition<T>, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,?> contentKey, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
   }
 
-  @androidx.compose.animation.ExperimentalAnimationApi public enum EnterExitState {
-    method public static androidx.compose.animation.EnterExitState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.animation.EnterExitState[] values();
-    enum_constant public static final androidx.compose.animation.EnterExitState PostExit;
-    enum_constant public static final androidx.compose.animation.EnterExitState PreEnter;
-    enum_constant public static final androidx.compose.animation.EnterExitState Visible;
-  }
-
   public final class EnterExitTransitionKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Horizontal expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialWidth);
     method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandIn(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntSize> initialSize);
@@ -132,9 +117,6 @@
     property public final androidx.compose.animation.ExitTransition None;
   }
 
-  @kotlin.RequiresOptIn(message="This is an experimental animation API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalAnimationApi {
-  }
-
   public final class SingleValueAnimationKt {
     method public static androidx.compose.animation.core.Animatable<androidx.compose.ui.graphics.Color,androidx.compose.animation.core.AnimationVector4D> Animatable(long initialValue);
     method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColorAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.graphics.Color> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Color,kotlin.Unit>? finishedListener);
diff --git a/compose/animation/animation/api/public_plus_experimental_1.5.0-beta01.txt b/compose/animation/animation/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..21baa95
--- /dev/null
+++ b/compose/animation/animation/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,176 @@
+// Signature format: 4.0
+package androidx.compose.animation {
+
+  public final class AndroidActualDefaultDecayAnimationSpec_androidKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> defaultDecayAnimationSpec();
+  }
+
+  public final class AnimatedContentKt {
+    method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(androidx.compose.animation.core.Transition<S>, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
+    method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
+    method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
+    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi public static infix androidx.compose.animation.ContentTransform with(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
+  }
+
+  public sealed interface AnimatedContentScope extends androidx.compose.animation.AnimatedVisibilityScope {
+  }
+
+  public sealed interface AnimatedContentTransitionScope<S> extends androidx.compose.animation.core.Transition.Segment<S> {
+    method public androidx.compose.animation.EnterTransition slideIntoContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialOffset);
+    method public androidx.compose.animation.ExitTransition slideOutOfContainer(int towards, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetOffset);
+    method public infix androidx.compose.animation.ContentTransform using(androidx.compose.animation.ContentTransform, androidx.compose.animation.SizeTransform? sizeTransform);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public static final value class AnimatedContentTransitionScope.SlideDirection {
+    field public static final androidx.compose.animation.AnimatedContentTransitionScope.SlideDirection.Companion Companion;
+  }
+
+  public static final class AnimatedContentTransitionScope.SlideDirection.Companion {
+    method public int getDown();
+    method public int getEnd();
+    method public int getLeft();
+    method public int getRight();
+    method public int getStart();
+    method public int getUp();
+    property public final int Down;
+    property public final int End;
+    property public final int Left;
+    property public final int Right;
+    property public final int Start;
+    property public final int Up;
+  }
+
+  public final class AnimatedVisibilityKt {
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void AnimatedVisibility(androidx.compose.animation.core.Transition<T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, androidx.compose.animation.EnterTransition enter, androidx.compose.animation.ExitTransition exit, boolean initiallyVisible, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface AnimatedVisibilityScope {
+    method @androidx.compose.animation.ExperimentalAnimationApi public default androidx.compose.ui.Modifier animateEnterExit(androidx.compose.ui.Modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label);
+    method @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> getTransition();
+    property @androidx.compose.animation.ExperimentalAnimationApi public abstract androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> transition;
+  }
+
+  public final class AnimationModifierKt {
+    method public static androidx.compose.ui.Modifier animateContentSize(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,kotlin.Unit>? finishedListener);
+  }
+
+  public final class ColorVectorConverterKt {
+    method public static kotlin.jvm.functions.Function1<androidx.compose.ui.graphics.colorspace.ColorSpace,androidx.compose.animation.core.TwoWayConverter<androidx.compose.ui.graphics.Color,androidx.compose.animation.core.AnimationVector4D>> getVectorConverter(androidx.compose.ui.graphics.Color.Companion);
+  }
+
+  public final class ContentTransform {
+    ctor public ContentTransform(androidx.compose.animation.EnterTransition targetContentEnter, androidx.compose.animation.ExitTransition initialContentExit, optional float targetContentZIndex, optional androidx.compose.animation.SizeTransform? sizeTransform);
+    method public androidx.compose.animation.ExitTransition getInitialContentExit();
+    method public androidx.compose.animation.SizeTransform? getSizeTransform();
+    method public androidx.compose.animation.EnterTransition getTargetContentEnter();
+    method public float getTargetContentZIndex();
+    method public void setTargetContentZIndex(float);
+    property public final androidx.compose.animation.ExitTransition initialContentExit;
+    property public final androidx.compose.animation.SizeTransform? sizeTransform;
+    property public final androidx.compose.animation.EnterTransition targetContentEnter;
+    property public final float targetContentZIndex;
+  }
+
+  public final class CrossfadeKt {
+    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void Crossfade(androidx.compose.animation.core.Transition<T>, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,?> contentKey, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
+  }
+
+  @androidx.compose.animation.ExperimentalAnimationApi public enum EnterExitState {
+    method public static androidx.compose.animation.EnterExitState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.animation.EnterExitState[] values();
+    enum_constant public static final androidx.compose.animation.EnterExitState PostExit;
+    enum_constant public static final androidx.compose.animation.EnterExitState PreEnter;
+    enum_constant public static final androidx.compose.animation.EnterExitState Visible;
+  }
+
+  public final class EnterExitTransitionKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Horizontal expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialWidth);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandIn(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntSize> initialSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandVertically(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Vertical expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialHeight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition fadeIn(optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional float initialAlpha);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition fadeOut(optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional float targetAlpha);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition scaleIn(optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional float initialScale, optional long transformOrigin);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition scaleOut(optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional float targetScale, optional long transformOrigin);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition shrinkHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Horizontal shrinkTowards, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetWidth);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition shrinkOut(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment shrinkTowards, optional boolean clip, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntSize> targetSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition shrinkVertically(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Vertical shrinkTowards, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetHeight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition slideIn(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntOffset> initialOffset);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition slideInHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialOffsetX);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition slideInVertically(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialOffsetY);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition slideOut(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntOffset> targetOffset);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition slideOutHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetOffsetX);
+    method @androidx.compose.runtime.Stable public static androidx.compose.animation.ExitTransition slideOutVertically(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> targetOffsetY);
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class EnterTransition {
+    method @androidx.compose.runtime.Stable public final operator androidx.compose.animation.EnterTransition plus(androidx.compose.animation.EnterTransition enter);
+    field public static final androidx.compose.animation.EnterTransition.Companion Companion;
+  }
+
+  public static final class EnterTransition.Companion {
+    method public androidx.compose.animation.EnterTransition getNone();
+    property public final androidx.compose.animation.EnterTransition None;
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class ExitTransition {
+    method @androidx.compose.runtime.Stable public final operator androidx.compose.animation.ExitTransition plus(androidx.compose.animation.ExitTransition exit);
+    field public static final androidx.compose.animation.ExitTransition.Companion Companion;
+  }
+
+  public static final class ExitTransition.Companion {
+    method public androidx.compose.animation.ExitTransition getNone();
+    property public final androidx.compose.animation.ExitTransition None;
+  }
+
+  @kotlin.RequiresOptIn(message="This is an experimental animation API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalAnimationApi {
+  }
+
+  public final class SingleValueAnimationKt {
+    method public static androidx.compose.animation.core.Animatable<androidx.compose.ui.graphics.Color,androidx.compose.animation.core.AnimationVector4D> Animatable(long initialValue);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColorAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.graphics.Color> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Color,kotlin.Unit>? finishedListener);
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColorAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.graphics.Color> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Color,kotlin.Unit>? finishedListener);
+  }
+
+  public interface SizeTransform {
+    method public androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> createAnimationSpec(long initialSize, long targetSize);
+    method public boolean getClip();
+    property public abstract boolean clip;
+  }
+
+  public final class SplineBasedDecayKt {
+    method public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> splineBasedDecay(androidx.compose.ui.unit.Density density);
+  }
+
+  public final class SplineBasedFloatDecayAnimationSpec implements androidx.compose.animation.core.FloatDecayAnimationSpec {
+    ctor public SplineBasedFloatDecayAnimationSpec(androidx.compose.ui.unit.Density density);
+    method public float getAbsVelocityThreshold();
+    method public long getDurationNanos(float initialValue, float initialVelocity);
+    method public float getTargetValue(float initialValue, float initialVelocity);
+    method public float getValueFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    method public float getVelocityFromNanos(long playTimeNanos, float initialValue, float initialVelocity);
+    property public float absVelocityThreshold;
+  }
+
+  public final class SplineBasedFloatDecayAnimationSpec_androidKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> rememberSplineBasedDecay();
+    method @Deprecated public static <T> androidx.compose.animation.core.DecayAnimationSpec<T> splineBasedDecay(androidx.compose.ui.unit.Density density);
+  }
+
+  public final class TransitionKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColor(androidx.compose.animation.core.InfiniteTransition, long initialValue, long targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<androidx.compose.ui.graphics.Color> animationSpec);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColor(androidx.compose.animation.core.InfiniteTransition, long initialValue, long targetValue, androidx.compose.animation.core.InfiniteRepeatableSpec<androidx.compose.ui.graphics.Color> animationSpec, optional String label);
+    method @androidx.compose.runtime.Composable public static inline <S> androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColor(androidx.compose.animation.core.Transition<S>, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.core.Transition.Segment<S>,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.graphics.Color>> transitionSpec, optional String label, kotlin.jvm.functions.Function1<? super S,androidx.compose.ui.graphics.Color> targetValueByState);
+  }
+
+}
+
diff --git a/compose/animation/animation/api/restricted_1.5.0-beta01.txt b/compose/animation/animation/api/restricted_1.5.0-beta01.txt
index 21baa95..f8122ac 100644
--- a/compose/animation/animation/api/restricted_1.5.0-beta01.txt
+++ b/compose/animation/animation/api/restricted_1.5.0-beta01.txt
@@ -10,7 +10,6 @@
     method @androidx.compose.runtime.Composable public static <S> void AnimatedContent(S targetState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<S>,androidx.compose.animation.ContentTransform> transitionSpec, optional androidx.compose.ui.Alignment contentAlignment, optional String label, optional kotlin.jvm.functions.Function1<? super S,?> contentKey, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super S,kotlin.Unit> content);
     method public static androidx.compose.animation.SizeTransform SizeTransform(optional boolean clip, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.IntSize,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize>> sizeAnimationSpec);
     method public static infix androidx.compose.animation.ContentTransform togetherWith(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
-    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi public static infix androidx.compose.animation.ContentTransform with(androidx.compose.animation.EnterTransition, androidx.compose.animation.ExitTransition exit);
   }
 
   public sealed interface AnimatedContentScope extends androidx.compose.animation.AnimatedVisibilityScope {
@@ -43,19 +42,14 @@
 
   public final class AnimatedVisibilityKt {
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void AnimatedVisibility(androidx.compose.animation.core.Transition<T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.ColumnScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> visibleState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(androidx.compose.foundation.layout.RowScope, boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
-    method @Deprecated @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, androidx.compose.animation.EnterTransition enter, androidx.compose.animation.ExitTransition exit, boolean initiallyVisible, kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static void AnimatedVisibility(boolean visible, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label, kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedVisibilityScope,kotlin.Unit> content);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface AnimatedVisibilityScope {
-    method @androidx.compose.animation.ExperimentalAnimationApi public default androidx.compose.ui.Modifier animateEnterExit(androidx.compose.ui.Modifier, optional androidx.compose.animation.EnterTransition enter, optional androidx.compose.animation.ExitTransition exit, optional String label);
-    method @androidx.compose.animation.ExperimentalAnimationApi public androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> getTransition();
-    property @androidx.compose.animation.ExperimentalAnimationApi public abstract androidx.compose.animation.core.Transition<androidx.compose.animation.EnterExitState> transition;
   }
 
   public final class AnimationModifierKt {
@@ -80,19 +74,10 @@
   }
 
   public final class CrossfadeKt {
-    method @androidx.compose.animation.ExperimentalAnimationApi @androidx.compose.runtime.Composable public static <T> void Crossfade(androidx.compose.animation.core.Transition<T>, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,?> contentKey, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, optional String label, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
     method @Deprecated @androidx.compose.runtime.Composable public static <T> void Crossfade(T targetState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> content);
   }
 
-  @androidx.compose.animation.ExperimentalAnimationApi public enum EnterExitState {
-    method public static androidx.compose.animation.EnterExitState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.animation.EnterExitState[] values();
-    enum_constant public static final androidx.compose.animation.EnterExitState PostExit;
-    enum_constant public static final androidx.compose.animation.EnterExitState PreEnter;
-    enum_constant public static final androidx.compose.animation.EnterExitState Visible;
-  }
-
   public final class EnterExitTransitionKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandHorizontally(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment.Horizontal expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Integer> initialWidth);
     method @androidx.compose.runtime.Stable public static androidx.compose.animation.EnterTransition expandIn(optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntSize> animationSpec, optional androidx.compose.ui.Alignment expandFrom, optional boolean clip, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,androidx.compose.ui.unit.IntSize> initialSize);
@@ -132,9 +117,6 @@
     property public final androidx.compose.animation.ExitTransition None;
   }
 
-  @kotlin.RequiresOptIn(message="This is an experimental animation API.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FIELD, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalAnimationApi {
-  }
-
   public final class SingleValueAnimationKt {
     method public static androidx.compose.animation.core.Animatable<androidx.compose.ui.graphics.Color,androidx.compose.animation.core.AnimationVector4D> Animatable(long initialValue);
     method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> animateColorAsState(long targetValue, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.graphics.Color> animationSpec, optional String label, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Color,kotlin.Unit>? finishedListener);
diff --git a/compose/animation/animation/build.gradle b/compose/animation/animation/build.gradle
index f2b4f811..944db36 100644
--- a/compose/animation/animation/build.gradle
+++ b/compose/animation/animation/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml b/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml
new file mode 100644
index 0000000..ad509bc
--- /dev/null
+++ b/compose/animation/animation/integration-tests/animation-demos/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;onOptionSelected&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="        val onOptionSelected: (Int) -> Unit = remember {"
+        errorLine2="                              ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method TransitionOptions has parameter &apos;onOptionSelected&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="fun TransitionOptions(selectedOptions: List&lt;Boolean>, onOptionSelected: (Int) -> Unit) {"
+        errorLine2="                                                                        ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/AnimationDemos.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/AnimationDemos.kt
index 434a88d..9350274 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/AnimationDemos.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/AnimationDemos.kt
@@ -44,6 +44,7 @@
 import androidx.compose.animation.demos.lookahead.LookaheadWithDisappearingMovableContentDemo
 import androidx.compose.animation.demos.lookahead.LookaheadWithFlowRowDemo
 import androidx.compose.animation.demos.lookahead.LookaheadWithIntrinsicsDemo
+import androidx.compose.animation.demos.lookahead.LookaheadWithLazyColumn
 import androidx.compose.animation.demos.lookahead.LookaheadWithMovableContentDemo
 import androidx.compose.animation.demos.lookahead.LookaheadWithScaffold
 import androidx.compose.animation.demos.lookahead.LookaheadWithSubcompose
@@ -126,6 +127,7 @@
                     LookaheadWithBoxWithConstraints()
                 },
                 ComposableDemo("Lookahead With Subcompose") { LookaheadWithSubcompose() },
+                ComposableDemo("Lookahead With LazyColumn") { LookaheadWithLazyColumn() },
                 ComposableDemo("Lookahead With Flow Row") { LookaheadWithFlowRowDemo() },
                 ComposableDemo("Lookahead With Intrinsics") {
                     LookaheadWithIntrinsicsDemo()
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithAnimateItemPlacement.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithAnimateItemPlacement.kt
new file mode 100644
index 0000000..493556a
--- /dev/null
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithAnimateItemPlacement.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.animation.demos.lookahead
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.demos.layoutanimation.turquoiseColors
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.produceState
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.LookaheadScope
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import kotlinx.coroutines.delay
+
+@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
+@Preview
+@Composable
+fun LookaheadWithLAnimateItemPlacement() {
+    val visible by produceState(true) {
+        while (true) {
+            delay(2000)
+            value = !value
+        }
+    }
+    LookaheadScope {
+        LazyColumn(Modifier.padding(20.dp)) {
+            items(3, key = { it }) {
+                Column(
+                    Modifier
+                        .animateItemPlacement()
+                        .clip(RoundedCornerShape(15.dp))
+                        .background(turquoiseColors[it])
+
+                ) {
+                    Box(
+                        Modifier
+                            .requiredHeight(ItemSize.dp)
+                            .fillMaxWidth()
+                    )
+                    AnimatedVisibility(visible = visible) {
+                        Box(
+                            Modifier
+                                .requiredHeight(ItemSize.dp)
+                                .fillMaxWidth()
+                                .background(Color.White)
+                        )
+                    }
+                }
+            }
+        }
+    }
+}
+
+@Suppress("ConstPropertyName")
+private const val ItemSize = 100
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithLazyColumn.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithLazyColumn.kt
new file mode 100644
index 0000000..8fdbd52
--- /dev/null
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithLazyColumn.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ */
+
+@file:OptIn(ExperimentalComposeUiApi::class)
+
+package androidx.compose.animation.demos.lookahead
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.spring
+import androidx.compose.animation.demos.R
+import androidx.compose.animation.demos.gesture.pastelColors
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.slideInHorizontally
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.movableContentOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.layout.LookaheadScope
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+
+@Preview
+@Composable
+fun LookaheadWithLazyColumn() {
+    LookaheadScope {
+        LazyColumn {
+            items(10, key = { it }) {
+                val index = it % 4
+                var expanded by rememberSaveable { mutableStateOf(false) }
+                AnimatedVisibility(
+                    remember { MutableTransitionState(false) }
+                        .apply { targetState = true },
+                    enter = slideInHorizontally { 20 } + fadeIn()
+                ) {
+                    Surface(shape = RoundedCornerShape(10.dp),
+                        color = pastelColors[index],
+                        modifier = Modifier
+                            .fillMaxWidth()
+                            .clickable {
+                                expanded = !expanded
+                            }) {
+                        LookaheadScope {
+                            val title = remember {
+                                movableContentOf {
+                                    Text(
+                                        names[index],
+                                        Modifier
+                                            .padding(20.dp)
+                                            .animateBounds(Modifier)
+                                    )
+                                }
+                            }
+                            val image = remember {
+                                if (index < 3) {
+                                    movableContentOf {
+                                        Image(
+                                            painter = painterResource(res[index]),
+                                            contentDescription = null,
+                                            modifier = Modifier
+                                                .padding(10.dp)
+                                                .animateBounds(
+                                                    if (expanded)
+                                                        Modifier.fillMaxWidth()
+                                                    else
+                                                        Modifier.size(80.dp),
+                                                    spring(stiffness = Spring.StiffnessLow)
+                                                )
+                                                .clip(RoundedCornerShape(5.dp)),
+                                            contentScale = if (expanded) {
+                                                ContentScale.FillWidth
+                                            } else {
+                                                ContentScale.Crop
+                                            }
+                                        )
+                                    }
+                                } else {
+                                    movableContentOf {
+                                        Box(
+                                            modifier = Modifier
+                                                .padding(10.dp)
+                                                .animateBounds(
+                                                    if (expanded) Modifier
+                                                        .fillMaxWidth()
+                                                        .aspectRatio(1f)
+                                                    else Modifier.size(80.dp),
+                                                    spring(stiffness = Spring.StiffnessLow)
+                                                )
+                                                .background(
+                                                    Color.LightGray, RoundedCornerShape(5.dp)
+                                                ),
+                                        )
+                                    }
+                                }
+                            }
+                            if (expanded) {
+                                Column {
+                                    title()
+                                    image()
+                                }
+                            } else {
+                                Row {
+                                    image()
+                                    title()
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+val names = listOf("YT", "Pepper", "Waffle", "Who?")
+val res = listOf(
+    R.drawable.yt_profile,
+    R.drawable.pepper,
+    R.drawable.waffle,
+)
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt
index 9717338..b39fd18 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/EnterExitCombination.kt
@@ -88,7 +88,6 @@
         var alignment by remember { mutableStateOf(TopStart) }
         var visible by remember { mutableStateOf(true) }
         val selectedOptions = remember { mutableStateListOf(false, true, false) }
-        @Suppress("PrimitiveInLambda")
         val onOptionSelected: (Int) -> Unit = remember {
             { selectedOptions[it] = !selectedOptions[it] }
         }
@@ -291,11 +290,7 @@
 }
 
 @Composable
-fun TransitionOptions(
-    selectedOptions: List<Boolean>,
-    @Suppress("PrimitiveInLambda")
-    onOptionSelected: (Int) -> Unit
-) {
+fun TransitionOptions(selectedOptions: List<Boolean>, onOptionSelected: (Int) -> Unit) {
     Column {
         val radioOptions =
             listOf("Fade", "Expand/Shrink", "Slide")
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/pepper.jpg b/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/pepper.jpg
new file mode 100644
index 0000000..1aa03c5
--- /dev/null
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/pepper.jpg
Binary files differ
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/waffle.jpeg b/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/waffle.jpeg
new file mode 100644
index 0000000..194b4e5
--- /dev/null
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/res/drawable/waffle.jpeg
Binary files differ
diff --git a/compose/animation/animation/lint-baseline.xml b/compose/animation/animation/lint-baseline.xml
new file mode 100644
index 0000000..dae5876
--- /dev/null
+++ b/compose/animation/animation/lint-baseline.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="cli" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideIntoContainer has parameter &apos;initialOffset&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="        initialOffset: (offsetForFullSlide: Int) -> Int = { it }"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideOutOfContainer has parameter &apos;targetOffset&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="        targetOffset: (offsetForFullSlide: Int) -> Int = { it }"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method expandHorizontally has parameter &apos;initialWidth&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    initialWidth: (fullWidth: Int) -> Int = { 0 },"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method expandVertically has parameter &apos;initialHeight&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    initialHeight: (fullHeight: Int) -> Int = { 0 },"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method shrinkHorizontally has parameter &apos;targetWidth&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    targetWidth: (fullWidth: Int) -> Int = { 0 }"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method shrinkVertically has parameter &apos;targetHeight&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    targetHeight: (fullHeight: Int) -> Int = { 0 },"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideInHorizontally has parameter &apos;initialOffsetX&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    initialOffsetX: (fullWidth: Int) -> Int = { -it / 2 },"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideInVertically has parameter &apos;initialOffsetY&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    initialOffsetY: (fullHeight: Int) -> Int = { -it / 2 },"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideOutHorizontally has parameter &apos;targetOffsetX&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    targetOffsetX: (fullWidth: Int) -> Int = { -it / 2 },"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method slideOutVertically has parameter &apos;targetOffsetY&apos; with type Function1&lt;? super Integer, Integer>."
+        errorLine1="    targetOffsetY: (fullHeight: Int) -> Int = { -it / 2 },"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
index fecb344..d1ac4ac 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
@@ -349,7 +349,6 @@
         animationSpec: FiniteAnimationSpec<IntOffset> = spring(
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-        @Suppress("PrimitiveInLambda")
         initialOffset: (offsetForFullSlide: Int) -> Int = { it }
     ): EnterTransition
 
@@ -379,7 +378,6 @@
         animationSpec: FiniteAnimationSpec<IntOffset> = spring(
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-        @Suppress("PrimitiveInLambda")
         targetOffset: (offsetForFullSlide: Int) -> Int = { it }
     ): ExitTransition
 }
@@ -440,7 +438,6 @@
     override fun slideIntoContainer(
         towards: AnimatedContentTransitionScope.SlideDirection,
         animationSpec: FiniteAnimationSpec<IntOffset>,
-        @Suppress("PrimitiveInLambda")
         initialOffset: (offsetForFullSlide: Int) -> Int
     ): EnterTransition =
         when {
@@ -510,7 +507,6 @@
     override fun slideOutOfContainer(
         towards: AnimatedContentTransitionScope.SlideDirection,
         animationSpec: FiniteAnimationSpec<IntOffset>,
-        @Suppress("PrimitiveInLambda")
         targetOffset: (offsetForFullSlide: Int) -> Int
     ): ExitTransition {
         return when {
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
index 035d8aa..3db5a76 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
@@ -40,9 +40,9 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.graphics.GraphicsLayerScope
 import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
@@ -513,7 +513,6 @@
         ),
     expandFrom: Alignment.Horizontal = Alignment.End,
     clip: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     initialWidth: (fullWidth: Int) -> Int = { 0 },
 ): EnterTransition {
     return expandIn(animationSpec, expandFrom.toAlignment(), clip = clip) {
@@ -553,7 +552,6 @@
         ),
     expandFrom: Alignment.Vertical = Alignment.Bottom,
     clip: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     initialHeight: (fullHeight: Int) -> Int = { 0 },
 ): EnterTransition {
     return expandIn(animationSpec, expandFrom.toAlignment(), clip) {
@@ -593,7 +591,6 @@
         ),
     shrinkTowards: Alignment.Horizontal = Alignment.End,
     clip: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     targetWidth: (fullWidth: Int) -> Int = { 0 }
 ): ExitTransition {
     // TODO: Support different animation types
@@ -634,7 +631,6 @@
         ),
     shrinkTowards: Alignment.Vertical = Alignment.Bottom,
     clip: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     targetHeight: (fullHeight: Int) -> Int = { 0 },
 ): ExitTransition {
     // TODO: Support different animation types
@@ -667,7 +663,6 @@
             stiffness = Spring.StiffnessMediumLow,
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-    @Suppress("PrimitiveInLambda")
     initialOffsetX: (fullWidth: Int) -> Int = { -it / 2 },
 ): EnterTransition =
     slideIn(
@@ -699,7 +694,6 @@
             stiffness = Spring.StiffnessMediumLow,
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-    @Suppress("PrimitiveInLambda")
     initialOffsetY: (fullHeight: Int) -> Int = { -it / 2 },
 ): EnterTransition =
     slideIn(
@@ -731,7 +725,6 @@
             stiffness = Spring.StiffnessMediumLow,
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-    @Suppress("PrimitiveInLambda")
     targetOffsetX: (fullWidth: Int) -> Int = { -it / 2 },
 ): ExitTransition =
     slideOut(
@@ -761,7 +754,6 @@
             stiffness = Spring.StiffnessMediumLow,
             visibilityThreshold = IntOffset.VisibilityThreshold
         ),
-    @Suppress("PrimitiveInLambda")
     targetOffsetY: (fullHeight: Int) -> Int = { -it / 2 },
 ): ExitTransition =
     slideOut(
@@ -864,7 +856,8 @@
 
     val graphicsLayerBlock = createGraphicsLayerBlock(enter, exit, label)
 
-    return (if (disableClip) Modifier else Modifier.clipToBounds())
+    return Modifier
+        .graphicsLayer(clip = !disableClip)
         .then(
             EnterExitTransitionElement(
                 this, sizeAnimation, offsetAnimation, slideAnimation,
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionalInterfaceExtensionReceiverTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionalInterfaceExtensionReceiverTransformTests.kt
new file mode 100644
index 0000000..86c1eaa
--- /dev/null
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FunctionalInterfaceExtensionReceiverTransformTests.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.compiler.plugins.kotlin
+
+import org.junit.Test
+
+class FunctionalInterfaceExtensionReceiverTransformTests : AbstractControlFlowTransformTests() {
+    @Test
+    fun testFunctionalInterfaceWithExtensionReceiverTransformation() {
+        verifyComposeIrTransform(
+            source = """
+                import androidx.compose.runtime.*
+                fun interface TestContent {
+                    @Composable
+                    fun String.Content()
+                }
+                @Composable
+                fun Test(content: TestContent) {
+                    with(content) {
+                        "".Content()
+                    }
+                }
+
+                @Composable
+                fun CallTest() {
+                    Test { this.length }
+                }
+            """.trimIndent(),
+            expectedTransformed = """
+            interface TestContent {
+              @Composable
+              abstract fun String.Content(%composer: Composer?, %changed: Int)
+            }
+            @Composable
+            @ComposableInferredTarget(scheme = "[0[0]]")
+            fun Test(content: TestContent, %composer: Composer?, %changed: Int) {
+              %composer = %composer.startRestartGroup(<>)
+              sourceInformation(%composer, "C(Test)*<Conten...>:Test.kt")
+              val %dirty = %changed
+              if (%changed and 0b1110 === 0) {
+                %dirty = %dirty or if (%composer.changed(content)) 0b0100 else 0b0010
+              }
+              if (%dirty and 0b1011 !== 0b0010 || !%composer.skipping) {
+                if (isTraceInProgress()) {
+                  traceEventStart(<>, %changed, -1, <>)
+                }
+                with(content) {
+                  %this%with.Content(%composer, 0b0110)
+                }
+                if (isTraceInProgress()) {
+                  traceEventEnd()
+                }
+              } else {
+                %composer.skipToGroupEnd()
+              }
+              %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+                Test(content, %composer, updateChangedFlags(%changed or 0b0001))
+              }
+            }
+            @Composable
+            fun CallTest(%composer: Composer?, %changed: Int) {
+              %composer = %composer.startRestartGroup(<>)
+              sourceInformation(%composer, "C(CallTest)<Test>:Test.kt")
+              if (%changed !== 0 || !%composer.skipping) {
+                if (isTraceInProgress()) {
+                  traceEventStart(<>, %changed, -1, <>)
+                }
+                Test(class <no name provided> : TestContent {
+                  @Composable
+                  override fun Content(%this%Test: String, %composer: Composer?, %changed: Int) {
+                    %composer = %composer.startRestartGroup(<>)
+                    sourceInformation(%composer, "C(Content):Test.kt")
+                    val %dirty = %changed
+                    if (%changed and 0b1110 === 0) {
+                      %dirty = %dirty or if (%composer.changed(%this%Test)) 0b0100 else 0b0010
+                    }
+                    if (%dirty and 0b1011 !== 0b0010 || !%composer.skipping) {
+                      if (isTraceInProgress()) {
+                        traceEventStart(<>, %changed, -1, <>)
+                      }
+                      %this%Test.length
+                      if (isTraceInProgress()) {
+                        traceEventEnd()
+                      }
+                    } else {
+                      %composer.skipToGroupEnd()
+                    }
+                    val tmp0_rcvr = <this>
+                    %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+                      tmp0_rcvr.Content(%this%Test, %composer, updateChangedFlags(%changed or 0b0001))
+                    }
+                  }
+                }
+                <no name provided>(), %composer, 0)
+                if (isTraceInProgress()) {
+                  traceEventEnd()
+                }
+              } else {
+                %composer.skipToGroupEnd()
+              }
+              %composer.endRestartGroup()?.updateScope { %composer: Composer?, %force: Int ->
+                CallTest(%composer, updateChangedFlags(%changed or 0b0001))
+              }
+            }
+            """.trimIndent()
+        )
+    }
+}
\ No newline at end of file
diff --git a/compose/compiler/compiler-hosted/lint-baseline.xml b/compose/compiler/compiler-hosted/lint-baseline.xml
deleted file mode 100644
index bf73059..0000000
--- a/compose/compiler/compiler-hosted/lint-baseline.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="LintError"
-        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: Could not read file: /media/workspace/android/androidx-main/prebuilts/androidx/external/org/jetbrains/kotlin/kotlin-compiler/1.8.10/kotlin-compiler-1.8.10.jar!/org/jetbrains/kotlin/ir/expressions/impl/IrSetFieldImpl.class; size in bytes: 5423; file type: CLASS&#xA;Stack: `IllegalStateException:VirtualFileKotlinClass$Factory.logFileReadingErrorMessage(VirtualFileKotlinClass.kt:77)←VirtualFileKotlinClass$Factory.access$logFileReadingErrorMessage(VirtualFileKotlinClass.kt:46)←VirtualFileKotlinClass$Factory$create$1.invoke(VirtualFileKotlinClass.kt:68)←VirtualFileKotlinClass$Factory$create$1.invoke(VirtualFileKotlinClass.kt:51)←PerformanceCounter.time(PerformanceCounter.kt:90)←VirtualFileKotlinClass$Factory.create$frontend_common_jvm(VirtualFileKotlinClass.kt:51)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent$lambda$0(KotlinBinaryClassCache.kt:90)←MockApplication.runReadAction(MockApplication.java:193)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent(KotlinBinaryClassCache.kt:89)←KotlinBinaryClassCache$Companion.getKotlinBinaryClassOrClassFileContent$default(KotlinBinaryClassCache.kt:73)←VirtualFileFinder.findKotlinClassOrContent(VirtualFileFinder.kt:37)←LazyJavaPackageScope$classes$1.invoke(LazyJavaPackageScope.kt:67)←LazyJavaPackageScope$classes$1.invoke(LazyJavaPackageScope.kt:59)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LazyJavaPackageScope.findClassifier(LazyJavaPackageScope.kt:146)←LazyJavaPackageScope.getContributedClassifier(LazyJavaPackageScope.kt:136)←JvmPackageScope.getContributedClassifier(JvmPackageScope.kt:55)←ChainedMemberScope.getContributedClassifier(ChainedMemberScope.kt:35)←AbstractScopeAdapter.getContributedClassifier(AbstractScopeAdapter.kt:44)←FindClassInModuleKt.findClassifierAcrossModuleDependencies(findClassInModule.kt:26)←TypeDeserializer.computeClassifierDescriptor(TypeDeserializer.kt:268)←TypeDeserializer.access$computeClassifierDescriptor(TypeDeserializer.kt:28)←TypeDeserializer$classifierDescriptors$1.invoke(TypeDeserializer.kt:37)←TypeDeserializer$classifierDescriptors$1.invoke(TypeDeserializer.kt:36)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←TypeDeserializer.typeConstructor(TypeDeserializer.kt:161)←TypeDeserializer.simpleType(TypeDeserializer.kt:91)←TypeDeserializer.type(TypeDeserializer.kt:68)←MemberDeserializer.loadFunction(MemberDeserializer.kt:218)←DeserializedMemberScope$OptimizedImplementation.computeFunctions(DeserializedMemberScope.kt:276)←DeserializedMemberScope$OptimizedImplementation.access$computeFunctions(DeserializedMemberScope.kt:228)←DeserializedMemberScope$OptimizedImplementation$functions$1.invoke(DeserializedMemberScope.kt:251)←DeserializedMemberScope$OptimizedImplementation$functions$1.invoke(DeserializedMemberScope.kt:251)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)←DeserializedMemberScope$OptimizedImplementation.getContributedFunctions(DeserializedMemberScope.kt:329)←DeserializedMemberScope.getContributedFunctions(DeserializedMemberScope.kt:82)←JvmPackageScope.getContributedFunctions(JvmPackageScope.kt:68)←ChainedMemberScope.getContributedFunctions(ChainedMemberScope.kt:41)←AbstractScopeAdapter.getContributedFunctions(AbstractScopeAdapter.kt:40)←LazyExplicitImportScope$getContributedFunctions$1.invoke(LazyExplicitImportScope.kt:54)←LazyExplicitImportScope$getContributedFunctions$1.invoke(LazyExplicitImportScope.kt:54)←LazyExplicitImportScope.collectCallableMemberDescriptors(LazyExplicitImportScope.kt:131)←LazyExplicitImportScope.getContributedFunctions(LazyExplicitImportScope.kt:54)←LazyImportScope$getContributedFunctions$1.invoke(LazyImportScope.kt:326)←LazyImportScope$getContributedFunctions$1.invoke(LazyImportScope.kt:326)←LazyImportResolver$collectFromImports$1.invoke(LazyImportScope.kt:121)←LazyImportResolver$collectFromImports$1.invoke(LazyImportScope.kt:118)←LockBasedStorageManager.compute(LockBasedStorageManager.java:290)←LazyImportResolver.collectFromImports(LazyImportScope.kt:118)←LazyImportScope.getContributedFunctions(LazyImportScope.kt:326)←TowerLevelsKt.getContributedFunctionsAndConstructors(TowerLevels.kt:474)←TowerLevelsKt.access$getContributedFunctionsAndConstructors(TowerLevels.kt:1)←ScopeBasedTowerLevel.getFunctions(TowerLevels.kt:361)←ScopeTowerProcessorsKt$createSimpleFunctionProcessor$1.invoke(ScopeTowerProcessors.kt:304)←ScopeTowerProcessorsKt$createSimpleFunctionProcessor$1.invoke(ScopeTowerProcessors.kt:304)←NoExplicitReceiverScopeTowerProcessor.simpleProcess(ScopeTowerProcessors.kt:201)←SimpleScopeTowerProcessor.process(ScopeTowerProcessors.kt:109)←PrioritizedCompositeScopeTowerProcessor.process(ScopeTowerProcessors.kt:41)←TowerResolver.processTowerData(TowerResolver.kt:383)←TowerResolver.access$processTowerData(TowerResolver.kt:95)←TowerResolver$Task.process(TowerResolver.kt:207)←TowerResolver$Task.processImplicitReceiver(TowerResolver.kt:342)←TowerResolver$Task.run$processLexicalScope(TowerResolver.kt:250)←TowerResolver$Task.run$processScopes(TowerResolver.kt:280)←TowerResolver$Task.run(TowerResolver.kt:305)←TowerResolver.run(TowerResolver.kt:114)←TowerResolver.runResolve(TowerResolver.kt:101)←KotlinCallResolver.resolveCall(KotlinCallResolver.kt:184)←KotlinCallResolver.resolveAndCompleteCall(KotlinCallResolver.kt:41)←PSICallResolver.runResolutionAndInference(PSICallResolver.kt:114)←CallResolver.doResolveCallOrGetCachedResults(CallResolver.java:602)←CallResolver.lambda$computeTasksAndResolveCall$0(CallResolver.java:213)←PerformanceCounter.time(PerformanceCounter.kt:90)←CallResolver.computeTasksAndResolveCall(CallResolver.java:211)←CallResolver.computeTasksAndResolveCall(CallResolver.java:199)←CallResolver.resolveFunctionCall(CallResolver.java:329)←CallExpressionResolver.getResolvedCallForFunction(CallExpressionResolver.kt:86)←CallExpressionResolver.getCallExpressionTypeInfoWithoutFinalTypeCheck(CallExpressionResolver.kt:208)←CallExpressionResolver.getCallExpressionTypeInfo(CallExpressionResolver.kt:185)←BasicExpressionTypingVisitor.visitCallExpression(BasicExpressionTypingVisitor.java:731)←ExpressionTypingVisitorDispatcher.visitCallExpression(ExpressionTypingVisitorDispatcher.java:396)←ExpressionTypingVisitorDispatcher$ForBlock.visitCallExpression(ExpressionTypingVisitorDispatcher.java:60)←KtCallExpression.accept(KtCallExpression.java:35)←ExpressionTypingVisitorDispatcher.lambda$getTypeInfo$0(ExpressionTypingVisitorDispatcher.java:176)←PerformanceCounter.time(PerformanceCounter.kt:90)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:165)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:135)←ExpressionTypingVisitorDispatcher.safeGetTypeInfo(ExpressionTypingVisitorDispatcher.java:123)←BasicExpressionTypingVisitor.visitUnaryExpression(BasicExpressionTypingVisitor.java:754)←ExpressionTypingVisitorDispatcher.visitUnaryExpression(ExpressionTypingVisitorDispatcher.java:401)←ExpressionTypingVisitorDispatcher$ForBlock.visitUnaryExpression(ExpressionTypingVisitorDispatcher.java:60)←KtVisitor.visitPrefixExpression(KtVisitor.java:210)←KtPrefixExpression.accept(KtPrefixExpression.java:31)←ExpressionTypingVisitorDispatcher.lambda$getTypeInfo$0(ExpressionTypingVisitorDispatcher.java:176)←PerformanceCounter.time(PerformanceCounter.kt:90)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:165)←ExpressionTypingVisitorDispatcher.getTypeInfo(ExpressionTypingVisitorDispatcher.java:135)←ExpressionTypingVisitorForStatements.visitExpression(ExpressionTypingVisitorForStatements.java:543)←ExpressionTypingVisitorForStatements.visitExpression(ExpressionTypingVisitorForStatements.java:73)`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
-        <location
-            file="compiler-hosted"/>
-    </issue>
-
-</issues>
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
index c337918..f6bbcbe 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposePlugin.kt
@@ -213,7 +213,7 @@
     companion object {
         fun checkCompilerVersion(configuration: CompilerConfiguration): Boolean {
             try {
-                val KOTLIN_VERSION_EXPECTATION = "1.8.21"
+                val KOTLIN_VERSION_EXPECTATION = "1.8.22"
                 KotlinCompilerVersion.getVersion()?.let { version ->
                     val msgCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
                     val suppressKotlinVersionCheck = configuration.get(
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
index dac5856..6305200 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/VersionChecker.kt
@@ -127,7 +127,7 @@
          * The maven version string of this compiler. This string should be updated before/after every
          * release.
          */
-        const val compilerVersion: String = "1.5.0-alpha05"
+        const val compilerVersion: String = "1.4.7"
         private val minimumRuntimeVersion: String
             get() = runtimeVersionToMavenVersionTable[minimumRuntimeVersionInt] ?: "unknown"
     }
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
index 43cb8fe..0db9743 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableFunctionBodyTransformer.kt
@@ -3852,9 +3852,7 @@
                 for (param in function.valueParameters) {
                     val paramName = param.name.asString()
                     when {
-                        !paramName.startsWith('$') &&
-                            !paramName.startsWith("_context_receiver_") ->
-                            realValueParamCount++
+                        paramName.startsWith("_context_receiver_") -> Unit
                         paramName == KtxNameConventions.COMPOSER_PARAMETER.identifier ->
                             composerParameter = param
                         paramName.startsWith(KtxNameConventions.DEFAULT_PARAMETER.identifier) ->
@@ -3864,7 +3862,8 @@
                         paramName.startsWith("\$anonymous\$parameter") -> Unit
                         paramName.startsWith("\$name\$for\$destructuring") -> Unit
                         paramName.startsWith("\$noName_") -> Unit
-                        else -> Unit
+                        paramName == "\$this" -> Unit
+                        else -> realValueParamCount++
                     }
                 }
                 slotCount = realValueParamCount
diff --git a/compose/foundation/foundation-layout/api/1.5.0-beta01.txt b/compose/foundation/foundation-layout/api/1.5.0-beta01.txt
index ec4aa19d..147caf6 100644
--- a/compose/foundation/foundation-layout/api/1.5.0-beta01.txt
+++ b/compose/foundation/foundation-layout/api/1.5.0-beta01.txt
@@ -111,20 +111,6 @@
     method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
   }
 
-  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalLayoutApi {
-  }
-
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
-  }
-
-  public final class FlowLayoutKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional int maxItemsInEachColumn, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowColumnScope,kotlin.Unit> content);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional int maxItemsInEachRow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowRowScope,kotlin.Unit> content);
-  }
-
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
-  }
-
   public final class IntrinsicKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
@@ -142,17 +128,6 @@
   @kotlin.DslMarker public @interface LayoutScopeMarker {
   }
 
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi public final class MutableWindowInsets implements androidx.compose.foundation.layout.WindowInsets {
-    ctor public MutableWindowInsets(optional androidx.compose.foundation.layout.WindowInsets initialInsets);
-    method public int getBottom(androidx.compose.ui.unit.Density density);
-    method public androidx.compose.foundation.layout.WindowInsets getInsets();
-    method public int getLeft(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
-    method public int getRight(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
-    method public int getTop(androidx.compose.ui.unit.Density density);
-    method public void setInsets(androidx.compose.foundation.layout.WindowInsets);
-    property public final androidx.compose.foundation.layout.WindowInsets insets;
-  }
-
   public final class OffsetKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, optional float x, optional float y);
     method public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.unit.IntOffset> offset);
@@ -241,10 +216,6 @@
   public static final class WindowInsets.Companion {
   }
 
-  public final class WindowInsetsConnection_androidKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi public static androidx.compose.ui.Modifier imeNestedScroll(androidx.compose.ui.Modifier);
-  }
-
   public final class WindowInsetsKt {
     method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional float left, optional float top, optional float right, optional float bottom);
     method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional int left, optional int top, optional int right, optional int bottom);
@@ -257,13 +228,9 @@
   }
 
   public final class WindowInsetsPaddingKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onConsumedWindowInsetsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsPadding(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier withConsumedWindowInsets(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
   }
 
   public final class WindowInsetsPadding_androidKt {
@@ -313,33 +280,20 @@
   }
 
   public final class WindowInsets_androidKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreNavigationBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreStatusBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreSystemBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBar(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBarIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method public static boolean getConsumeWindowInsets(androidx.compose.ui.platform.ComposeView);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getDisplayCutout(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getIme(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationSource(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationTarget(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getMandatorySystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeContent(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeDrawing(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElement(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElementIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getWaterfall(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isCaptionBarVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isImeVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isTappableElementVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
     method public static void setConsumeWindowInsets(androidx.compose.ui.platform.ComposeView, boolean);
   }
 
diff --git a/compose/foundation/foundation-layout/api/public_plus_experimental_1.5.0-beta01.txt b/compose/foundation/foundation-layout/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..ec4aa19d
--- /dev/null
+++ b/compose/foundation/foundation-layout/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,347 @@
+// Signature format: 4.0
+package androidx.compose.foundation.layout {
+
+  public final class AlignmentLineKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier paddingFrom(androidx.compose.ui.Modifier, androidx.compose.ui.layout.AlignmentLine alignmentLine, optional float before, optional float after);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier paddingFrom(androidx.compose.ui.Modifier, androidx.compose.ui.layout.AlignmentLine alignmentLine, optional long before, optional long after);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier paddingFromBaseline(androidx.compose.ui.Modifier, optional float top, optional float bottom);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier paddingFromBaseline(androidx.compose.ui.Modifier, optional long top, optional long bottom);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Arrangement {
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Horizontal aligned(androidx.compose.ui.Alignment.Horizontal alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Vertical aligned(androidx.compose.ui.Alignment.Vertical alignment);
+    method public androidx.compose.foundation.layout.Arrangement.Vertical getBottom();
+    method public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical getCenter();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getEnd();
+    method public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical getSpaceAround();
+    method public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical getSpaceBetween();
+    method public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical getSpaceEvenly();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getStart();
+    method public androidx.compose.foundation.layout.Arrangement.Vertical getTop();
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical spacedBy(float space);
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Horizontal spacedBy(float space, androidx.compose.ui.Alignment.Horizontal alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Vertical spacedBy(float space, androidx.compose.ui.Alignment.Vertical alignment);
+    property public final androidx.compose.foundation.layout.Arrangement.Vertical Bottom;
+    property public final androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical Center;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal End;
+    property public final androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical SpaceAround;
+    property public final androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical SpaceBetween;
+    property public final androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical SpaceEvenly;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal Start;
+    property public final androidx.compose.foundation.layout.Arrangement.Vertical Top;
+    field public static final androidx.compose.foundation.layout.Arrangement INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class Arrangement.Absolute {
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Horizontal aligned(androidx.compose.ui.Alignment.Horizontal alignment);
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getCenter();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getLeft();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getRight();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getSpaceAround();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getSpaceBetween();
+    method public androidx.compose.foundation.layout.Arrangement.Horizontal getSpaceEvenly();
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.HorizontalOrVertical spacedBy(float space);
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Horizontal spacedBy(float space, androidx.compose.ui.Alignment.Horizontal alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.foundation.layout.Arrangement.Vertical spacedBy(float space, androidx.compose.ui.Alignment.Vertical alignment);
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal Center;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal Left;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal Right;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal SpaceAround;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal SpaceBetween;
+    property public final androidx.compose.foundation.layout.Arrangement.Horizontal SpaceEvenly;
+    field public static final androidx.compose.foundation.layout.Arrangement.Absolute INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public static interface Arrangement.Horizontal {
+    method public void arrange(androidx.compose.ui.unit.Density, int totalSize, int[] sizes, androidx.compose.ui.unit.LayoutDirection layoutDirection, int[] outPositions);
+    method public default float getSpacing();
+    property public default float spacing;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public static interface Arrangement.HorizontalOrVertical extends androidx.compose.foundation.layout.Arrangement.Horizontal androidx.compose.foundation.layout.Arrangement.Vertical {
+    property public default float spacing;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public static interface Arrangement.Vertical {
+    method public void arrange(androidx.compose.ui.unit.Density, int totalSize, int[] sizes, int[] outPositions);
+    method public default float getSpacing();
+    property public default float spacing;
+  }
+
+  public final class AspectRatioKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier aspectRatio(androidx.compose.ui.Modifier, float ratio, optional boolean matchHeightConstraintsFirst);
+  }
+
+  public final class BoxKt {
+    method @androidx.compose.runtime.Composable public static void Box(androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public static inline void Box(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional boolean propagateMinConstraints, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface BoxScope {
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier align(androidx.compose.ui.Modifier, androidx.compose.ui.Alignment alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier matchParentSize(androidx.compose.ui.Modifier);
+  }
+
+  public final class BoxWithConstraintsKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void BoxWithConstraints(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional boolean propagateMinConstraints, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxWithConstraintsScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Stable public interface BoxWithConstraintsScope extends androidx.compose.foundation.layout.BoxScope {
+    method public long getConstraints();
+    method public float getMaxHeight();
+    method public float getMaxWidth();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    property public abstract long constraints;
+    property public abstract float maxHeight;
+    property public abstract float maxWidth;
+    property public abstract float minHeight;
+    property public abstract float minWidth;
+  }
+
+  public final class ColumnKt {
+    method @androidx.compose.runtime.Composable public static inline void Column(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface ColumnScope {
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier align(androidx.compose.ui.Modifier, androidx.compose.ui.Alignment.Horizontal alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier alignBy(androidx.compose.ui.Modifier, androidx.compose.ui.layout.VerticalAlignmentLine alignmentLine);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier alignBy(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.Measured,java.lang.Integer> alignmentLineBlock);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
+  }
+
+  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalLayoutApi {
+  }
+
+  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
+  }
+
+  public final class FlowLayoutKt {
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional int maxItemsInEachColumn, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowColumnScope,kotlin.Unit> content);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional int maxItemsInEachRow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowRowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
+  }
+
+  public final class IntrinsicKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
+  }
+
+  public enum IntrinsicSize {
+    method public static androidx.compose.foundation.layout.IntrinsicSize valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.foundation.layout.IntrinsicSize[] values();
+    enum_constant public static final androidx.compose.foundation.layout.IntrinsicSize Max;
+    enum_constant public static final androidx.compose.foundation.layout.IntrinsicSize Min;
+  }
+
+  @kotlin.DslMarker public @interface LayoutScopeMarker {
+  }
+
+  @androidx.compose.foundation.layout.ExperimentalLayoutApi public final class MutableWindowInsets implements androidx.compose.foundation.layout.WindowInsets {
+    ctor public MutableWindowInsets(optional androidx.compose.foundation.layout.WindowInsets initialInsets);
+    method public int getBottom(androidx.compose.ui.unit.Density density);
+    method public androidx.compose.foundation.layout.WindowInsets getInsets();
+    method public int getLeft(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public int getRight(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public int getTop(androidx.compose.ui.unit.Density density);
+    method public void setInsets(androidx.compose.foundation.layout.WindowInsets);
+    property public final androidx.compose.foundation.layout.WindowInsets insets;
+  }
+
+  public final class OffsetKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, optional float x, optional float y);
+    method public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.unit.IntOffset> offset);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier offset(androidx.compose.ui.Modifier, optional float x, optional float y);
+    method public static androidx.compose.ui.Modifier offset(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.unit.IntOffset> offset);
+  }
+
+  public final class PaddingKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.layout.PaddingValues PaddingValues(float all);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.layout.PaddingValues PaddingValues(optional float horizontal, optional float vertical);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.layout.PaddingValues PaddingValues(optional float start, optional float top, optional float end, optional float bottom);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier absolutePadding(androidx.compose.ui.Modifier, optional float left, optional float top, optional float right, optional float bottom);
+    method @androidx.compose.runtime.Stable public static float calculateEndPadding(androidx.compose.foundation.layout.PaddingValues, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method @androidx.compose.runtime.Stable public static float calculateStartPadding(androidx.compose.foundation.layout.PaddingValues, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier padding(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier padding(androidx.compose.ui.Modifier, float all);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier padding(androidx.compose.ui.Modifier, optional float horizontal, optional float vertical);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier padding(androidx.compose.ui.Modifier, optional float start, optional float top, optional float end, optional float bottom);
+  }
+
+  @androidx.compose.runtime.Stable public interface PaddingValues {
+    method public float calculateBottomPadding();
+    method public float calculateLeftPadding(androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public float calculateRightPadding(androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public float calculateTopPadding();
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PaddingValues.Absolute implements androidx.compose.foundation.layout.PaddingValues {
+    ctor public PaddingValues.Absolute(optional @androidx.compose.runtime.Stable float left, optional @androidx.compose.runtime.Stable float top, optional @androidx.compose.runtime.Stable float right, optional @androidx.compose.runtime.Stable float bottom);
+    method public float calculateBottomPadding();
+    method public float calculateLeftPadding(androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public float calculateRightPadding(androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public float calculateTopPadding();
+  }
+
+  public final class RowKt {
+    method @androidx.compose.runtime.Composable public static inline void Row(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface RowScope {
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier align(androidx.compose.ui.Modifier, androidx.compose.ui.Alignment.Vertical alignment);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier alignBy(androidx.compose.ui.Modifier, androidx.compose.ui.layout.HorizontalAlignmentLine alignmentLine);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier alignBy(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.Measured,java.lang.Integer> alignmentLineBlock);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier alignByBaseline(androidx.compose.ui.Modifier);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
+  }
+
+  public final class SizeKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier defaultMinSize(androidx.compose.ui.Modifier, optional float minWidth, optional float minHeight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier fillMaxHeight(androidx.compose.ui.Modifier, optional float fraction);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier fillMaxSize(androidx.compose.ui.Modifier, optional float fraction);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier fillMaxWidth(androidx.compose.ui.Modifier, optional float fraction);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, float height);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier heightIn(androidx.compose.ui.Modifier, optional float min, optional float max);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, float height);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeightIn(androidx.compose.ui.Modifier, optional float min, optional float max);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredSize(androidx.compose.ui.Modifier, float size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredSize(androidx.compose.ui.Modifier, float width, float height);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredSize(androidx.compose.ui.Modifier, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredSizeIn(androidx.compose.ui.Modifier, optional float minWidth, optional float minHeight, optional float maxWidth, optional float maxHeight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidth(androidx.compose.ui.Modifier, float width);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredWidthIn(androidx.compose.ui.Modifier, optional float min, optional float max);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier size(androidx.compose.ui.Modifier, float size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier size(androidx.compose.ui.Modifier, float width, float height);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier size(androidx.compose.ui.Modifier, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier sizeIn(androidx.compose.ui.Modifier, optional float minWidth, optional float minHeight, optional float maxWidth, optional float maxHeight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier width(androidx.compose.ui.Modifier, float width);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier widthIn(androidx.compose.ui.Modifier, optional float min, optional float max);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier wrapContentHeight(androidx.compose.ui.Modifier, optional androidx.compose.ui.Alignment.Vertical align, optional boolean unbounded);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier wrapContentSize(androidx.compose.ui.Modifier, optional androidx.compose.ui.Alignment align, optional boolean unbounded);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier wrapContentWidth(androidx.compose.ui.Modifier, optional androidx.compose.ui.Alignment.Horizontal align, optional boolean unbounded);
+  }
+
+  public final class SpacerKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Spacer(androidx.compose.ui.Modifier modifier);
+  }
+
+  @androidx.compose.runtime.Stable public interface WindowInsets {
+    method public int getBottom(androidx.compose.ui.unit.Density density);
+    method public int getLeft(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public int getRight(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public int getTop(androidx.compose.ui.unit.Density density);
+    field public static final androidx.compose.foundation.layout.WindowInsets.Companion Companion;
+  }
+
+  public static final class WindowInsets.Companion {
+  }
+
+  public final class WindowInsetsConnection_androidKt {
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi public static androidx.compose.ui.Modifier imeNestedScroll(androidx.compose.ui.Modifier);
+  }
+
+  public final class WindowInsetsKt {
+    method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional float left, optional float top, optional float right, optional float bottom);
+    method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional int left, optional int top, optional int right, optional int bottom);
+    method public static androidx.compose.foundation.layout.WindowInsets add(androidx.compose.foundation.layout.WindowInsets, androidx.compose.foundation.layout.WindowInsets insets);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.foundation.layout.PaddingValues asPaddingValues(androidx.compose.foundation.layout.WindowInsets);
+    method public static androidx.compose.foundation.layout.PaddingValues asPaddingValues(androidx.compose.foundation.layout.WindowInsets, androidx.compose.ui.unit.Density density);
+    method public static androidx.compose.foundation.layout.WindowInsets exclude(androidx.compose.foundation.layout.WindowInsets, androidx.compose.foundation.layout.WindowInsets insets);
+    method public static androidx.compose.foundation.layout.WindowInsets only(androidx.compose.foundation.layout.WindowInsets, int sides);
+    method public static androidx.compose.foundation.layout.WindowInsets union(androidx.compose.foundation.layout.WindowInsets, androidx.compose.foundation.layout.WindowInsets insets);
+  }
+
+  public final class WindowInsetsPaddingKt {
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
+    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onConsumedWindowInsetsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsPadding(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier withConsumedWindowInsets(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
+  }
+
+  public final class WindowInsetsPadding_androidKt {
+    method public static androidx.compose.ui.Modifier captionBarPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier displayCutoutPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier imePadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier mandatorySystemGesturesPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier navigationBarsPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier safeContentPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier safeDrawingPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier safeGesturesPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier statusBarsPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier systemBarsPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier systemGesturesPadding(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier waterfallPadding(androidx.compose.ui.Modifier);
+  }
+
+  @kotlin.jvm.JvmInline public final value class WindowInsetsSides {
+    method public operator int plus(int sides);
+    field public static final androidx.compose.foundation.layout.WindowInsetsSides.Companion Companion;
+  }
+
+  public static final class WindowInsetsSides.Companion {
+    method public int getBottom();
+    method public int getEnd();
+    method public int getHorizontal();
+    method public int getLeft();
+    method public int getRight();
+    method public int getStart();
+    method public int getTop();
+    method public int getVertical();
+    property public final int Bottom;
+    property public final int End;
+    property public final int Horizontal;
+    property public final int Left;
+    property public final int Right;
+    property public final int Start;
+    property public final int Top;
+    property public final int Vertical;
+  }
+
+  public final class WindowInsetsSizeKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsBottomHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsEndWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsStartWidth(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsTopHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
+  }
+
+  public final class WindowInsets_androidKt {
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreNavigationBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreStatusBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreSystemBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBar(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBarIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method public static boolean getConsumeWindowInsets(androidx.compose.ui.platform.ComposeView);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getDisplayCutout(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getIme(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationSource(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationTarget(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getMandatorySystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBars(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeContent(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeDrawing(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBars(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBars(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElement(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElementIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getWaterfall(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isCaptionBarVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isImeVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isTappableElementVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
+    method public static void setConsumeWindowInsets(androidx.compose.ui.platform.ComposeView, boolean);
+  }
+
+}
+
diff --git a/compose/foundation/foundation-layout/api/restricted_1.5.0-beta01.txt b/compose/foundation/foundation-layout/api/restricted_1.5.0-beta01.txt
index 6fe644c..ee1efa2 100644
--- a/compose/foundation/foundation-layout/api/restricted_1.5.0-beta01.txt
+++ b/compose/foundation/foundation-layout/api/restricted_1.5.0-beta01.txt
@@ -114,22 +114,11 @@
     method @androidx.compose.runtime.Stable public androidx.compose.ui.Modifier weight(androidx.compose.ui.Modifier, float weight, optional boolean fill);
   }
 
-  @kotlin.RequiresOptIn(message="The API of this layout is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalLayoutApi {
-  }
-
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowColumnScope extends androidx.compose.foundation.layout.ColumnScope {
-  }
-
   public final class FlowLayoutKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional int maxItemsInEachColumn, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowColumnScope,kotlin.Unit> content);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable public static inline void FlowRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional int maxItemsInEachRow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.FlowRowScope,kotlin.Unit> content);
     method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy columnMeasurementHelper(androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, int maxItemsInMainAxis);
     method @androidx.compose.runtime.Composable @kotlin.PublishedApi internal static androidx.compose.ui.layout.MeasurePolicy rowMeasurementHelper(androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, int maxItemsInMainAxis);
   }
 
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.foundation.layout.LayoutScopeMarker @androidx.compose.runtime.Immutable public interface FlowRowScope extends androidx.compose.foundation.layout.RowScope {
-  }
-
   public final class IntrinsicKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier height(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier requiredHeight(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.IntrinsicSize intrinsicSize);
@@ -147,17 +136,6 @@
   @kotlin.DslMarker public @interface LayoutScopeMarker {
   }
 
-  @androidx.compose.foundation.layout.ExperimentalLayoutApi public final class MutableWindowInsets implements androidx.compose.foundation.layout.WindowInsets {
-    ctor public MutableWindowInsets(optional androidx.compose.foundation.layout.WindowInsets initialInsets);
-    method public int getBottom(androidx.compose.ui.unit.Density density);
-    method public androidx.compose.foundation.layout.WindowInsets getInsets();
-    method public int getLeft(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
-    method public int getRight(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection);
-    method public int getTop(androidx.compose.ui.unit.Density density);
-    method public void setInsets(androidx.compose.foundation.layout.WindowInsets);
-    property public final androidx.compose.foundation.layout.WindowInsets insets;
-  }
-
   public final class OffsetKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, optional float x, optional float y);
     method public static androidx.compose.ui.Modifier absoluteOffset(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.unit.IntOffset> offset);
@@ -248,10 +226,6 @@
   public static final class WindowInsets.Companion {
   }
 
-  public final class WindowInsetsConnection_androidKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi public static androidx.compose.ui.Modifier imeNestedScroll(androidx.compose.ui.Modifier);
-  }
-
   public final class WindowInsetsKt {
     method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional float left, optional float top, optional float right, optional float bottom);
     method public static androidx.compose.foundation.layout.WindowInsets WindowInsets(optional int left, optional int top, optional int right, optional int bottom);
@@ -264,13 +238,9 @@
   }
 
   public final class WindowInsetsPaddingKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumeWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.PaddingValues paddingValues);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier consumedWindowInsets(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onConsumedWindowInsetsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier windowInsetsPadding(androidx.compose.ui.Modifier, androidx.compose.foundation.layout.WindowInsets insets);
-    method @Deprecated @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier withConsumedWindowInsets(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.WindowInsets,kotlin.Unit> block);
   }
 
   public final class WindowInsetsPadding_androidKt {
@@ -320,33 +290,20 @@
   }
 
   public final class WindowInsets_androidKt {
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreNavigationBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreStatusBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean getAreSystemBarsVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBar(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getCaptionBarIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method public static boolean getConsumeWindowInsets(androidx.compose.ui.platform.ComposeView);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getDisplayCutout(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getIme(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationSource(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getImeAnimationTarget(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getMandatorySystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getNavigationBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeContent(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeDrawing(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSafeGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getStatusBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBars(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemBarsIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getSystemGestures(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElement(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getTappableElementIgnoringVisibility(androidx.compose.foundation.layout.WindowInsets.Companion);
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static androidx.compose.foundation.layout.WindowInsets getWaterfall(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isCaptionBarVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isImeVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
-    method @androidx.compose.foundation.layout.ExperimentalLayoutApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static boolean isTappableElementVisible(androidx.compose.foundation.layout.WindowInsets.Companion);
     method public static void setConsumeWindowInsets(androidx.compose.ui.platform.ComposeView, boolean);
   }
 
diff --git a/compose/foundation/foundation-layout/build.gradle b/compose/foundation/foundation-layout/build.gradle
index 872eef6..055f276 100644
--- a/compose/foundation/foundation-layout/build.gradle
+++ b/compose/foundation/foundation-layout/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/foundation/foundation-layout/lint-baseline.xml b/compose/foundation/foundation-layout/lint-baseline.xml
new file mode 100644
index 0000000..ecffddb
--- /dev/null
+++ b/compose/foundation/foundation-layout/lint-baseline.xml
@@ -0,0 +1,418 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SpacedAligned has parameter &apos;alignment&apos; with type Function2&lt;? super Integer, ? super LayoutDirection, Integer>."
+        errorLine1="        val alignment: ((Int, LayoutDirection) -> Int)?"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Integer, LayoutDirection, Integer> of &apos;getAlignment&apos;."
+        errorLine1="        val alignment: ((Int, LayoutDirection) -> Int)?"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method alignBy has parameter &apos;alignmentLineBlock&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="    fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int): Modifier"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function5&lt;Integer, int[], LayoutDirection, Density, int[], Unit> of &apos;getVerticalArrangement&apos;."
+        errorLine1="        (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit ="
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function5&lt;Integer, int[], LayoutDirection, Density, int[], Unit> of &apos;getHorizontalArrangement&apos;."
+        errorLine1="private fun getHorizontalArrangement(horizontalArrangement: Arrangement.Horizontal) ="
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method flowMeasurePolicy has parameter &apos;mainAxisArrangement&apos; with type Function5&lt;? super Integer, ? super int[], ? super LayoutDirection, ? super Density, ? super int[], Unit>."
+        errorLine1="    mainAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method flowMeasurePolicy has parameter &apos;crossAxisArrangement&apos; with type Function5&lt;? super Integer, ? super int[], ? super LayoutDirection, ? super Density, ? super int[], Unit>."
+        errorLine1="    crossAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;IntrinsicMeasurable, Integer, Integer, Integer> of &apos;getMaxMainAxisIntrinsicItemSize&apos;."
+        errorLine1="        val maxMainAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int ="
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;IntrinsicMeasurable, Integer, Integer, Integer> of &apos;getMaxCrossAxisIntrinsicItemSize&apos;."
+        errorLine1="        val maxCrossAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int ="
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;IntrinsicMeasurable, Integer, Integer, Integer> of &apos;getMinCrossAxisIntrinsicItemSize&apos;."
+        errorLine1="        val minCrossAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int ="
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;IntrinsicMeasurable, Integer, Integer, Integer> of &apos;getMinMainAxisIntrinsicItemSize&apos;."
+        errorLine1="        val minMainAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int ="
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method maxIntrinsicMainAxisSize has parameter &apos;mainAxisSize&apos; with type Function3&lt;? super IntrinsicMeasurable, ? super Integer, ? super Integer, Integer>."
+        errorLine1="    mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method minIntrinsicMainAxisSize has parameter &apos;mainAxisSize&apos; with type Function3&lt;? super IntrinsicMeasurable, ? super Integer, ? super Integer, Integer>."
+        errorLine1="    mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method minIntrinsicMainAxisSize has parameter &apos;crossAxisSize&apos; with type Function3&lt;? super IntrinsicMeasurable, ? super Integer, ? super Integer, Integer>."
+        errorLine1="    crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicCrossAxisSize has parameter &apos;mainAxisSize&apos; with type Function3&lt;? super IntrinsicMeasurable, ? super Integer, ? super Integer, Integer>."
+        errorLine1="    mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicCrossAxisSize has parameter &apos;crossAxisSize&apos; with type Function3&lt;? super IntrinsicMeasurable, ? super Integer, ? super Integer, Integer>."
+        errorLine1="    crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method alignBy has parameter &apos;alignmentLineBlock&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="    fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int): Modifier"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rowColumnMeasurePolicy has parameter &apos;arrangement&apos; with type Function5&lt;? super Integer, ? super int[], ? super LayoutDirection, ? super Density, ? super int[], Unit>."
+        errorLine1="    arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;MinIntrinsicWidthMeasureBlock&apos;."
+        errorLine1="private fun MinIntrinsicWidthMeasureBlock(orientation: LayoutOrientation) ="
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;MinIntrinsicHeightMeasureBlock&apos;."
+        errorLine1="private fun MinIntrinsicHeightMeasureBlock(orientation: LayoutOrientation) ="
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;MaxIntrinsicWidthMeasureBlock&apos;."
+        errorLine1="private fun MaxIntrinsicWidthMeasureBlock(orientation: LayoutOrientation) ="
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;MaxIntrinsicHeightMeasureBlock&apos;."
+        errorLine1="private fun MaxIntrinsicHeightMeasureBlock(orientation: LayoutOrientation) ="
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getHorizontalMinWidth&apos;."
+        errorLine1="    val HorizontalMinWidth: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getVerticalMinWidth&apos;."
+        errorLine1="    val VerticalMinWidth: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getHorizontalMinHeight&apos;."
+        errorLine1="    val HorizontalMinHeight: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getVerticalMinHeight&apos;."
+        errorLine1="    val VerticalMinHeight: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getHorizontalMaxWidth&apos;."
+        errorLine1="    val HorizontalMaxWidth: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getVerticalMaxWidth&apos;."
+        errorLine1="    val VerticalMaxWidth: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getHorizontalMaxHeight&apos;."
+        errorLine1="    val HorizontalMaxHeight: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;List&lt;? extends IntrinsicMeasurable>, Integer, Integer, Integer> of &apos;getVerticalMaxHeight&apos;."
+        errorLine1="    val VerticalMaxHeight: (List&lt;IntrinsicMeasurable>, Int, Int) -> Int ="
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicSize has parameter &apos;intrinsicMainSize&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="    intrinsicMainSize: IntrinsicMeasurable.(Int) -> Int,"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicSize has parameter &apos;intrinsicCrossSize&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="    intrinsicCrossSize: IntrinsicMeasurable.(Int) -> Int,"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicMainAxisSize has parameter &apos;mainAxisSize&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="    mainAxisSize: IntrinsicMeasurable.(Int) -> Int,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicCrossAxisSize has parameter &apos;mainAxisSize&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="    mainAxisSize: IntrinsicMeasurable.(Int) -> Int,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicCrossAxisSize has parameter &apos;crossAxisSize&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="    crossAxisSize: IntrinsicMeasurable.(Int) -> Int,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor WithAlignmentLineBlockElement has parameter &apos;block&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="    val block: (Measured) -> Int"
+        errorLine2="               ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Measured, Integer> of &apos;getBlock&apos;."
+        errorLine1="    val block: (Measured) -> Int"
+        errorLine2="               ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor WithAlignmentLineBlockNode has parameter &apos;block&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="        var block: (Measured) -> Int,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setBlock has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="        var block: (Measured) -> Int,"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Measured, Integer> of &apos;getBlock&apos;."
+        errorLine1="        var block: (Measured) -> Int,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor Block has parameter &apos;lineProviderBlock&apos; with type Function1&lt;? super Measured, Integer>."
+        errorLine1="    data class Block(val lineProviderBlock: (Measured) -> Int) : AlignmentLineProvider() {"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Measured, Integer> of &apos;getLineProviderBlock&apos;."
+        errorLine1="    data class Block(val lineProviderBlock: (Measured) -> Int) : AlignmentLineProvider() {"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor RowColumnMeasurementHelper has parameter &apos;arrangement&apos; with type Function5&lt;? super Integer, ? super int[], ? super LayoutDirection, ? super Density, ? super int[], Unit>."
+        errorLine1="    val arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function5&lt;Integer, int[], LayoutDirection, Density, int[], Unit> of &apos;getArrangement&apos;."
+        errorLine1="    val arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DerivedWidthModifier has parameter &apos;widthCalc&apos; with type Function3&lt;? super WindowInsets, ? super LayoutDirection, ? super Density, Integer>."
+        errorLine1="    private val widthCalc: WindowInsets.(LayoutDirection, Density) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DerivedHeightModifier has parameter &apos;heightCalc&apos; with type Function2&lt;? super WindowInsets, ? super Density, Integer>."
+        errorLine1="    private val heightCalc: WindowInsets.(Density) -> Int"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
index 824fee8..b7e385e 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
@@ -566,7 +566,6 @@
     internal data class SpacedAligned(
         val space: Dp,
         val rtlMirror: Boolean,
-        @Suppress("PrimitiveInLambda")
         val alignment: ((Int, LayoutDirection) -> Int)?
     ) : HorizontalOrVertical {
 
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
index 1612d89..10f1128 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Column.kt
@@ -191,10 +191,7 @@
      * @sample androidx.compose.foundation.layout.samples.SimpleRelativeToSiblings
      */
     @Stable
-    fun Modifier.alignBy(
-        @Suppress("PrimitiveInLambda")
-        alignmentLineBlock: (Measured) -> Int
-    ): Modifier
+    fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int): Modifier
 }
 
 internal object ColumnScopeInstance : ColumnScope {
@@ -225,10 +222,7 @@
     )
 
     @Stable
-    override fun Modifier.alignBy(
-        @Suppress("PrimitiveInLambda")
-        alignmentLineBlock: (Measured) -> Int
-    ) = this.then(
+    override fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int) = this.then(
         WithAlignmentLineBlockElement(
             block = alignmentLineBlock
         )
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
index 1dc731a..cdec1d5 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/FlowLayout.kt
@@ -143,7 +143,6 @@
 @OptIn(ExperimentalLayoutApi::class)
 internal object FlowColumnScopeInstance : ColumnScope by ColumnScopeInstance, FlowColumnScope
 
-@Suppress("PrimitiveInLambda")
 private fun getVerticalArrangement(verticalArrangement: Arrangement.Vertical):
         (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit =
     { totalSize: Int, size: IntArray, _, density: Density, outPosition: IntArray ->
@@ -152,7 +151,6 @@
         }
     }
 
-@Suppress("PrimitiveInLambda")
 private fun getHorizontalArrangement(horizontalArrangement: Arrangement.Horizontal) =
     { totalSize: Int, size: IntArray, layoutDirection: LayoutDirection,
         density: Density, outPosition: IntArray ->
@@ -208,12 +206,10 @@
  */
 private fun flowMeasurePolicy(
     orientation: LayoutOrientation,
-    @Suppress("PrimitiveInLambda")
     mainAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
     mainAxisArrangementSpacing: Dp,
     crossAxisSize: SizeMode,
     crossAxisAlignment: CrossAxisAlignment,
-    @Suppress("PrimitiveInLambda")
     crossAxisArrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
     crossAxisArrangementSpacing: Dp,
     maxItemsInMainAxis: Int,
@@ -403,7 +399,6 @@
             maxItemsInMainAxis
         )
 
-        @Suppress("PrimitiveInLambda")
         val maxMainAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int =
             if (orientation == LayoutOrientation.Horizontal) { _, h ->
                 maxIntrinsicWidth(h)
@@ -412,7 +407,6 @@
                 maxIntrinsicHeight(w)
             }
 
-        @Suppress("PrimitiveInLambda")
         val maxCrossAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int =
             if (orientation == LayoutOrientation.Horizontal) { _, w ->
                 maxIntrinsicHeight(w)
@@ -421,7 +415,6 @@
                 maxIntrinsicWidth(h)
             }
 
-        @Suppress("PrimitiveInLambda")
         val minCrossAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int =
             if (orientation == LayoutOrientation.Horizontal) { _, w ->
                 minIntrinsicHeight(w)
@@ -430,7 +423,6 @@
                 minIntrinsicWidth(h)
             }
 
-        @Suppress("PrimitiveInLambda")
         val minMainAxisIntrinsicItemSize: IntrinsicMeasurable.(Int, Int) -> Int =
             if (orientation == LayoutOrientation.Horizontal) { _, h ->
                 minIntrinsicWidth(h)
@@ -443,7 +435,6 @@
 
 private fun maxIntrinsicMainAxisSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
     crossAxisAvailable: Int,
     mainAxisSpacing: Int,
@@ -473,9 +464,7 @@
  */
 private fun minIntrinsicMainAxisSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
-    @Suppress("PrimitiveInLambda")
     crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
     crossAxisAvailable: Int,
     mainAxisSpacing: Int,
@@ -556,9 +545,7 @@
  */
 private fun intrinsicCrossAxisSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     mainAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
-    @Suppress("PrimitiveInLambda")
     crossAxisSize: IntrinsicMeasurable.(Int, Int) -> Int,
     mainAxisAvailable: Int,
     mainAxisSpacing: Int,
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
index 0b40831..02bd8ec 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Row.kt
@@ -211,10 +211,7 @@
      * @sample androidx.compose.foundation.layout.samples.SimpleAlignByInRow
      */
     @Stable
-    fun Modifier.alignBy(
-        @Suppress("PrimitiveInLambda")
-        alignmentLineBlock: (Measured) -> Int
-    ): Modifier
+    fun Modifier.alignBy(alignmentLineBlock: (Measured) -> Int): Modifier
 }
 
 internal object RowScopeInstance : RowScope {
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
index 3add92f..ce9028a 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnImpl.kt
@@ -45,7 +45,6 @@
 
 internal fun rowColumnMeasurePolicy(
     orientation: LayoutOrientation,
-    @Suppress("PrimitiveInLambda")
     arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
     arrangementSpacing: Dp,
     crossAxisSize: SizeMode,
@@ -405,7 +404,6 @@
 internal val RowColumnParentData?.isRelative: Boolean
     get() = this.crossAxisAlignment?.isRelative ?: false
 
-@Suppress("PrimitiveInLambda")
 private fun MinIntrinsicWidthMeasureBlock(orientation: LayoutOrientation) =
     if (orientation == LayoutOrientation.Horizontal) {
         IntrinsicMeasureBlocks.HorizontalMinWidth
@@ -413,7 +411,6 @@
         IntrinsicMeasureBlocks.VerticalMinWidth
     }
 
-@Suppress("PrimitiveInLambda")
 private fun MinIntrinsicHeightMeasureBlock(orientation: LayoutOrientation) =
     if (orientation == LayoutOrientation.Horizontal) {
         IntrinsicMeasureBlocks.HorizontalMinHeight
@@ -421,7 +418,6 @@
         IntrinsicMeasureBlocks.VerticalMinHeight
     }
 
-@Suppress("PrimitiveInLambda")
 private fun MaxIntrinsicWidthMeasureBlock(orientation: LayoutOrientation) =
     if (orientation == LayoutOrientation.Horizontal) {
         IntrinsicMeasureBlocks.HorizontalMaxWidth
@@ -429,7 +425,6 @@
         IntrinsicMeasureBlocks.VerticalMaxWidth
     }
 
-@Suppress("PrimitiveInLambda")
 private fun MaxIntrinsicHeightMeasureBlock(orientation: LayoutOrientation) =
     if (orientation == LayoutOrientation.Horizontal) {
         IntrinsicMeasureBlocks.HorizontalMaxHeight
@@ -438,7 +433,6 @@
     }
 
 private object IntrinsicMeasureBlocks {
-    @Suppress("PrimitiveInLambda")
     val HorizontalMinWidth: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableHeight, mainAxisSpacing ->
             intrinsicSize(
@@ -451,7 +445,6 @@
                 LayoutOrientation.Horizontal
             )
         }
-    @Suppress("PrimitiveInLambda")
     val VerticalMinWidth: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableHeight, mainAxisSpacing ->
             intrinsicSize(
@@ -464,7 +457,6 @@
                 LayoutOrientation.Horizontal
             )
         }
-    @Suppress("PrimitiveInLambda")
     val HorizontalMinHeight: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableWidth, mainAxisSpacing ->
             intrinsicSize(
@@ -477,7 +469,6 @@
                 LayoutOrientation.Vertical
             )
         }
-    @Suppress("PrimitiveInLambda")
     val VerticalMinHeight: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableWidth, mainAxisSpacing ->
             intrinsicSize(
@@ -490,7 +481,6 @@
                 LayoutOrientation.Vertical
             )
         }
-    @Suppress("PrimitiveInLambda")
     val HorizontalMaxWidth: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableHeight, mainAxisSpacing ->
             intrinsicSize(
@@ -503,7 +493,6 @@
                 LayoutOrientation.Horizontal
             )
         }
-    @Suppress("PrimitiveInLambda")
     val VerticalMaxWidth: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableHeight, mainAxisSpacing ->
             intrinsicSize(
@@ -516,7 +505,6 @@
                 LayoutOrientation.Horizontal
             )
         }
-    @Suppress("PrimitiveInLambda")
     val HorizontalMaxHeight: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableWidth, mainAxisSpacing ->
             intrinsicSize(
@@ -529,7 +517,6 @@
                 LayoutOrientation.Vertical
             )
         }
-    @Suppress("PrimitiveInLambda")
     val VerticalMaxHeight: (List<IntrinsicMeasurable>, Int, Int) -> Int =
         { measurables, availableWidth, mainAxisSpacing ->
             intrinsicSize(
@@ -546,9 +533,7 @@
 
 private fun intrinsicSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     intrinsicMainSize: IntrinsicMeasurable.(Int) -> Int,
-    @Suppress("PrimitiveInLambda")
     intrinsicCrossSize: IntrinsicMeasurable.(Int) -> Int,
     crossAxisAvailable: Int,
     mainAxisSpacing: Int,
@@ -568,7 +553,6 @@
 
 private fun intrinsicMainAxisSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     mainAxisSize: IntrinsicMeasurable.(Int) -> Int,
     crossAxisAvailable: Int,
     mainAxisSpacing: Int
@@ -592,9 +576,7 @@
 
 private fun intrinsicCrossAxisSize(
     children: List<IntrinsicMeasurable>,
-    @Suppress("PrimitiveInLambda")
     mainAxisSize: IntrinsicMeasurable.(Int) -> Int,
-    @Suppress("PrimitiveInLambda")
     crossAxisSize: IntrinsicMeasurable.(Int) -> Int,
     mainAxisAvailable: Int,
     mainAxisSpacing: Int
@@ -693,7 +675,6 @@
 }
 
 internal class WithAlignmentLineBlockElement(
-    @Suppress("PrimitiveInLambda")
     val block: (Measured) -> Int
 ) : ModifierNodeElement<SiblingsAlignedNode.WithAlignmentLineBlockNode>() {
     override fun create(): SiblingsAlignedNode.WithAlignmentLineBlockNode {
@@ -747,7 +728,6 @@
     abstract override fun Density.modifyParentData(parentData: Any?): Any?
 
     internal class WithAlignmentLineBlockNode(
-        @Suppress("PrimitiveInLambda")
         var block: (Measured) -> Int,
     ) : SiblingsAlignedNode() {
         override fun Density.modifyParentData(parentData: Any?): Any {
@@ -853,10 +833,7 @@
  */
 internal sealed class AlignmentLineProvider {
     abstract fun calculateAlignmentLinePosition(placeable: Placeable): Int
-    data class Block(
-        @Suppress("PrimitiveInLambda")
-        val lineProviderBlock: (Measured) -> Int
-    ) : AlignmentLineProvider() {
+    data class Block(val lineProviderBlock: (Measured) -> Int) : AlignmentLineProvider() {
         override fun calculateAlignmentLinePosition(
             placeable: Placeable
         ): Int {
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
index 82e6af0..a828f9f 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/RowColumnMeasurementHelper.kt
@@ -48,7 +48,6 @@
  */
 internal class RowColumnMeasurementHelper(
     val orientation: LayoutOrientation,
-    @Suppress("PrimitiveInLambda")
     val arrangement: (Int, IntArray, LayoutDirection, Density, IntArray) -> Unit,
     val arrangementSpacing: Dp,
     val crossAxisSize: SizeMode,
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt
index 5970247..76af273 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/WindowInsetsSize.kt
@@ -130,7 +130,6 @@
 private class DerivedWidthModifier(
     private val insets: WindowInsets,
     inspectorInfo: InspectorInfo.() -> Unit,
-    @Suppress("PrimitiveInLambda")
     private val widthCalc: WindowInsets.(LayoutDirection, Density) -> Int
 ) : LayoutModifier, ModifierLocalConsumer, InspectorValueInfo(inspectorInfo) {
     private var unconsumedInsets: WindowInsets by mutableStateOf(insets)
@@ -176,7 +175,6 @@
 private class DerivedHeightModifier(
     private val insets: WindowInsets,
     inspectorInfo: InspectorInfo.() -> Unit,
-    @Suppress("PrimitiveInLambda")
     private val heightCalc: WindowInsets.(Density) -> Int
 ) : LayoutModifier, ModifierLocalConsumer, InspectorValueInfo(inspectorInfo) {
     private var unconsumedInsets: WindowInsets by mutableStateOf(insets)
diff --git a/compose/foundation/foundation/api/1.5.0-beta01.txt b/compose/foundation/foundation/api/1.5.0-beta01.txt
index 15fd553..8be51e4 100644
--- a/compose/foundation/foundation/api/1.5.0-beta01.txt
+++ b/compose/foundation/foundation/api/1.5.0-beta01.txt
@@ -6,19 +6,6 @@
     method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
   }
 
-  public final class BasicMarqueeKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeDelayMillis();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeIterations();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static float getDefaultMarqueeVelocity();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeDelayMillis;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeIterations;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final float DefaultMarqueeVelocity;
-  }
-
   public final class BorderKt {
     method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, androidx.compose.foundation.BorderStroke border, optional androidx.compose.ui.graphics.Shape shape);
     method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, float width, androidx.compose.ui.graphics.Brush brush, androidx.compose.ui.graphics.Shape shape);
@@ -39,7 +26,6 @@
   }
 
   public final class CanvasKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, String contentDescription, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
     method @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
   }
 
@@ -50,8 +36,6 @@
   public final class ClickableKt {
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class ClipScrollableContainerKt {
@@ -67,18 +51,10 @@
     method @Deprecated public static androidx.compose.ui.Modifier excludeFromSystemGesture(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> exclusion);
   }
 
-  @kotlin.RequiresOptIn(message="This foundation API is experimental and is likely to change or be removed in the " + "future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalFoundationApi {
-  }
-
   public final class FocusableKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier focusGroup(androidx.compose.ui.Modifier);
     method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
-  public final class FocusedBoundsKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier onFocusedBoundsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,kotlin.Unit> onPositioned);
-  }
-
   public final class HoverableKt {
     method public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
   }
@@ -104,47 +80,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> LocalIndication;
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
-  }
-
-  public final class MagnifierKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier magnifier(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> sourceCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> magnifierCenter, optional float zoom, optional androidx.compose.foundation.MagnifierStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.DpSize,kotlin.Unit>? onSizeChanged);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class MagnifierStyle {
-    ctor @androidx.compose.foundation.ExperimentalFoundationApi public MagnifierStyle(optional long size, optional float cornerRadius, optional float elevation, optional boolean clippingEnabled, optional boolean fishEyeEnabled);
-    method public boolean isSupported();
-    property public final boolean isSupported;
-    field public static final androidx.compose.foundation.MagnifierStyle.Companion Companion;
-  }
-
-  public static final class MagnifierStyle.Companion {
-    method public androidx.compose.foundation.MagnifierStyle getDefault();
-    method public androidx.compose.foundation.MagnifierStyle getTextDefault();
-    property public final androidx.compose.foundation.MagnifierStyle Default;
-    property public final androidx.compose.foundation.MagnifierStyle TextDefault;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
-    field public static final androidx.compose.foundation.MarqueeAnimationMode.Companion Companion;
-  }
-
-  public static final class MarqueeAnimationMode.Companion {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int getImmediately();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int getWhileFocused();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int Immediately;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int WhileFocused;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
-    field public static final androidx.compose.foundation.MarqueeSpacing.Companion Companion;
-  }
-
-  public static final class MarqueeSpacing.Companion {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
-  }
-
   public enum MutatePriority {
     method public static androidx.compose.foundation.MutatePriority valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.compose.foundation.MutatePriority[] values();
@@ -159,32 +94,6 @@
     method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
   }
 
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class OverscrollConfiguration {
-    ctor public OverscrollConfiguration(optional long glowColor, optional androidx.compose.foundation.layout.PaddingValues drawPadding);
-    method public androidx.compose.foundation.layout.PaddingValues getDrawPadding();
-    method public long getGlowColor();
-    property public final androidx.compose.foundation.layout.PaddingValues drawPadding;
-    property public final long glowColor;
-  }
-
-  public final class OverscrollConfigurationKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> getLocalOverscrollConfiguration();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> LocalOverscrollConfiguration;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface OverscrollEffect {
-    method public suspend Object? applyToFling(long velocity, kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Velocity,? super kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>,?> performFling, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public long applyToScroll(long delta, int source, kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset> performScroll);
-    method public androidx.compose.ui.Modifier getEffectModifier();
-    method public boolean isInProgress();
-    property public abstract androidx.compose.ui.Modifier effectModifier;
-    property public abstract boolean isInProgress;
-  }
-
-  public final class OverscrollKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier overscroll(androidx.compose.ui.Modifier, androidx.compose.foundation.OverscrollEffect overscrollEffect);
-  }
-
   public final class ProgressSemanticsKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier, float value, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps);
@@ -298,13 +207,11 @@
 
   public final class ScrollableDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.FlingBehavior flingBehavior();
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public androidx.compose.foundation.OverscrollEffect overscrollEffect();
     method public boolean reverseDirection(androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.foundation.gestures.Orientation orientation, boolean reverseScrolling);
     field public static final androidx.compose.foundation.gestures.ScrollableDefaults INSTANCE;
   }
 
   public final class ScrollableKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, androidx.compose.foundation.OverscrollEffect? overscrollEffect, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
@@ -347,7 +254,6 @@
 
   public final class TransformableKt {
     method public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, optional boolean lockRotationOnZoomPan, optional boolean enabled);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, kotlin.jvm.functions.Function0<java.lang.Boolean> canPan, optional boolean lockRotationOnZoomPan, optional boolean enabled);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface TransformableState {
@@ -370,45 +276,6 @@
 
 }
 
-package androidx.compose.foundation.gestures.snapping {
-
-  public final class LazyGridSnapLayoutInfoProviderKt {
-    method @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.SnapPositionInLayout positionInLayout);
-  }
-
-  public final class LazyListSnapLayoutInfoProviderKt {
-    method @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.SnapPositionInLayout positionInLayout);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.FlingBehavior {
-    ctor 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, androidx.compose.ui.unit.Density density, optional float shortSnapVelocityThreshold);
-    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
-    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onSettlingDistanceUpdated, kotlin.coroutines.Continuation<? super java.lang.Float>);
-  }
-
-  public final class SnapFlingBehaviorKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.snapping.SnapFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public interface SnapLayoutInfoProvider {
-    method public float calculateApproachOffset(androidx.compose.ui.unit.Density, float initialVelocity);
-    method public float calculateSnapStepSize(androidx.compose.ui.unit.Density);
-    method public float calculateSnappingOffset(androidx.compose.ui.unit.Density, float currentVelocity);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public fun interface SnapPositionInLayout {
-    method public int position(androidx.compose.ui.unit.Density, int layoutSize, int itemSize, int itemIndex);
-    field public static final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion Companion;
-  }
-
-  public static final class SnapPositionInLayout.Companion {
-    method public androidx.compose.foundation.gestures.snapping.SnapPositionInLayout getCenterToCenter();
-    property public final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout CenterToCenter;
-  }
-
-}
-
 package androidx.compose.foundation.interaction {
 
   public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
@@ -530,7 +397,6 @@
   }
 
   @androidx.compose.foundation.lazy.LazyScopeMarker @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
     method public androidx.compose.ui.Modifier fillParentMaxHeight(androidx.compose.ui.Modifier, optional float fraction);
     method public androidx.compose.ui.Modifier fillParentMaxSize(androidx.compose.ui.Modifier, optional float fraction);
     method public androidx.compose.ui.Modifier fillParentMaxWidth(androidx.compose.ui.Modifier, optional float fraction);
@@ -577,7 +443,6 @@
     method @Deprecated public void item(optional Object? key, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
     method public default void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
     method @Deprecated public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public void stickyHeader(optional Object? key, optional Object? contentType, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Stable public final class LazyListState implements androidx.compose.foundation.gestures.ScrollableState {
@@ -638,7 +503,6 @@
 
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class GridItemSpan {
     method public int getCurrentLineSpan();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int currentLineSpan;
   }
 
   public final class LazyGridDslKt {
@@ -676,7 +540,6 @@
   }
 
   @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker @androidx.compose.runtime.Stable public sealed interface LazyGridItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
   }
 
   @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker public sealed interface LazyGridItemSpanScope {
@@ -753,110 +616,6 @@
 
 }
 
-package androidx.compose.foundation.lazy.layout {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface IntervalList<T> {
-    method public void forEach(optional int fromIndex, optional int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
-    method public operator androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
-    method public int getSize();
-    property public abstract int size;
-  }
-
-  public static final class IntervalList.Interval<T> {
-    method public int getSize();
-    method public int getStartIndex();
-    method public T getValue();
-    property public final int size;
-    property public final int startIndex;
-    property public final T value;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public abstract class LazyLayoutIntervalContent<Interval extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> {
-    ctor public LazyLayoutIntervalContent();
-    method public final Object? getContentType(int index);
-    method public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> getIntervals();
-    method public final int getItemCount();
-    method public final Object getKey(int index);
-    method public final inline <T> T withInterval(int globalIndex, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super Interval,? extends T> block);
-    property public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> intervals;
-    property public final int itemCount;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static interface LazyLayoutIntervalContent.Interval {
-    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? getKey();
-    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> getType();
-    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? key;
-    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> type;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface LazyLayoutItemProvider {
-    method @androidx.compose.runtime.Composable public void Item(int index, Object key);
-    method public default Object? getContentType(int index);
-    method public default int getIndex(Object key);
-    method public int getItemCount();
-    method public default Object getKey(int index);
-    property public abstract int itemCount;
-  }
-
-  public final class LazyLayoutItemProviderKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
-  }
-
-  public final class LazyLayoutKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayout(androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider itemProvider, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState? prefetchState, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public sealed interface LazyLayoutMeasureScope extends androidx.compose.ui.layout.MeasureScope {
-    method public java.util.List<androidx.compose.ui.layout.Placeable> measure(int index, long constraints);
-    method @androidx.compose.runtime.Stable public default float toDp(float);
-    method @androidx.compose.runtime.Stable public default float toDp(int);
-    method @androidx.compose.runtime.Stable public default float toDp(long);
-    method @androidx.compose.runtime.Stable public default long toDpSize(long);
-    method @androidx.compose.runtime.Stable public default long toSize(long);
-    method @androidx.compose.runtime.Stable public default long toSp(float);
-    method @androidx.compose.runtime.Stable public default long toSp(float);
-    method @androidx.compose.runtime.Stable public default long toSp(int);
-  }
-
-  public final class LazyLayoutPinnableItemKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayoutPinnableItem(Object? key, int index, androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList pinnedItemList, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class LazyLayoutPinnedItemList implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList.PinnedItem> {
-    ctor public LazyLayoutPinnedItemList();
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static sealed interface LazyLayoutPinnedItemList.PinnedItem {
-    method public int getIndex();
-    method public Object? getKey();
-    property public abstract int index;
-    property public abstract Object? key;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class LazyLayoutPrefetchState {
-    ctor public LazyLayoutPrefetchState();
-    method public androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState.PrefetchHandle schedulePrefetch(int index, long constraints);
-  }
-
-  public static sealed interface LazyLayoutPrefetchState.PrefetchHandle {
-    method public void cancel();
-  }
-
-  public final class Lazy_androidKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class MutableIntervalList<T> implements androidx.compose.foundation.lazy.layout.IntervalList<T> {
-    ctor public MutableIntervalList();
-    method public void addInterval(int size, T value);
-    method public void forEach(int fromIndex, int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
-    method public androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
-    method public int getSize();
-    property public int size;
-  }
-
-}
-
 package androidx.compose.foundation.lazy.staggeredgrid {
 
   public final class LazyStaggeredGridDslKt {
@@ -884,7 +643,6 @@
   }
 
   @androidx.compose.runtime.Stable public sealed interface LazyStaggeredGridItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
   }
 
   public sealed interface LazyStaggeredGridLayoutInfo {
@@ -975,109 +733,6 @@
 
 }
 
-package androidx.compose.foundation.pager {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PageSize {
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fill implements androidx.compose.foundation.pager.PageSize {
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-    field public static final androidx.compose.foundation.pager.PageSize.Fill INSTANCE;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fixed implements androidx.compose.foundation.pager.PageSize {
-    ctor public PageSize.Fixed(float pageSize);
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-    method public float getPageSize();
-    property public final float pageSize;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
-    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.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 snapVelocityThreshold, optional float snapPositionalThreshold);
-    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.gestures.Orientation orientation);
-    field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
-  }
-
-  public final class PagerKt {
-    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerScope {
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PagerSnapDistance {
-    method public int calculateTargetPage(int startPage, int suggestedTargetPage, float velocity, int pageSize, int pageSpacing);
-    field public static final androidx.compose.foundation.pager.PagerSnapDistance.Companion Companion;
-  }
-
-  public static final class PagerSnapDistance.Companion {
-    method public androidx.compose.foundation.pager.PagerSnapDistance atMost(int pages);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public abstract class PagerState implements androidx.compose.foundation.gestures.ScrollableState {
-    ctor public PagerState(optional int initialPage, optional float initialPageOffsetFraction);
-    method public final suspend Object? animateScrollToPage(int page, optional float pageOffsetFraction, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public float dispatchRawDelta(float delta);
-    method public final boolean getCanScrollBackward();
-    method public final boolean getCanScrollForward();
-    method public final int getCurrentPage();
-    method public final float getCurrentPageOffsetFraction();
-    method public final int getInitialPage();
-    method public final float getInitialPageOffsetFraction();
-    method public final androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
-    method public final float getOffsetFractionForPage(int page);
-    method public abstract int getPageCount();
-    method public final int getSettledPage();
-    method public final int getTargetPage();
-    method public boolean isScrollInProgress();
-    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final suspend Object? scrollToPage(int page, optional float pageOffsetFraction, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final boolean canScrollBackward;
-    property public final boolean canScrollForward;
-    property public final int currentPage;
-    property public final float currentPageOffsetFraction;
-    property public final int initialPage;
-    property public final float initialPageOffsetFraction;
-    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
-    property public boolean isScrollInProgress;
-    property public abstract int pageCount;
-    property public final int settledPage;
-    property public final int targetPage;
-  }
-
-  public final class PagerStateKt {
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
-  }
-
-}
-
-package androidx.compose.foundation.relocation {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface BringIntoViewRequester {
-    method public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class BringIntoViewRequesterKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.relocation.BringIntoViewRequester BringIntoViewRequester();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewRequester(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewRequester bringIntoViewRequester);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public interface BringIntoViewResponder {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public suspend Object? bringChildIntoView(kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Rect> localRect, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.geometry.Rect calculateRectForParent(androidx.compose.ui.geometry.Rect localRect);
-  }
-
-  public final class BringIntoViewResponderKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewResponder(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewResponder responder);
-  }
-
-}
-
 package androidx.compose.foundation.selection {
 
   public final class SelectableGroupKt {
@@ -1221,7 +876,6 @@
 
   public final class ClickableTextKt {
     method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onHover, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
   }
 
   @androidx.compose.runtime.Immutable public final class InlineTextContent {
@@ -1236,9 +890,6 @@
     method public static void appendInlineContent(androidx.compose.ui.text.AnnotatedString.Builder, String id, optional String alternateText);
   }
 
-  @kotlin.RequiresOptIn(message="Internal/Unstable API for use only between foundation modules sharing " + "the same exact version, subject to change without notice.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationTextApi {
-  }
-
   public interface KeyboardActionScope {
     method public void defaultKeyboardAction(int imeAction);
   }
diff --git a/compose/foundation/foundation/api/public_plus_experimental_1.5.0-beta01.txt b/compose/foundation/foundation/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..15fd553
--- /dev/null
+++ b/compose/foundation/foundation/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,1314 @@
+// Signature format: 4.0
+package androidx.compose.foundation {
+
+  public final class BackgroundKt {
+    method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.Brush brush, optional androidx.compose.ui.graphics.Shape shape, optional float alpha);
+    method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
+  }
+
+  public final class BasicMarqueeKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeDelayMillis();
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeIterations();
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static float getDefaultMarqueeVelocity();
+    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeDelayMillis;
+    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeIterations;
+    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
+    property @androidx.compose.foundation.ExperimentalFoundationApi public static final float DefaultMarqueeVelocity;
+  }
+
+  public final class BorderKt {
+    method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, androidx.compose.foundation.BorderStroke border, optional androidx.compose.ui.graphics.Shape shape);
+    method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, float width, androidx.compose.ui.graphics.Brush brush, androidx.compose.ui.graphics.Shape shape);
+    method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, float width, long color, optional androidx.compose.ui.graphics.Shape shape);
+  }
+
+  @androidx.compose.runtime.Immutable public final class BorderStroke {
+    ctor public BorderStroke(float width, androidx.compose.ui.graphics.Brush brush);
+    method public androidx.compose.foundation.BorderStroke copy(optional float width, optional androidx.compose.ui.graphics.Brush brush);
+    method public androidx.compose.ui.graphics.Brush getBrush();
+    method public float getWidth();
+    property public final androidx.compose.ui.graphics.Brush brush;
+    property public final float width;
+  }
+
+  public final class BorderStrokeKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.BorderStroke BorderStroke(float width, long color);
+  }
+
+  public final class CanvasKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, String contentDescription, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
+    method @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
+  }
+
+  public final class CheckScrollableContainerConstraintsKt {
+    method public static void checkScrollableContainerConstraints(long constraints, androidx.compose.foundation.gestures.Orientation orientation);
+  }
+
+  public final class ClickableKt {
+    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+  }
+
+  public final class ClipScrollableContainerKt {
+    method public static androidx.compose.ui.Modifier clipScrollableContainer(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.Orientation orientation);
+  }
+
+  public final class DarkThemeKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static boolean isSystemInDarkTheme();
+  }
+
+  public final class ExcludeFromSystemGesture_androidKt {
+    method @Deprecated public static androidx.compose.ui.Modifier excludeFromSystemGesture(androidx.compose.ui.Modifier);
+    method @Deprecated public static androidx.compose.ui.Modifier excludeFromSystemGesture(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> exclusion);
+  }
+
+  @kotlin.RequiresOptIn(message="This foundation API is experimental and is likely to change or be removed in the " + "future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalFoundationApi {
+  }
+
+  public final class FocusableKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier focusGroup(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+  }
+
+  public final class FocusedBoundsKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier onFocusedBoundsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,kotlin.Unit> onPositioned);
+  }
+
+  public final class HoverableKt {
+    method public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
+  }
+
+  public final class ImageKt {
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Image(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Image(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int filterQuality);
+    method @androidx.compose.runtime.Composable public static void Image(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Image(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter);
+  }
+
+  @androidx.compose.runtime.Stable public interface Indication {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.IndicationInstance rememberUpdatedInstance(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+  }
+
+  public interface IndicationInstance {
+    method public void drawIndication(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
+  }
+
+  public final class IndicationKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> getLocalIndication();
+    method public static androidx.compose.ui.Modifier indication(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.foundation.Indication? indication);
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> LocalIndication;
+  }
+
+  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
+  }
+
+  public final class MagnifierKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier magnifier(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> sourceCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> magnifierCenter, optional float zoom, optional androidx.compose.foundation.MagnifierStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.DpSize,kotlin.Unit>? onSizeChanged);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class MagnifierStyle {
+    ctor @androidx.compose.foundation.ExperimentalFoundationApi public MagnifierStyle(optional long size, optional float cornerRadius, optional float elevation, optional boolean clippingEnabled, optional boolean fishEyeEnabled);
+    method public boolean isSupported();
+    property public final boolean isSupported;
+    field public static final androidx.compose.foundation.MagnifierStyle.Companion Companion;
+  }
+
+  public static final class MagnifierStyle.Companion {
+    method public androidx.compose.foundation.MagnifierStyle getDefault();
+    method public androidx.compose.foundation.MagnifierStyle getTextDefault();
+    property public final androidx.compose.foundation.MagnifierStyle Default;
+    property public final androidx.compose.foundation.MagnifierStyle TextDefault;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
+    field public static final androidx.compose.foundation.MarqueeAnimationMode.Companion Companion;
+  }
+
+  public static final class MarqueeAnimationMode.Companion {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public int getImmediately();
+    method @androidx.compose.foundation.ExperimentalFoundationApi public int getWhileFocused();
+    property @androidx.compose.foundation.ExperimentalFoundationApi public final int Immediately;
+    property @androidx.compose.foundation.ExperimentalFoundationApi public final int WhileFocused;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
+    field public static final androidx.compose.foundation.MarqueeSpacing.Companion Companion;
+  }
+
+  public static final class MarqueeSpacing.Companion {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
+  }
+
+  public enum MutatePriority {
+    method public static androidx.compose.foundation.MutatePriority valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.foundation.MutatePriority[] values();
+    enum_constant public static final androidx.compose.foundation.MutatePriority Default;
+    enum_constant public static final androidx.compose.foundation.MutatePriority PreventUserInput;
+    enum_constant public static final androidx.compose.foundation.MutatePriority UserInput;
+  }
+
+  @androidx.compose.runtime.Stable public final class MutatorMutex {
+    ctor public MutatorMutex();
+    method public suspend <R> Object? mutate(optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+    method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class OverscrollConfiguration {
+    ctor public OverscrollConfiguration(optional long glowColor, optional androidx.compose.foundation.layout.PaddingValues drawPadding);
+    method public androidx.compose.foundation.layout.PaddingValues getDrawPadding();
+    method public long getGlowColor();
+    property public final androidx.compose.foundation.layout.PaddingValues drawPadding;
+    property public final long glowColor;
+  }
+
+  public final class OverscrollConfigurationKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> getLocalOverscrollConfiguration();
+    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> LocalOverscrollConfiguration;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface OverscrollEffect {
+    method public suspend Object? applyToFling(long velocity, kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Velocity,? super kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>,?> performFling, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public long applyToScroll(long delta, int source, kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset> performScroll);
+    method public androidx.compose.ui.Modifier getEffectModifier();
+    method public boolean isInProgress();
+    property public abstract androidx.compose.ui.Modifier effectModifier;
+    property public abstract boolean isInProgress;
+  }
+
+  public final class OverscrollKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier overscroll(androidx.compose.ui.Modifier, androidx.compose.foundation.OverscrollEffect overscrollEffect);
+  }
+
+  public final class ProgressSemanticsKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier, float value, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps);
+  }
+
+  public final class ScrollKt {
+    method public static androidx.compose.ui.Modifier horizontalScroll(androidx.compose.ui.Modifier, androidx.compose.foundation.ScrollState state, optional boolean enabled, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional boolean reverseScrolling);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.ScrollState rememberScrollState(optional int initial);
+    method public static androidx.compose.ui.Modifier verticalScroll(androidx.compose.ui.Modifier, androidx.compose.foundation.ScrollState state, optional boolean enabled, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional boolean reverseScrolling);
+  }
+
+  @androidx.compose.runtime.Stable public final class ScrollState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public ScrollState(int initial);
+    method public suspend Object? animateScrollTo(int value, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public int getMaxValue();
+    method public int getValue();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? scrollTo(int value, kotlin.coroutines.Continuation<? super java.lang.Float>);
+    property public boolean canScrollBackward;
+    property public boolean canScrollForward;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
+    property public boolean isScrollInProgress;
+    property public final int maxValue;
+    property public final int value;
+    field public static final androidx.compose.foundation.ScrollState.Companion Companion;
+  }
+
+  public static final class ScrollState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.ScrollState,?> Saver;
+  }
+
+  public final class SystemGestureExclusionKt {
+    method public static androidx.compose.ui.Modifier systemGestureExclusion(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier systemGestureExclusion(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> exclusion);
+  }
+
+}
+
+package androidx.compose.foundation.gestures {
+
+  public final class DragGestureDetectorKt {
+    method public static suspend Object? awaitDragOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitHorizontalDragOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitHorizontalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitLongPressOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitTouchSlopOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitVerticalDragOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? awaitVerticalTouchSlopOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onTouchSlopReached, kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? detectDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? detectDragGesturesAfterLongPress(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? detectHorizontalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onHorizontalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? detectVerticalDragGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit> onDragStart, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragEnd, optional kotlin.jvm.functions.Function0<kotlin.Unit> onDragCancel, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputChange,? super java.lang.Float,kotlin.Unit> onVerticalDrag, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? drag(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public static suspend Object? horizontalDrag(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public static suspend Object? verticalDrag(androidx.compose.ui.input.pointer.AwaitPointerEventScope, long pointerId, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.pointer.PointerInputChange,kotlin.Unit> onDrag, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public interface DragScope {
+    method public void dragBy(float pixels);
+  }
+
+  public final class DraggableKt {
+    method public static androidx.compose.foundation.gestures.DraggableState DraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
+    method public static androidx.compose.ui.Modifier draggable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.DraggableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional boolean startDragImmediately, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStarted, optional kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Float,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onDragStopped, optional boolean reverseDirection);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.DraggableState rememberDraggableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onDelta);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface DraggableState {
+    method public void dispatchRawDelta(float delta);
+    method public suspend Object? drag(optional androidx.compose.foundation.MutatePriority dragPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.DragScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  @androidx.compose.runtime.Stable public interface FlingBehavior {
+    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
+  }
+
+  public final class ForEachGestureKt {
+    method public static suspend Object? awaitEachGesture(androidx.compose.ui.input.pointer.PointerInputScope, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.AwaitPointerEventScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @Deprecated public static suspend Object? forEachGesture(androidx.compose.ui.input.pointer.PointerInputScope, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class GestureCancellationException extends java.util.concurrent.CancellationException {
+    ctor public GestureCancellationException(optional String? message);
+  }
+
+  public enum Orientation {
+    method public static androidx.compose.foundation.gestures.Orientation valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.foundation.gestures.Orientation[] values();
+    enum_constant public static final androidx.compose.foundation.gestures.Orientation Horizontal;
+    enum_constant public static final androidx.compose.foundation.gestures.Orientation Vertical;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface PressGestureScope extends androidx.compose.ui.unit.Density {
+    method public suspend Object? awaitRelease(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? tryAwaitRelease(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public final class ScrollExtensionsKt {
+    method public static suspend Object? animateScrollBy(androidx.compose.foundation.gestures.ScrollableState, float value, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super java.lang.Float>);
+    method public static suspend Object? scrollBy(androidx.compose.foundation.gestures.ScrollableState, float value, kotlin.coroutines.Continuation<? super java.lang.Float>);
+    method public static suspend Object? stopScroll(androidx.compose.foundation.gestures.ScrollableState, optional androidx.compose.foundation.MutatePriority scrollPriority, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public interface ScrollScope {
+    method public float scrollBy(float pixels);
+  }
+
+  public final class ScrollableDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.FlingBehavior flingBehavior();
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public androidx.compose.foundation.OverscrollEffect overscrollEffect();
+    method public boolean reverseDirection(androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.foundation.gestures.Orientation orientation, boolean reverseScrolling);
+    field public static final androidx.compose.foundation.gestures.ScrollableDefaults INSTANCE;
+  }
+
+  public final class ScrollableKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, androidx.compose.foundation.OverscrollEffect? overscrollEffect, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+    method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ScrollableState {
+    method public float dispatchRawDelta(float delta);
+    method public default boolean getCanScrollBackward();
+    method public default boolean getCanScrollForward();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(optional androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public default boolean canScrollBackward;
+    property public default boolean canScrollForward;
+    property public abstract boolean isScrollInProgress;
+  }
+
+  public final class ScrollableStateKt {
+    method public static androidx.compose.foundation.gestures.ScrollableState ScrollableState(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> consumeScrollDelta);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.ScrollableState rememberScrollableState(kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> consumeScrollDelta);
+  }
+
+  public final class TapGestureDetectorKt {
+    method @Deprecated public static suspend androidx.compose.ui.input.pointer.PointerInputChange awaitFirstDown(androidx.compose.ui.input.pointer.AwaitPointerEventScope, optional boolean requireUnconsumed);
+    method public static suspend Object? awaitFirstDown(androidx.compose.ui.input.pointer.AwaitPointerEventScope, optional boolean requireUnconsumed, optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+    method public static suspend Object? detectTapGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit>? onDoubleTap, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit>? onLongPress, optional kotlin.jvm.functions.Function3<? super androidx.compose.foundation.gestures.PressGestureScope,? super androidx.compose.ui.geometry.Offset,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onPress, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,kotlin.Unit>? onTap, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @Deprecated public static suspend androidx.compose.ui.input.pointer.PointerInputChange? waitForUpOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope);
+    method public static suspend Object? waitForUpOrCancellation(androidx.compose.ui.input.pointer.AwaitPointerEventScope, optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerInputChange>);
+  }
+
+  public final class TransformGestureDetectorKt {
+    method public static long calculateCentroid(androidx.compose.ui.input.pointer.PointerEvent, optional boolean useCurrent);
+    method public static float calculateCentroidSize(androidx.compose.ui.input.pointer.PointerEvent, optional boolean useCurrent);
+    method public static long calculatePan(androidx.compose.ui.input.pointer.PointerEvent);
+    method public static float calculateRotation(androidx.compose.ui.input.pointer.PointerEvent);
+    method public static float calculateZoom(androidx.compose.ui.input.pointer.PointerEvent);
+    method public static suspend Object? detectTransformGestures(androidx.compose.ui.input.pointer.PointerInputScope, optional boolean panZoomLock, kotlin.jvm.functions.Function4<? super androidx.compose.ui.geometry.Offset,? super androidx.compose.ui.geometry.Offset,? super java.lang.Float,? super java.lang.Float,kotlin.Unit> onGesture, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface TransformScope {
+    method public void transformBy(optional float zoomChange, optional long panChange, optional float rotationChange);
+  }
+
+  public final class TransformableKt {
+    method public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, optional boolean lockRotationOnZoomPan, optional boolean enabled);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, kotlin.jvm.functions.Function0<java.lang.Boolean> canPan, optional boolean lockRotationOnZoomPan, optional boolean enabled);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface TransformableState {
+    method public boolean isTransformInProgress();
+    method public suspend Object? transform(optional androidx.compose.foundation.MutatePriority transformPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.TransformScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract boolean isTransformInProgress;
+  }
+
+  public final class TransformableStateKt {
+    method public static androidx.compose.foundation.gestures.TransformableState TransformableState(kotlin.jvm.functions.Function3<? super java.lang.Float,? super androidx.compose.ui.geometry.Offset,? super java.lang.Float,kotlin.Unit> onTransformation);
+    method public static suspend Object? animatePanBy(androidx.compose.foundation.gestures.TransformableState, long offset, optional androidx.compose.animation.core.AnimationSpec<androidx.compose.ui.geometry.Offset> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? animateRotateBy(androidx.compose.foundation.gestures.TransformableState, float degrees, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? animateZoomBy(androidx.compose.foundation.gestures.TransformableState, float zoomFactor, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? panBy(androidx.compose.foundation.gestures.TransformableState, long offset, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.TransformableState rememberTransformableState(kotlin.jvm.functions.Function3<? super java.lang.Float,? super androidx.compose.ui.geometry.Offset,? super java.lang.Float,kotlin.Unit> onTransformation);
+    method public static suspend Object? rotateBy(androidx.compose.foundation.gestures.TransformableState, float degrees, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? stopTransformation(androidx.compose.foundation.gestures.TransformableState, optional androidx.compose.foundation.MutatePriority terminationPriority, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? zoomBy(androidx.compose.foundation.gestures.TransformableState, float zoomFactor, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+}
+
+package androidx.compose.foundation.gestures.snapping {
+
+  public final class LazyGridSnapLayoutInfoProviderKt {
+    method @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.SnapPositionInLayout positionInLayout);
+  }
+
+  public final class LazyListSnapLayoutInfoProviderKt {
+    method @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.SnapPositionInLayout positionInLayout);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.FlingBehavior {
+    ctor 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, androidx.compose.ui.unit.Density density, optional float shortSnapVelocityThreshold);
+    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
+    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onSettlingDistanceUpdated, kotlin.coroutines.Continuation<? super java.lang.Float>);
+  }
+
+  public final class SnapFlingBehaviorKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.snapping.SnapFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public interface SnapLayoutInfoProvider {
+    method public float calculateApproachOffset(androidx.compose.ui.unit.Density, float initialVelocity);
+    method public float calculateSnapStepSize(androidx.compose.ui.unit.Density);
+    method public float calculateSnappingOffset(androidx.compose.ui.unit.Density, float currentVelocity);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public fun interface SnapPositionInLayout {
+    method public int position(androidx.compose.ui.unit.Density, int layoutSize, int itemSize, int itemIndex);
+    field public static final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion Companion;
+  }
+
+  public static final class SnapPositionInLayout.Companion {
+    method public androidx.compose.foundation.gestures.snapping.SnapPositionInLayout getCenterToCenter();
+    property public final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout CenterToCenter;
+  }
+
+}
+
+package androidx.compose.foundation.interaction {
+
+  public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class DragInteraction.Cancel implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Cancel(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public static final class DragInteraction.Start implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Start();
+  }
+
+  public static final class DragInteraction.Stop implements androidx.compose.foundation.interaction.DragInteraction {
+    ctor public DragInteraction.Stop(androidx.compose.foundation.interaction.DragInteraction.Start start);
+    method public androidx.compose.foundation.interaction.DragInteraction.Start getStart();
+    property public final androidx.compose.foundation.interaction.DragInteraction.Start start;
+  }
+
+  public final class DragInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsDraggedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface FocusInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class FocusInteraction.Focus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Focus();
+  }
+
+  public static final class FocusInteraction.Unfocus implements androidx.compose.foundation.interaction.FocusInteraction {
+    ctor public FocusInteraction.Unfocus(androidx.compose.foundation.interaction.FocusInteraction.Focus focus);
+    method public androidx.compose.foundation.interaction.FocusInteraction.Focus getFocus();
+    property public final androidx.compose.foundation.interaction.FocusInteraction.Focus focus;
+  }
+
+  public final class FocusInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsFocusedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface HoverInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class HoverInteraction.Enter implements androidx.compose.foundation.interaction.HoverInteraction {
+    ctor public HoverInteraction.Enter();
+  }
+
+  public static final class HoverInteraction.Exit implements androidx.compose.foundation.interaction.HoverInteraction {
+    ctor public HoverInteraction.Exit(androidx.compose.foundation.interaction.HoverInteraction.Enter enter);
+    method public androidx.compose.foundation.interaction.HoverInteraction.Enter getEnter();
+    property public final androidx.compose.foundation.interaction.HoverInteraction.Enter enter;
+  }
+
+  public final class HoverInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsHoveredAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+  public interface Interaction {
+  }
+
+  @androidx.compose.runtime.Stable public interface InteractionSource {
+    method public kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> getInteractions();
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.compose.foundation.interaction.Interaction> interactions;
+  }
+
+  public final class InteractionSourceKt {
+    method public static androidx.compose.foundation.interaction.MutableInteractionSource MutableInteractionSource();
+  }
+
+  @androidx.compose.runtime.Stable public interface MutableInteractionSource extends androidx.compose.foundation.interaction.InteractionSource {
+    method public suspend Object? emit(androidx.compose.foundation.interaction.Interaction interaction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean tryEmit(androidx.compose.foundation.interaction.Interaction interaction);
+  }
+
+  public interface PressInteraction extends androidx.compose.foundation.interaction.Interaction {
+  }
+
+  public static final class PressInteraction.Cancel implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Cancel(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public static final class PressInteraction.Press implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Press(long pressPosition);
+    method public long getPressPosition();
+    property public final long pressPosition;
+  }
+
+  public static final class PressInteraction.Release implements androidx.compose.foundation.interaction.PressInteraction {
+    ctor public PressInteraction.Release(androidx.compose.foundation.interaction.PressInteraction.Press press);
+    method public androidx.compose.foundation.interaction.PressInteraction.Press getPress();
+    property public final androidx.compose.foundation.interaction.PressInteraction.Press press;
+  }
+
+  public final class PressInteractionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> collectIsPressedAsState(androidx.compose.foundation.interaction.InteractionSource);
+  }
+
+}
+
+package androidx.compose.foundation.lazy {
+
+  public final class LazyDslKt {
+    method @androidx.compose.runtime.Composable public static void LazyColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.LazyListState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyListScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LazyColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.LazyListState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyListScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.LazyListState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyListScope,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LazyRow(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.LazyListState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.ui.Alignment.Vertical verticalAlignment, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyListScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function1<? super T,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method @Deprecated public static inline <T> void items(androidx.compose.foundation.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.LazyListScope, T![] items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function1<? super T,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method @Deprecated public static inline <T> void items(androidx.compose.foundation.lazy.LazyListScope, T![] items, optional kotlin.jvm.functions.Function1<? super T,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method @Deprecated public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.LazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.LazyListScope, T![] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method @Deprecated public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.LazyListScope, T![] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.compose.foundation.lazy.LazyScopeMarker @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyItemScope {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
+    method public androidx.compose.ui.Modifier fillParentMaxHeight(androidx.compose.ui.Modifier, optional float fraction);
+    method public androidx.compose.ui.Modifier fillParentMaxSize(androidx.compose.ui.Modifier, optional float fraction);
+    method public androidx.compose.ui.Modifier fillParentMaxWidth(androidx.compose.ui.Modifier, optional float fraction);
+  }
+
+  public interface LazyListItemInfo {
+    method public default Object? getContentType();
+    method public int getIndex();
+    method public Object getKey();
+    method public int getOffset();
+    method public int getSize();
+    property public default Object? contentType;
+    property public abstract int index;
+    property public abstract Object key;
+    property public abstract int offset;
+    property public abstract int size;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyListLayoutInfo {
+    method public default int getAfterContentPadding();
+    method public default int getBeforeContentPadding();
+    method public default int getMainAxisItemSpacing();
+    method public default androidx.compose.foundation.gestures.Orientation getOrientation();
+    method public default boolean getReverseLayout();
+    method public int getTotalItemsCount();
+    method public int getViewportEndOffset();
+    method public default long getViewportSize();
+    method public int getViewportStartOffset();
+    method public java.util.List<androidx.compose.foundation.lazy.LazyListItemInfo> getVisibleItemsInfo();
+    property public default int afterContentPadding;
+    property public default int beforeContentPadding;
+    property public default int mainAxisItemSpacing;
+    property public default androidx.compose.foundation.gestures.Orientation orientation;
+    property public default boolean reverseLayout;
+    property public abstract int totalItemsCount;
+    property public abstract int viewportEndOffset;
+    property public default long viewportSize;
+    property public abstract int viewportStartOffset;
+    property public abstract java.util.List<androidx.compose.foundation.lazy.LazyListItemInfo> visibleItemsInfo;
+  }
+
+  @androidx.compose.foundation.lazy.LazyScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyListScope {
+    method public default void item(optional Object? key, optional Object? contentType, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
+    method @Deprecated public void item(optional Object? key, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
+    method public default void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    method @Deprecated public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public void stickyHeader(optional Object? key, optional Object? contentType, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Stable public final class LazyListState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public LazyListState(optional int firstVisibleItemIndex, optional int firstVisibleItemScrollOffset);
+    method public suspend Object? animateScrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public int getFirstVisibleItemIndex();
+    method public int getFirstVisibleItemScrollOffset();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public androidx.compose.foundation.lazy.LazyListLayoutInfo getLayoutInfo();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean canScrollBackward;
+    property public boolean canScrollForward;
+    property public final int firstVisibleItemIndex;
+    property public final int firstVisibleItemScrollOffset;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
+    property public boolean isScrollInProgress;
+    property public final androidx.compose.foundation.lazy.LazyListLayoutInfo layoutInfo;
+    field public static final androidx.compose.foundation.lazy.LazyListState.Companion Companion;
+  }
+
+  public static final class LazyListState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.LazyListState,?> Saver;
+  }
+
+  public final class LazyListStateKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.lazy.LazyListState rememberLazyListState(optional int initialFirstVisibleItemIndex, optional int initialFirstVisibleItemScrollOffset);
+  }
+
+  @kotlin.DslMarker public @interface LazyScopeMarker {
+  }
+
+}
+
+package androidx.compose.foundation.lazy.grid {
+
+  @androidx.compose.runtime.Stable public interface GridCells {
+    method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class GridCells.Adaptive implements androidx.compose.foundation.lazy.grid.GridCells {
+    ctor public GridCells.Adaptive(float minSize);
+    method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class GridCells.Fixed implements androidx.compose.foundation.lazy.grid.GridCells {
+    ctor public GridCells.Fixed(int count);
+    method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class GridCells.FixedSize implements androidx.compose.foundation.lazy.grid.GridCells {
+    ctor public GridCells.FixedSize(float size);
+    method public java.util.List<java.lang.Integer> calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class GridItemSpan {
+    method public int getCurrentLineSpan();
+    property @androidx.compose.foundation.ExperimentalFoundationApi public final int currentLineSpan;
+  }
+
+  public final class LazyGridDslKt {
+    method @androidx.compose.runtime.Composable public static void LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells rows, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.grid.LazyGridState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.grid.LazyGridScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells columns, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.grid.LazyGridState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.grid.LazyGridScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.grid.LazyGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,? super T,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional kotlin.jvm.functions.Function1<? super T,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.grid.LazyGridScope, T![] items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,? super T,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional kotlin.jvm.functions.Function1<? super T,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.grid.LazyGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,? super java.lang.Integer,? super T,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.grid.LazyGridScope, T![] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,? super java.lang.Integer,? super T,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  public sealed interface LazyGridItemInfo {
+    method public int getColumn();
+    method public Object? getContentType();
+    method public int getIndex();
+    method public Object getKey();
+    method public long getOffset();
+    method public int getRow();
+    method public long getSize();
+    property public abstract int column;
+    property public abstract Object? contentType;
+    property public abstract int index;
+    property public abstract Object key;
+    property public abstract long offset;
+    property public abstract int row;
+    property public abstract long size;
+    field public static final androidx.compose.foundation.lazy.grid.LazyGridItemInfo.Companion Companion;
+    field public static final int UnknownColumn = -1; // 0xffffffff
+    field public static final int UnknownRow = -1; // 0xffffffff
+  }
+
+  public static final class LazyGridItemInfo.Companion {
+    field public static final int UnknownColumn = -1; // 0xffffffff
+    field public static final int UnknownRow = -1; // 0xffffffff
+  }
+
+  @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker @androidx.compose.runtime.Stable public sealed interface LazyGridItemScope {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
+  }
+
+  @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker public sealed interface LazyGridItemSpanScope {
+    method public int getMaxCurrentLineSpan();
+    method public int getMaxLineSpan();
+    property public abstract int maxCurrentLineSpan;
+    property public abstract int maxLineSpan;
+  }
+
+  public sealed interface LazyGridLayoutInfo {
+    method public int getAfterContentPadding();
+    method public int getBeforeContentPadding();
+    method public int getMainAxisItemSpacing();
+    method public androidx.compose.foundation.gestures.Orientation getOrientation();
+    method public boolean getReverseLayout();
+    method public int getTotalItemsCount();
+    method public int getViewportEndOffset();
+    method public long getViewportSize();
+    method public int getViewportStartOffset();
+    method public java.util.List<androidx.compose.foundation.lazy.grid.LazyGridItemInfo> getVisibleItemsInfo();
+    property public abstract int afterContentPadding;
+    property public abstract int beforeContentPadding;
+    property public abstract int mainAxisItemSpacing;
+    property public abstract androidx.compose.foundation.gestures.Orientation orientation;
+    property public abstract boolean reverseLayout;
+    property public abstract int totalItemsCount;
+    property public abstract int viewportEndOffset;
+    property public abstract long viewportSize;
+    property public abstract int viewportStartOffset;
+    property public abstract java.util.List<androidx.compose.foundation.lazy.grid.LazyGridItemInfo> visibleItemsInfo;
+  }
+
+  @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker public sealed interface LazyGridScope {
+    method public void item(optional Object? key, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional Object? contentType, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemSpanScope,? super java.lang.Integer,androidx.compose.foundation.lazy.grid.GridItemSpan>? span, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.grid.LazyGridItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+  }
+
+  @kotlin.DslMarker public @interface LazyGridScopeMarker {
+  }
+
+  public final class LazyGridSpanKt {
+    method public static long GridItemSpan(int currentLineSpan);
+  }
+
+  @androidx.compose.runtime.Stable public final class LazyGridState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public LazyGridState(optional int firstVisibleItemIndex, optional int firstVisibleItemScrollOffset);
+    method public suspend Object? animateScrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public int getFirstVisibleItemIndex();
+    method public int getFirstVisibleItemScrollOffset();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public androidx.compose.foundation.lazy.grid.LazyGridLayoutInfo getLayoutInfo();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean canScrollBackward;
+    property public boolean canScrollForward;
+    property public final int firstVisibleItemIndex;
+    property public final int firstVisibleItemScrollOffset;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
+    property public boolean isScrollInProgress;
+    property public final androidx.compose.foundation.lazy.grid.LazyGridLayoutInfo layoutInfo;
+    field public static final androidx.compose.foundation.lazy.grid.LazyGridState.Companion Companion;
+  }
+
+  public static final class LazyGridState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,?> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.grid.LazyGridState,?> Saver;
+  }
+
+  public final class LazyGridStateKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.lazy.grid.LazyGridState rememberLazyGridState(optional int initialFirstVisibleItemIndex, optional int initialFirstVisibleItemScrollOffset);
+  }
+
+}
+
+package androidx.compose.foundation.lazy.layout {
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface IntervalList<T> {
+    method public void forEach(optional int fromIndex, optional int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
+    method public operator androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
+    method public int getSize();
+    property public abstract int size;
+  }
+
+  public static final class IntervalList.Interval<T> {
+    method public int getSize();
+    method public int getStartIndex();
+    method public T getValue();
+    property public final int size;
+    property public final int startIndex;
+    property public final T value;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public abstract class LazyLayoutIntervalContent<Interval extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> {
+    ctor public LazyLayoutIntervalContent();
+    method public final Object? getContentType(int index);
+    method public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> getIntervals();
+    method public final int getItemCount();
+    method public final Object getKey(int index);
+    method public final inline <T> T withInterval(int globalIndex, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super Interval,? extends T> block);
+    property public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> intervals;
+    property public final int itemCount;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public static interface LazyLayoutIntervalContent.Interval {
+    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? getKey();
+    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> getType();
+    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? key;
+    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> type;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface LazyLayoutItemProvider {
+    method @androidx.compose.runtime.Composable public void Item(int index, Object key);
+    method public default Object? getContentType(int index);
+    method public default int getIndex(Object key);
+    method public int getItemCount();
+    method public default Object getKey(int index);
+    property public abstract int itemCount;
+  }
+
+  public final class LazyLayoutItemProviderKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
+  }
+
+  public final class LazyLayoutKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayout(androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider itemProvider, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState? prefetchState, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public sealed interface LazyLayoutMeasureScope extends androidx.compose.ui.layout.MeasureScope {
+    method public java.util.List<androidx.compose.ui.layout.Placeable> measure(int index, long constraints);
+    method @androidx.compose.runtime.Stable public default float toDp(float);
+    method @androidx.compose.runtime.Stable public default float toDp(int);
+    method @androidx.compose.runtime.Stable public default float toDp(long);
+    method @androidx.compose.runtime.Stable public default long toDpSize(long);
+    method @androidx.compose.runtime.Stable public default long toSize(long);
+    method @androidx.compose.runtime.Stable public default long toSp(float);
+    method @androidx.compose.runtime.Stable public default long toSp(float);
+    method @androidx.compose.runtime.Stable public default long toSp(int);
+  }
+
+  public final class LazyLayoutPinnableItemKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayoutPinnableItem(Object? key, int index, androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList pinnedItemList, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public final class LazyLayoutPinnedItemList implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList.PinnedItem> {
+    ctor public LazyLayoutPinnedItemList();
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public static sealed interface LazyLayoutPinnedItemList.PinnedItem {
+    method public int getIndex();
+    method public Object? getKey();
+    property public abstract int index;
+    property public abstract Object? key;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class LazyLayoutPrefetchState {
+    ctor public LazyLayoutPrefetchState();
+    method public androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState.PrefetchHandle schedulePrefetch(int index, long constraints);
+  }
+
+  public static sealed interface LazyLayoutPrefetchState.PrefetchHandle {
+    method public void cancel();
+  }
+
+  public final class Lazy_androidKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public final class MutableIntervalList<T> implements androidx.compose.foundation.lazy.layout.IntervalList<T> {
+    ctor public MutableIntervalList();
+    method public void addInterval(int size, T value);
+    method public void forEach(int fromIndex, int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
+    method public androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
+    method public int getSize();
+    property public int size;
+  }
+
+}
+
+package androidx.compose.foundation.lazy.staggeredgrid {
+
+  public final class LazyStaggeredGridDslKt {
+    method @androidx.compose.runtime.Composable public static void LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells rows, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional float horizontalItemSpacing, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells columns, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional float verticalItemSpacing, optional androidx.compose.foundation.layout.Arrangement.Horizontal horizontalArrangement, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function1<? super T,?> contentType, optional kotlin.jvm.functions.Function1<? super T,androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan>? span, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope, T![] items, optional kotlin.jvm.functions.Function1<? super T,?>? key, optional kotlin.jvm.functions.Function1<? super T,?> contentType, optional kotlin.jvm.functions.Function1<? super T,androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan>? span, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan>? span, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope, T![] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?> contentType, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan>? span, kotlin.jvm.functions.Function3<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  public sealed interface LazyStaggeredGridItemInfo {
+    method public Object? getContentType();
+    method public int getIndex();
+    method public Object getKey();
+    method public int getLane();
+    method public long getOffset();
+    method public long getSize();
+    property public abstract Object? contentType;
+    property public abstract int index;
+    property public abstract Object key;
+    property public abstract int lane;
+    property public abstract long offset;
+    property public abstract long size;
+  }
+
+  @androidx.compose.runtime.Stable public sealed interface LazyStaggeredGridItemScope {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
+  }
+
+  public sealed interface LazyStaggeredGridLayoutInfo {
+    method public int getAfterContentPadding();
+    method public int getBeforeContentPadding();
+    method public int getMainAxisItemSpacing();
+    method public androidx.compose.foundation.gestures.Orientation getOrientation();
+    method public int getTotalItemsCount();
+    method public int getViewportEndOffset();
+    method public long getViewportSize();
+    method public int getViewportStartOffset();
+    method public java.util.List<androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemInfo> getVisibleItemsInfo();
+    property public abstract int afterContentPadding;
+    property public abstract int beforeContentPadding;
+    property public abstract int mainAxisItemSpacing;
+    property public abstract androidx.compose.foundation.gestures.Orientation orientation;
+    property public abstract int totalItemsCount;
+    property public abstract int viewportEndOffset;
+    property public abstract long viewportSize;
+    property public abstract int viewportStartOffset;
+    property public abstract java.util.List<androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemInfo> visibleItemsInfo;
+  }
+
+  public sealed interface LazyStaggeredGridScope {
+    method public void item(optional Object? key, optional Object? contentType, optional androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan? span, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?> contentType, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan>? span, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+  }
+
+  public final class LazyStaggeredGridState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public LazyStaggeredGridState(optional int initialFirstVisibleItemIndex, optional int initialFirstVisibleItemOffset);
+    method public suspend Object? animateScrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public int getFirstVisibleItemIndex();
+    method public int getFirstVisibleItemScrollOffset();
+    method public androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridLayoutInfo getLayoutInfo();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean canScrollBackward;
+    property public boolean canScrollForward;
+    property public final int firstVisibleItemIndex;
+    property public final int firstVisibleItemScrollOffset;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
+    property public boolean isScrollInProgress;
+    property public final androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridLayoutInfo layoutInfo;
+    field public static final androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState.Companion Companion;
+  }
+
+  public static final class LazyStaggeredGridState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,java.lang.Object> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,java.lang.Object> Saver;
+  }
+
+  public final class LazyStaggeredGridStateKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState rememberLazyStaggeredGridState(optional int initialFirstVisibleItemIndex, optional int initialFirstVisibleItemScrollOffset);
+  }
+
+  @androidx.compose.runtime.Stable public interface StaggeredGridCells {
+    method public int[] calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class StaggeredGridCells.Adaptive implements androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells {
+    ctor public StaggeredGridCells.Adaptive(float minSize);
+    method public int[] calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class StaggeredGridCells.Fixed implements androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells {
+    ctor public StaggeredGridCells.Fixed(int count);
+    method public int[] calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public static final class StaggeredGridCells.FixedSize implements androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells {
+    ctor public StaggeredGridCells.FixedSize(float size);
+    method public int[] calculateCrossAxisCellSizes(androidx.compose.ui.unit.Density, int availableSize, int spacing);
+  }
+
+  public final class StaggeredGridItemSpan {
+    field public static final androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan.Companion Companion;
+  }
+
+  public static final class StaggeredGridItemSpan.Companion {
+    method public androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan getFullLine();
+    method public androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan getSingleLane();
+    property public final androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan FullLine;
+    property public final androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan SingleLane;
+  }
+
+}
+
+package androidx.compose.foundation.pager {
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PageSize {
+    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fill implements androidx.compose.foundation.pager.PageSize {
+    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
+    field public static final androidx.compose.foundation.pager.PageSize.Fill INSTANCE;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fixed implements androidx.compose.foundation.pager.PageSize {
+    ctor public PageSize.Fixed(float pageSize);
+    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
+    method public float getPageSize();
+    property public final float pageSize;
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
+    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.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 snapVelocityThreshold, optional float snapPositionalThreshold);
+    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.gestures.Orientation orientation);
+    field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
+  }
+
+  public final class PagerKt {
+    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerScope {
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PagerSnapDistance {
+    method public int calculateTargetPage(int startPage, int suggestedTargetPage, float velocity, int pageSize, int pageSpacing);
+    field public static final androidx.compose.foundation.pager.PagerSnapDistance.Companion Companion;
+  }
+
+  public static final class PagerSnapDistance.Companion {
+    method public androidx.compose.foundation.pager.PagerSnapDistance atMost(int pages);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public abstract class PagerState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public PagerState(optional int initialPage, optional float initialPageOffsetFraction);
+    method public final suspend Object? animateScrollToPage(int page, optional float pageOffsetFraction, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public final boolean getCanScrollBackward();
+    method public final boolean getCanScrollForward();
+    method public final int getCurrentPage();
+    method public final float getCurrentPageOffsetFraction();
+    method public final int getInitialPage();
+    method public final float getInitialPageOffsetFraction();
+    method public final androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
+    method public final float getOffsetFractionForPage(int page);
+    method public abstract int getPageCount();
+    method public final int getSettledPage();
+    method public final int getTargetPage();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public final suspend Object? scrollToPage(int page, optional float pageOffsetFraction, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final boolean canScrollBackward;
+    property public final boolean canScrollForward;
+    property public final int currentPage;
+    property public final float currentPageOffsetFraction;
+    property public final int initialPage;
+    property public final float initialPageOffsetFraction;
+    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
+    property public boolean isScrollInProgress;
+    property public abstract int pageCount;
+    property public final int settledPage;
+    property public final int targetPage;
+  }
+
+  public final class PagerStateKt {
+    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
+  }
+
+}
+
+package androidx.compose.foundation.relocation {
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface BringIntoViewRequester {
+    method public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class BringIntoViewRequesterKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.relocation.BringIntoViewRequester BringIntoViewRequester();
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewRequester(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewRequester bringIntoViewRequester);
+  }
+
+  @androidx.compose.foundation.ExperimentalFoundationApi public interface BringIntoViewResponder {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public suspend Object? bringChildIntoView(kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Rect> localRect, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.geometry.Rect calculateRectForParent(androidx.compose.ui.geometry.Rect localRect);
+  }
+
+  public final class BringIntoViewResponderKt {
+    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewResponder(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewResponder responder);
+  }
+
+}
+
+package androidx.compose.foundation.selection {
+
+  public final class SelectableGroupKt {
+    method public static androidx.compose.ui.Modifier selectableGroup(androidx.compose.ui.Modifier);
+  }
+
+  public final class SelectableKt {
+    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier selectable(androidx.compose.ui.Modifier, boolean selected, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+  }
+
+  public final class ToggleableKt {
+    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
+    method public static androidx.compose.ui.Modifier toggleable(androidx.compose.ui.Modifier, boolean value, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onValueChange);
+    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+    method public static androidx.compose.ui.Modifier triStateToggleable(androidx.compose.ui.Modifier, androidx.compose.ui.state.ToggleableState state, optional boolean enabled, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
+  }
+
+}
+
+package androidx.compose.foundation.shape {
+
+  public final class AbsoluteCutCornerShape extends androidx.compose.foundation.shape.CornerBasedShape {
+    ctor public AbsoluteCutCornerShape(androidx.compose.foundation.shape.CornerSize topLeft, androidx.compose.foundation.shape.CornerSize topRight, androidx.compose.foundation.shape.CornerSize bottomRight, androidx.compose.foundation.shape.CornerSize bottomLeft);
+    method public androidx.compose.foundation.shape.AbsoluteCutCornerShape copy(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, float topStart, float topEnd, float bottomEnd, float bottomStart, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+  }
+
+  public final class AbsoluteCutCornerShapeKt {
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(androidx.compose.foundation.shape.CornerSize corner);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(float size);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(float size);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(optional float topLeft, optional float topRight, optional float bottomRight, optional float bottomLeft);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(optional float topLeft, optional float topRight, optional float bottomRight, optional float bottomLeft);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(int percent);
+    method public static androidx.compose.foundation.shape.AbsoluteCutCornerShape AbsoluteCutCornerShape(optional int topLeftPercent, optional int topRightPercent, optional int bottomRightPercent, optional int bottomLeftPercent);
+  }
+
+  public final class AbsoluteRoundedCornerShape extends androidx.compose.foundation.shape.CornerBasedShape {
+    ctor public AbsoluteRoundedCornerShape(androidx.compose.foundation.shape.CornerSize topLeft, androidx.compose.foundation.shape.CornerSize topRight, androidx.compose.foundation.shape.CornerSize bottomRight, androidx.compose.foundation.shape.CornerSize bottomLeft);
+    method public androidx.compose.foundation.shape.AbsoluteRoundedCornerShape copy(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, float topStart, float topEnd, float bottomEnd, float bottomStart, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+  }
+
+  public final class AbsoluteRoundedCornerShapeKt {
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(androidx.compose.foundation.shape.CornerSize corner);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(float size);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(float size);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(optional float topLeft, optional float topRight, optional float bottomRight, optional float bottomLeft);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(optional float topLeft, optional float topRight, optional float bottomRight, optional float bottomLeft);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(int percent);
+    method public static androidx.compose.foundation.shape.AbsoluteRoundedCornerShape AbsoluteRoundedCornerShape(optional int topLeftPercent, optional int topRightPercent, optional int bottomRightPercent, optional int bottomLeftPercent);
+  }
+
+  public abstract class CornerBasedShape implements androidx.compose.ui.graphics.Shape {
+    ctor public CornerBasedShape(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public final androidx.compose.foundation.shape.CornerBasedShape copy(androidx.compose.foundation.shape.CornerSize all);
+    method public abstract androidx.compose.foundation.shape.CornerBasedShape copy(optional androidx.compose.foundation.shape.CornerSize topStart, optional androidx.compose.foundation.shape.CornerSize topEnd, optional androidx.compose.foundation.shape.CornerSize bottomEnd, optional androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public final androidx.compose.ui.graphics.Outline createOutline(long size, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.unit.Density density);
+    method public abstract androidx.compose.ui.graphics.Outline createOutline(long size, float topStart, float topEnd, float bottomEnd, float bottomStart, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public final androidx.compose.foundation.shape.CornerSize getBottomEnd();
+    method public final androidx.compose.foundation.shape.CornerSize getBottomStart();
+    method public final androidx.compose.foundation.shape.CornerSize getTopEnd();
+    method public final androidx.compose.foundation.shape.CornerSize getTopStart();
+    property public final androidx.compose.foundation.shape.CornerSize bottomEnd;
+    property public final androidx.compose.foundation.shape.CornerSize bottomStart;
+    property public final androidx.compose.foundation.shape.CornerSize topEnd;
+    property public final androidx.compose.foundation.shape.CornerSize topStart;
+  }
+
+  @androidx.compose.runtime.Immutable public interface CornerSize {
+    method public float toPx(long shapeSize, androidx.compose.ui.unit.Density density);
+  }
+
+  public final class CornerSizeKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.shape.CornerSize CornerSize(float size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.shape.CornerSize CornerSize(float size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.foundation.shape.CornerSize CornerSize(int percent);
+    method public static androidx.compose.foundation.shape.CornerSize getZeroCornerSize();
+    property public static final androidx.compose.foundation.shape.CornerSize ZeroCornerSize;
+  }
+
+  public final class CutCornerShape extends androidx.compose.foundation.shape.CornerBasedShape {
+    ctor public CutCornerShape(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.foundation.shape.CutCornerShape copy(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, float topStart, float topEnd, float bottomEnd, float bottomStart, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+  }
+
+  public final class CutCornerShapeKt {
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(androidx.compose.foundation.shape.CornerSize corner);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(float size);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(float size);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(optional float topStart, optional float topEnd, optional float bottomEnd, optional float bottomStart);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(optional float topStart, optional float topEnd, optional float bottomEnd, optional float bottomStart);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(int percent);
+    method public static androidx.compose.foundation.shape.CutCornerShape CutCornerShape(optional int topStartPercent, optional int topEndPercent, optional int bottomEndPercent, optional int bottomStartPercent);
+  }
+
+  public final class GenericShape implements androidx.compose.ui.graphics.Shape {
+    ctor public GenericShape(kotlin.jvm.functions.Function3<? super androidx.compose.ui.graphics.Path,? super androidx.compose.ui.geometry.Size,? super androidx.compose.ui.unit.LayoutDirection,kotlin.Unit> builder);
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.unit.Density density);
+  }
+
+  public final class RoundedCornerShape extends androidx.compose.foundation.shape.CornerBasedShape {
+    ctor public RoundedCornerShape(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.foundation.shape.RoundedCornerShape copy(androidx.compose.foundation.shape.CornerSize topStart, androidx.compose.foundation.shape.CornerSize topEnd, androidx.compose.foundation.shape.CornerSize bottomEnd, androidx.compose.foundation.shape.CornerSize bottomStart);
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, float topStart, float topEnd, float bottomEnd, float bottomStart, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+  }
+
+  public final class RoundedCornerShapeKt {
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(androidx.compose.foundation.shape.CornerSize corner);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(float size);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(float size);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(optional float topStart, optional float topEnd, optional float bottomEnd, optional float bottomStart);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(optional float topStart, optional float topEnd, optional float bottomEnd, optional float bottomStart);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(int percent);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape RoundedCornerShape(optional int topStartPercent, optional int topEndPercent, optional int bottomEndPercent, optional int bottomStartPercent);
+    method public static androidx.compose.foundation.shape.RoundedCornerShape getCircleShape();
+    property public static final androidx.compose.foundation.shape.RoundedCornerShape CircleShape;
+  }
+
+}
+
+package androidx.compose.foundation.text {
+
+  public final class BasicTextFieldKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicTextField(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 androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(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 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.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicTextField(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 androidx.compose.foundation.text.KeyboardOptions keyboardOptions, optional androidx.compose.foundation.text.KeyboardActions keyboardActions, optional boolean singleLine, optional int maxLines, optional androidx.compose.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+    method @androidx.compose.runtime.Composable public static void BasicTextField(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 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.ui.text.input.VisualTransformation visualTransformation, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Brush cursorBrush, optional kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> decorationBox);
+  }
+
+  public final class BasicTextKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent);
+    method @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional androidx.compose.ui.graphics.ColorProducer? color);
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent);
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicText(String text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines);
+    method @Deprecated @androidx.compose.runtime.Composable public static void BasicText(String text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines);
+    method @androidx.compose.runtime.Composable public static void BasicText(String text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional androidx.compose.ui.graphics.ColorProducer? color);
+  }
+
+  public final class ClickableTextKt {
+    method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onHover, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
+  }
+
+  @androidx.compose.runtime.Immutable public final class InlineTextContent {
+    ctor public InlineTextContent(androidx.compose.ui.text.Placeholder placeholder, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit> children);
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit> getChildren();
+    method public androidx.compose.ui.text.Placeholder getPlaceholder();
+    property public final kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit> children;
+    property public final androidx.compose.ui.text.Placeholder placeholder;
+  }
+
+  public final class InlineTextContentKt {
+    method public static void appendInlineContent(androidx.compose.ui.text.AnnotatedString.Builder, String id, optional String alternateText);
+  }
+
+  @kotlin.RequiresOptIn(message="Internal/Unstable API for use only between foundation modules sharing " + "the same exact version, subject to change without notice.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationTextApi {
+  }
+
+  public interface KeyboardActionScope {
+    method public void defaultKeyboardAction(int imeAction);
+  }
+
+  @androidx.compose.runtime.Stable public final class KeyboardActions {
+    ctor public KeyboardActions(optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onDone, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onGo, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onNext, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onPrevious, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onSearch, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onSend);
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnDone();
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnGo();
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnNext();
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnPrevious();
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnSearch();
+    method public kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? getOnSend();
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onDone;
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onGo;
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onNext;
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onPrevious;
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onSearch;
+    property public final kotlin.jvm.functions.Function1<androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit>? onSend;
+    field public static final androidx.compose.foundation.text.KeyboardActions.Companion Companion;
+  }
+
+  public static final class KeyboardActions.Companion {
+    method public androidx.compose.foundation.text.KeyboardActions getDefault();
+    property public final androidx.compose.foundation.text.KeyboardActions Default;
+  }
+
+  public final class KeyboardActionsKt {
+    method public static androidx.compose.foundation.text.KeyboardActions KeyboardActions(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.text.KeyboardActionScope,kotlin.Unit> onAny);
+  }
+
+  @androidx.compose.runtime.Immutable public final class KeyboardOptions {
+    ctor public KeyboardOptions(optional int capitalization, optional boolean autoCorrect, optional int keyboardType, optional int imeAction);
+    method public androidx.compose.foundation.text.KeyboardOptions copy(optional int capitalization, optional boolean autoCorrect, optional int keyboardType, optional int imeAction);
+    method public boolean getAutoCorrect();
+    method public int getCapitalization();
+    method public int getImeAction();
+    method public int getKeyboardType();
+    property public final boolean autoCorrect;
+    property public final int capitalization;
+    property public final int imeAction;
+    property public final int keyboardType;
+    field public static final androidx.compose.foundation.text.KeyboardOptions.Companion Companion;
+  }
+
+  public static final class KeyboardOptions.Companion {
+    method public androidx.compose.foundation.text.KeyboardOptions getDefault();
+    property public final androidx.compose.foundation.text.KeyboardOptions Default;
+  }
+
+}
+
+package androidx.compose.foundation.text.selection {
+
+  public final class SelectionContainerKt {
+    method @androidx.compose.runtime.Composable public static void DisableSelection(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void SelectionContainer(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextSelectionColors {
+    ctor public TextSelectionColors(long handleColor, long backgroundColor);
+    method public long getBackgroundColor();
+    method public long getHandleColor();
+    property public final long backgroundColor;
+    property public final long handleColor;
+  }
+
+  public final class TextSelectionColorsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.text.selection.TextSelectionColors> getLocalTextSelectionColors();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.text.selection.TextSelectionColors> LocalTextSelectionColors;
+  }
+
+}
+
diff --git a/compose/foundation/foundation/api/restricted_1.5.0-beta01.txt b/compose/foundation/foundation/api/restricted_1.5.0-beta01.txt
index 15fd553..8be51e4 100644
--- a/compose/foundation/foundation/api/restricted_1.5.0-beta01.txt
+++ b/compose/foundation/foundation/api/restricted_1.5.0-beta01.txt
@@ -6,19 +6,6 @@
     method public static androidx.compose.ui.Modifier background(androidx.compose.ui.Modifier, long color, optional androidx.compose.ui.graphics.Shape shape);
   }
 
-  public final class BasicMarqueeKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing MarqueeSpacing(float spacing);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier basicMarquee(androidx.compose.ui.Modifier, optional int iterations, optional int animationMode, optional int delayMillis, optional int initialDelayMillis, optional androidx.compose.foundation.MarqueeSpacing spacing, optional float velocity);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeDelayMillis();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static int getDefaultMarqueeIterations();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.MarqueeSpacing getDefaultMarqueeSpacing();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static float getDefaultMarqueeVelocity();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeDelayMillis;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final int DefaultMarqueeIterations;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.foundation.MarqueeSpacing DefaultMarqueeSpacing;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final float DefaultMarqueeVelocity;
-  }
-
   public final class BorderKt {
     method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, androidx.compose.foundation.BorderStroke border, optional androidx.compose.ui.graphics.Shape shape);
     method public static androidx.compose.ui.Modifier border(androidx.compose.ui.Modifier, float width, androidx.compose.ui.graphics.Brush brush, androidx.compose.ui.graphics.Shape shape);
@@ -39,7 +26,6 @@
   }
 
   public final class CanvasKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, String contentDescription, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
     method @androidx.compose.runtime.Composable public static void Canvas(androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
   }
 
@@ -50,8 +36,6 @@
   public final class ClickableKt {
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
     method public static androidx.compose.ui.Modifier clickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier combinedClickable(androidx.compose.ui.Modifier, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, optional String? onLongClickLabel, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onLongClick, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDoubleClick, kotlin.jvm.functions.Function0<kotlin.Unit> onClick);
   }
 
   public final class ClipScrollableContainerKt {
@@ -67,18 +51,10 @@
     method @Deprecated public static androidx.compose.ui.Modifier excludeFromSystemGesture(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> exclusion);
   }
 
-  @kotlin.RequiresOptIn(message="This foundation API is experimental and is likely to change or be removed in the " + "future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalFoundationApi {
-  }
-
   public final class FocusableKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier focusGroup(androidx.compose.ui.Modifier);
     method public static androidx.compose.ui.Modifier focusable(androidx.compose.ui.Modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
-  public final class FocusedBoundsKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier onFocusedBoundsChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,kotlin.Unit> onPositioned);
-  }
-
   public final class HoverableKt {
     method public static androidx.compose.ui.Modifier hoverable(androidx.compose.ui.Modifier, androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional boolean enabled);
   }
@@ -104,47 +80,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.Indication> LocalIndication;
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationApi {
-  }
-
-  public final class MagnifierKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier magnifier(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> sourceCenter, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Density,androidx.compose.ui.geometry.Offset> magnifierCenter, optional float zoom, optional androidx.compose.foundation.MagnifierStyle style, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.DpSize,kotlin.Unit>? onSizeChanged);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class MagnifierStyle {
-    ctor @androidx.compose.foundation.ExperimentalFoundationApi public MagnifierStyle(optional long size, optional float cornerRadius, optional float elevation, optional boolean clippingEnabled, optional boolean fishEyeEnabled);
-    method public boolean isSupported();
-    property public final boolean isSupported;
-    field public static final androidx.compose.foundation.MagnifierStyle.Companion Companion;
-  }
-
-  public static final class MagnifierStyle.Companion {
-    method public androidx.compose.foundation.MagnifierStyle getDefault();
-    method public androidx.compose.foundation.MagnifierStyle getTextDefault();
-    property public final androidx.compose.foundation.MagnifierStyle Default;
-    property public final androidx.compose.foundation.MagnifierStyle TextDefault;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @kotlin.jvm.JvmInline public final value class MarqueeAnimationMode {
-    field public static final androidx.compose.foundation.MarqueeAnimationMode.Companion Companion;
-  }
-
-  public static final class MarqueeAnimationMode.Companion {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int getImmediately();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int getWhileFocused();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int Immediately;
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int WhileFocused;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public fun interface MarqueeSpacing {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public int calculateSpacing(androidx.compose.ui.unit.Density, int contentWidth, int containerWidth);
-    field public static final androidx.compose.foundation.MarqueeSpacing.Companion Companion;
-  }
-
-  public static final class MarqueeSpacing.Companion {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.foundation.MarqueeSpacing fractionOfContainer(float fraction);
-  }
-
   public enum MutatePriority {
     method public static androidx.compose.foundation.MutatePriority valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.compose.foundation.MutatePriority[] values();
@@ -159,32 +94,6 @@
     method public suspend <T, R> Object? mutateWith(T receiver, optional androidx.compose.foundation.MutatePriority priority, kotlin.jvm.functions.Function2<? super T,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
   }
 
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class OverscrollConfiguration {
-    ctor public OverscrollConfiguration(optional long glowColor, optional androidx.compose.foundation.layout.PaddingValues drawPadding);
-    method public androidx.compose.foundation.layout.PaddingValues getDrawPadding();
-    method public long getGlowColor();
-    property public final androidx.compose.foundation.layout.PaddingValues drawPadding;
-    property public final long glowColor;
-  }
-
-  public final class OverscrollConfigurationKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> getLocalOverscrollConfiguration();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.foundation.OverscrollConfiguration> LocalOverscrollConfiguration;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface OverscrollEffect {
-    method public suspend Object? applyToFling(long velocity, kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Velocity,? super kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>,?> performFling, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public long applyToScroll(long delta, int source, kotlin.jvm.functions.Function1<? super androidx.compose.ui.geometry.Offset,androidx.compose.ui.geometry.Offset> performScroll);
-    method public androidx.compose.ui.Modifier getEffectModifier();
-    method public boolean isInProgress();
-    property public abstract androidx.compose.ui.Modifier effectModifier;
-    property public abstract boolean isInProgress;
-  }
-
-  public final class OverscrollKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier overscroll(androidx.compose.ui.Modifier, androidx.compose.foundation.OverscrollEffect overscrollEffect);
-  }
-
   public final class ProgressSemanticsKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier progressSemantics(androidx.compose.ui.Modifier, float value, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps);
@@ -298,13 +207,11 @@
 
   public final class ScrollableDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.FlingBehavior flingBehavior();
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public androidx.compose.foundation.OverscrollEffect overscrollEffect();
     method public boolean reverseDirection(androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.foundation.gestures.Orientation orientation, boolean reverseScrolling);
     field public static final androidx.compose.foundation.gestures.ScrollableDefaults INSTANCE;
   }
 
   public final class ScrollableKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, androidx.compose.foundation.OverscrollEffect? overscrollEffect, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
     method public static androidx.compose.ui.Modifier scrollable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.ScrollableState state, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.gestures.FlingBehavior? flingBehavior, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource);
   }
 
@@ -347,7 +254,6 @@
 
   public final class TransformableKt {
     method public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, optional boolean lockRotationOnZoomPan, optional boolean enabled);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier transformable(androidx.compose.ui.Modifier, androidx.compose.foundation.gestures.TransformableState state, kotlin.jvm.functions.Function0<java.lang.Boolean> canPan, optional boolean lockRotationOnZoomPan, optional boolean enabled);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface TransformableState {
@@ -370,45 +276,6 @@
 
 }
 
-package androidx.compose.foundation.gestures.snapping {
-
-  public final class LazyGridSnapLayoutInfoProviderKt {
-    method @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.SnapPositionInLayout positionInLayout);
-  }
-
-  public final class LazyListSnapLayoutInfoProviderKt {
-    method @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.SnapPositionInLayout positionInLayout);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.FlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.lazy.LazyListState lazyListState);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class SnapFlingBehavior implements androidx.compose.foundation.gestures.FlingBehavior {
-    ctor 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, androidx.compose.ui.unit.Density density, optional float shortSnapVelocityThreshold);
-    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.coroutines.Continuation<? super java.lang.Float>);
-    method public suspend Object? performFling(androidx.compose.foundation.gestures.ScrollScope, float initialVelocity, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onSettlingDistanceUpdated, kotlin.coroutines.Continuation<? super java.lang.Float>);
-  }
-
-  public final class SnapFlingBehaviorKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.gestures.snapping.SnapFlingBehavior rememberSnapFlingBehavior(androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider snapLayoutInfoProvider);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public interface SnapLayoutInfoProvider {
-    method public float calculateApproachOffset(androidx.compose.ui.unit.Density, float initialVelocity);
-    method public float calculateSnapStepSize(androidx.compose.ui.unit.Density);
-    method public float calculateSnappingOffset(androidx.compose.ui.unit.Density, float currentVelocity);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public fun interface SnapPositionInLayout {
-    method public int position(androidx.compose.ui.unit.Density, int layoutSize, int itemSize, int itemIndex);
-    field public static final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion Companion;
-  }
-
-  public static final class SnapPositionInLayout.Companion {
-    method public androidx.compose.foundation.gestures.snapping.SnapPositionInLayout getCenterToCenter();
-    property public final androidx.compose.foundation.gestures.snapping.SnapPositionInLayout CenterToCenter;
-  }
-
-}
-
 package androidx.compose.foundation.interaction {
 
   public interface DragInteraction extends androidx.compose.foundation.interaction.Interaction {
@@ -530,7 +397,6 @@
   }
 
   @androidx.compose.foundation.lazy.LazyScopeMarker @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LazyItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
     method public androidx.compose.ui.Modifier fillParentMaxHeight(androidx.compose.ui.Modifier, optional float fraction);
     method public androidx.compose.ui.Modifier fillParentMaxSize(androidx.compose.ui.Modifier, optional float fraction);
     method public androidx.compose.ui.Modifier fillParentMaxWidth(androidx.compose.ui.Modifier, optional float fraction);
@@ -577,7 +443,6 @@
     method @Deprecated public void item(optional Object? key, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
     method public default void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?> contentType, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
     method @Deprecated public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.LazyItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public void stickyHeader(optional Object? key, optional Object? contentType, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.LazyItemScope,kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Stable public final class LazyListState implements androidx.compose.foundation.gestures.ScrollableState {
@@ -638,7 +503,6 @@
 
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class GridItemSpan {
     method public int getCurrentLineSpan();
-    property @androidx.compose.foundation.ExperimentalFoundationApi public final int currentLineSpan;
   }
 
   public final class LazyGridDslKt {
@@ -676,7 +540,6 @@
   }
 
   @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker @androidx.compose.runtime.Stable public sealed interface LazyGridItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
   }
 
   @androidx.compose.foundation.lazy.grid.LazyGridScopeMarker public sealed interface LazyGridItemSpanScope {
@@ -753,110 +616,6 @@
 
 }
 
-package androidx.compose.foundation.lazy.layout {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface IntervalList<T> {
-    method public void forEach(optional int fromIndex, optional int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
-    method public operator androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
-    method public int getSize();
-    property public abstract int size;
-  }
-
-  public static final class IntervalList.Interval<T> {
-    method public int getSize();
-    method public int getStartIndex();
-    method public T getValue();
-    property public final int size;
-    property public final int startIndex;
-    property public final T value;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public abstract class LazyLayoutIntervalContent<Interval extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> {
-    ctor public LazyLayoutIntervalContent();
-    method public final Object? getContentType(int index);
-    method public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> getIntervals();
-    method public final int getItemCount();
-    method public final Object getKey(int index);
-    method public final inline <T> T withInterval(int globalIndex, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super Interval,? extends T> block);
-    property public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> intervals;
-    property public final int itemCount;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static interface LazyLayoutIntervalContent.Interval {
-    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? getKey();
-    method public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> getType();
-    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object>? key;
-    property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> type;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface LazyLayoutItemProvider {
-    method @androidx.compose.runtime.Composable public void Item(int index, Object key);
-    method public default Object? getContentType(int index);
-    method public default int getIndex(Object key);
-    method public int getItemCount();
-    method public default Object getKey(int index);
-    property public abstract int itemCount;
-  }
-
-  public final class LazyLayoutItemProviderKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
-  }
-
-  public final class LazyLayoutKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayout(androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider itemProvider, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState? prefetchState, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public sealed interface LazyLayoutMeasureScope extends androidx.compose.ui.layout.MeasureScope {
-    method public java.util.List<androidx.compose.ui.layout.Placeable> measure(int index, long constraints);
-    method @androidx.compose.runtime.Stable public default float toDp(float);
-    method @androidx.compose.runtime.Stable public default float toDp(int);
-    method @androidx.compose.runtime.Stable public default float toDp(long);
-    method @androidx.compose.runtime.Stable public default long toDpSize(long);
-    method @androidx.compose.runtime.Stable public default long toSize(long);
-    method @androidx.compose.runtime.Stable public default long toSp(float);
-    method @androidx.compose.runtime.Stable public default long toSp(float);
-    method @androidx.compose.runtime.Stable public default long toSp(int);
-  }
-
-  public final class LazyLayoutPinnableItemKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void LazyLayoutPinnableItem(Object? key, int index, androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList pinnedItemList, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class LazyLayoutPinnedItemList implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList.PinnedItem> {
-    ctor public LazyLayoutPinnedItemList();
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static sealed interface LazyLayoutPinnedItemList.PinnedItem {
-    method public int getIndex();
-    method public Object? getKey();
-    property public abstract int index;
-    property public abstract Object? key;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public final class LazyLayoutPrefetchState {
-    ctor public LazyLayoutPrefetchState();
-    method public androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState.PrefetchHandle schedulePrefetch(int index, long constraints);
-  }
-
-  public static sealed interface LazyLayoutPrefetchState.PrefetchHandle {
-    method public void cancel();
-  }
-
-  public final class Lazy_androidKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static Object getDefaultLazyLayoutKey(int index);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class MutableIntervalList<T> implements androidx.compose.foundation.lazy.layout.IntervalList<T> {
-    ctor public MutableIntervalList();
-    method public void addInterval(int size, T value);
-    method public void forEach(int fromIndex, int toIndex, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.lazy.layout.IntervalList.Interval<? extends T>,kotlin.Unit> block);
-    method public androidx.compose.foundation.lazy.layout.IntervalList.Interval<T> get(int index);
-    method public int getSize();
-    property public int size;
-  }
-
-}
-
 package androidx.compose.foundation.lazy.staggeredgrid {
 
   public final class LazyStaggeredGridDslKt {
@@ -884,7 +643,6 @@
   }
 
   @androidx.compose.runtime.Stable public sealed interface LazyStaggeredGridItemScope {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.Modifier animateItemPlacement(androidx.compose.ui.Modifier, optional androidx.compose.animation.core.FiniteAnimationSpec<androidx.compose.ui.unit.IntOffset> animationSpec);
   }
 
   public sealed interface LazyStaggeredGridLayoutInfo {
@@ -975,109 +733,6 @@
 
 }
 
-package androidx.compose.foundation.pager {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PageSize {
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fill implements androidx.compose.foundation.pager.PageSize {
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-    field public static final androidx.compose.foundation.pager.PageSize.Fill INSTANCE;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public static final class PageSize.Fixed implements androidx.compose.foundation.pager.PageSize {
-    ctor public PageSize.Fixed(float pageSize);
-    method public int calculateMainAxisPageSize(androidx.compose.ui.unit.Density, int availableSpace, int pageSpacing);
-    method public float getPageSize();
-    property public final float pageSize;
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public final class PagerDefaults {
-    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.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 snapVelocityThreshold, optional float snapPositionalThreshold);
-    method public androidx.compose.ui.input.nestedscroll.NestedScrollConnection pageNestedScrollConnection(androidx.compose.foundation.gestures.Orientation orientation);
-    field public static final androidx.compose.foundation.pager.PagerDefaults INSTANCE;
-  }
-
-  public final class PagerKt {
-    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void HorizontalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @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 beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void VerticalPager(int pageCount, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.pager.PagerState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.pager.PageSize pageSize, optional int beyondBoundsPageCount, 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, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.pager.PagerScope,? super java.lang.Integer,kotlin.Unit> pageContent);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface PagerScope {
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface PagerSnapDistance {
-    method public int calculateTargetPage(int startPage, int suggestedTargetPage, float velocity, int pageSize, int pageSpacing);
-    field public static final androidx.compose.foundation.pager.PagerSnapDistance.Companion Companion;
-  }
-
-  public static final class PagerSnapDistance.Companion {
-    method public androidx.compose.foundation.pager.PagerSnapDistance atMost(int pages);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public abstract class PagerState implements androidx.compose.foundation.gestures.ScrollableState {
-    ctor public PagerState(optional int initialPage, optional float initialPageOffsetFraction);
-    method public final suspend Object? animateScrollToPage(int page, optional float pageOffsetFraction, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public float dispatchRawDelta(float delta);
-    method public final boolean getCanScrollBackward();
-    method public final boolean getCanScrollForward();
-    method public final int getCurrentPage();
-    method public final float getCurrentPageOffsetFraction();
-    method public final int getInitialPage();
-    method public final float getInitialPageOffsetFraction();
-    method public final androidx.compose.foundation.interaction.InteractionSource getInteractionSource();
-    method public final float getOffsetFractionForPage(int page);
-    method public abstract int getPageCount();
-    method public final int getSettledPage();
-    method public final int getTargetPage();
-    method public boolean isScrollInProgress();
-    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final suspend Object? scrollToPage(int page, optional float pageOffsetFraction, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final boolean canScrollBackward;
-    property public final boolean canScrollForward;
-    property public final int currentPage;
-    property public final float currentPageOffsetFraction;
-    property public final int initialPage;
-    property public final float initialPageOffsetFraction;
-    property public final androidx.compose.foundation.interaction.InteractionSource interactionSource;
-    property public boolean isScrollInProgress;
-    property public abstract int pageCount;
-    property public final int settledPage;
-    property public final int targetPage;
-  }
-
-  public final class PagerStateKt {
-    method @Deprecated @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static androidx.compose.foundation.pager.PagerState rememberPagerState(optional int initialPage, optional float initialPageOffsetFraction, kotlin.jvm.functions.Function0<java.lang.Integer> pageCount);
-  }
-
-}
-
-package androidx.compose.foundation.relocation {
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public sealed interface BringIntoViewRequester {
-    method public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class BringIntoViewRequesterKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.foundation.relocation.BringIntoViewRequester BringIntoViewRequester();
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewRequester(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewRequester bringIntoViewRequester);
-  }
-
-  @androidx.compose.foundation.ExperimentalFoundationApi public interface BringIntoViewResponder {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public suspend Object? bringChildIntoView(kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Rect> localRect, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.foundation.ExperimentalFoundationApi public androidx.compose.ui.geometry.Rect calculateRectForParent(androidx.compose.ui.geometry.Rect localRect);
-  }
-
-  public final class BringIntoViewResponderKt {
-    method @androidx.compose.foundation.ExperimentalFoundationApi public static androidx.compose.ui.Modifier bringIntoViewResponder(androidx.compose.ui.Modifier, androidx.compose.foundation.relocation.BringIntoViewResponder responder);
-  }
-
-}
-
 package androidx.compose.foundation.selection {
 
   public final class SelectableGroupKt {
@@ -1221,7 +876,6 @@
 
   public final class ClickableTextKt {
     method @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
-    method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static void ClickableText(androidx.compose.ui.text.AnnotatedString text, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onHover, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.text.TextStyle style, optional boolean softWrap, optional int overflow, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onClick);
   }
 
   @androidx.compose.runtime.Immutable public final class InlineTextContent {
@@ -1236,9 +890,6 @@
     method public static void appendInlineContent(androidx.compose.ui.text.AnnotatedString.Builder, String id, optional String alternateText);
   }
 
-  @kotlin.RequiresOptIn(message="Internal/Unstable API for use only between foundation modules sharing " + "the same exact version, subject to change without notice.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalFoundationTextApi {
-  }
-
   public interface KeyboardActionScope {
     method public void defaultKeyboardAction(int imeAction);
   }
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index 2c62926..3126b99 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -31,6 +32,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
@@ -62,7 +65,7 @@
             dependencies {
                 api("androidx.annotation:annotation:1.1.0")
                 implementation("androidx.emoji2:emoji2:1.3.0")
-                implementation(project(":core:core"))
+                implementation("androidx.core:core:1.11.0-beta02")
             }
         }
 
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/lint-baseline.xml b/compose/foundation/foundation/integration-tests/foundation-demos/lint-baseline.xml
new file mode 100644
index 0000000..6ac65e5
--- /dev/null
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/lint-baseline.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SnappingSlider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberDragDropState has parameter &apos;onMove&apos; with type Function2&lt;? super Integer, ? super Integer, Unit>."
+        errorLine1="    onMove: (Int, Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DragDropState has parameter &apos;onMove&apos; with type Function2&lt;? super Integer, ? super Integer, Unit>."
+        errorLine1="    private val onMove: (Int, Int) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberGridDragDropState has parameter &apos;onMove&apos; with type Function2&lt;? super Integer, ? super Integer, Unit>."
+        errorLine1="    onMove: (Int, Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor GridDragDropState has parameter &apos;onMove&apos; with type Function2&lt;? super Integer, ? super Integer, Unit>."
+        errorLine1="    private val onMove: (Int, Int) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;item1&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="        val item1 = @Composable { index: Int ->"
+        errorLine2="        ^">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/ListDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;item2&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="        val item2 = @Composable { index: Int ->"
+        errorLine2="        ^">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/ListDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;item&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    val item = @Composable { index: Int ->"
+        errorLine2="    ^">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/ListDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SnapLayoutInfoProvider has parameter &apos;itemSize&apos; with type Function1&lt;? super Density, Float>."
+        errorLine1="    itemSize: Density.() -> Float,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SnapLayoutInfoProvider has parameter &apos;layoutSize&apos; with type Function1&lt;? super Density, Float>."
+        errorLine1="    layoutSize: Density.() -> Float"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberRowSnapLayoutInfoProvider has parameter &apos;layoutSize&apos; with type Function1&lt;? super Density, Float>."
+        errorLine1="    layoutSize: Density.() -> Float"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberMultiPageRowSnapLayoutInfoProvider has parameter &apos;layoutSize&apos; with type Function1&lt;? super Density, Float>."
+        errorLine1="    layoutSize: Density.() -> Float"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberViewPortRowSnapLayoutInfoProvider has parameter &apos;layoutSize&apos; with type Function1&lt;? super Density, Float>."
+        errorLine1="    layoutSize: Density.() -> Float"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ResizeHandle has parameter &apos;onDrag&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="private fun ResizeHandle(orientation: Orientation, onDrag: (Float) -> Unit) {"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor ViewPortBasedSnappingLayoutInfoProvider has parameter &apos;viewPortStep&apos; with type Function0&lt;Float>."
+        errorLine1="    private val viewPortStep: () -> Float"
+        errorLine2="                              ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SnappingDemoMainLayout has parameter &apos;content&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    content: @Composable (Int) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;setDemoIndex&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    val (currentDemoIndex, setDemoIndex) = rememberSaveable { mutableIntStateOf(-1) }"
+        errorLine2="                           ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;setWeight&apos; with type Function1&lt;? super Float, ? extends Unit>."
+        errorLine1="    val (weight, setWeight) = remember { mutableFloatStateOf(1000f) }"
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
index 62d3d93..303631a 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
@@ -90,7 +90,6 @@
 @Composable
 fun rememberDragDropState(
     lazyListState: LazyListState,
-    @Suppress("PrimitiveInLambda")
     onMove: (Int, Int) -> Unit
 ): DragDropState {
     val scope = rememberCoroutineScope()
@@ -113,7 +112,6 @@
 class DragDropState internal constructor(
     private val state: LazyListState,
     private val scope: CoroutineScope,
-    @Suppress("PrimitiveInLambda")
     private val onMove: (Int, Int) -> Unit
 ) {
     var draggingItemIndex by mutableStateOf<Int?>(null)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt
index 9abf0d0..25063b2 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyGridDragAndDropDemo.kt
@@ -102,7 +102,6 @@
 @Composable
 fun rememberGridDragDropState(
     gridState: LazyGridState,
-    @Suppress("PrimitiveInLambda")
     onMove: (Int, Int) -> Unit
 ): GridDragDropState {
     val scope = rememberCoroutineScope()
@@ -125,7 +124,6 @@
 class GridDragDropState internal constructor(
     private val state: LazyGridState,
     private val scope: CoroutineScope,
-    @Suppress("PrimitiveInLambda")
     private val onMove: (Int, Int) -> Unit
 ) {
     var draggingItemIndex by mutableStateOf<Int?>(null)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
index af17836..4634941 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
@@ -529,7 +529,6 @@
                 .widthIn(200.dp)
                 .fillMaxHeight()
         }
-        @Suppress("PrimitiveInLambda")
         val item1 = @Composable { index: Int ->
             Text(
                 "${index}A",
@@ -538,7 +537,6 @@
                     .border(1.dp, Color.Cyan)
             )
         }
-        @Suppress("PrimitiveInLambda")
         val item2 = @Composable { index: Int ->
             Text("${index}B")
         }
@@ -627,7 +625,6 @@
     }
 }
 
-@Suppress("PrimitiveInLambda")
 @Composable
 private fun NestedLazyDemo() {
     val item = @Composable { index: Int ->
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
index d82ec70..92d0c13 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
@@ -235,11 +235,7 @@
 
 @Suppress("NAME_SHADOWING")
 @Composable
-private fun ResizeHandle(
-    orientation: Orientation,
-    @Suppress("PrimitiveInLambda")
-    onDrag: (Float) -> Unit
-) {
+private fun ResizeHandle(orientation: Orientation, onDrag: (Float) -> Unit) {
     val dragState = rememberDraggableState(onDrag)
     val lineWidth = 24.dp
     val lineSpacing = 4.dp
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt
index 6b913c1..203eae5 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnapLayoutInfoProvider.kt
@@ -29,9 +29,7 @@
 @OptIn(ExperimentalFoundationApi::class)
 fun SnapLayoutInfoProvider(
     scrollState: ScrollState,
-    @Suppress("PrimitiveInLambda")
     itemSize: Density.() -> Float,
-    @Suppress("PrimitiveInLambda")
     layoutSize: Density.() -> Float
 ) = object : SnapLayoutInfoProvider {
 
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt
index 9325b66..ef0f3387 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/RowSnappingDemos.kt
@@ -141,7 +141,6 @@
 @Composable
 private fun rememberRowSnapLayoutInfoProvider(
     scrollState: ScrollState,
-    @Suppress("PrimitiveInLambda")
     layoutSize: Density.() -> Float
 ): SnapLayoutInfoProvider {
     return remember(scrollState, layoutSize) {
@@ -157,7 +156,6 @@
 @Composable
 private fun rememberMultiPageRowSnapLayoutInfoProvider(
     scrollState: ScrollState,
-    @Suppress("PrimitiveInLambda")
     layoutSize: Density.() -> Float
 ): SnapLayoutInfoProvider {
     val animation: DecayAnimationSpec<Float> = rememberSplineBasedDecay()
@@ -177,7 +175,6 @@
 @Composable
 private fun rememberViewPortRowSnapLayoutInfoProvider(
     scrollState: ScrollState,
-    @Suppress("PrimitiveInLambda")
     layoutSize: Density.() -> Float
 ): SnapLayoutInfoProvider {
     val density = LocalDensity.current
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt
index ba6d8cc7..f4e5e58 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/SnappingDemos.kt
@@ -72,7 +72,6 @@
 internal class ViewPortBasedSnappingLayoutInfoProvider(
     private val baseSnapLayoutInfoProvider: SnapLayoutInfoProvider,
     private val decayAnimationSpec: DecayAnimationSpec<Float>,
-    @Suppress("PrimitiveInLambda")
     private val viewPortStep: () -> Float
 ) : SnapLayoutInfoProvider by baseSnapLayoutInfoProvider {
     override fun Density.calculateApproachOffset(initialVelocity: Float): Float {
@@ -87,7 +86,6 @@
     lazyListState: LazyListState,
     flingBehavior: FlingBehavior,
     contentPaddingValues: PaddingValues = PaddingValues(8.dp),
-    @Suppress("PrimitiveInLambda")
     content: @Composable (Int) -> Unit
 ) {
     LazyRow(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
index c807951..a91e0d2 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
@@ -330,7 +330,6 @@
 @Composable
 private fun SnappingSlider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     modifier: Modifier = Modifier,
     valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
index 49833e3..15f6d1e 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
@@ -103,7 +103,6 @@
     }
 )
 
-@Suppress("PrimitiveInLambda")
 @OptIn(ExperimentalMaterialApi::class)
 @Composable
 fun TextFieldsInDialogDemo() {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
index 9329108..8e052ff 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
@@ -58,7 +58,6 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext
 
-@Suppress("PrimitiveInLambda")
 @OptIn(ExperimentalFoundationApi::class)
 @Preview
 @Composable
diff --git a/compose/foundation/foundation/lint-baseline.xml b/compose/foundation/foundation/lint-baseline.xml
index 82be5f8..7204fa6 100644
--- a/compose/foundation/foundation/lint-baseline.xml
+++ b/compose/foundation/foundation/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -47,12 +47,1254 @@
     </issue>
 
     <issue
-        id="IllegalExperimentalApiUsage"
-        message="`Experimental` and `RequiresOptIn` APIs may only be used within the same-version group where they were defined."
-        errorLine1="    @OptIn(ExperimentalTextApi::class)"
-        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="    internal val positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt"/>
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Float> of &apos;getPositionalThreshold$lint_module&apos;."
+        errorLine1="    internal val positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="    internal val velocityThreshold: () -> Float,"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function0&lt;Float> of &apos;getVelocityThreshold$lint_module&apos;."
+        errorLine1="    internal val velocityThreshold: () -> Float,"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="        positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="        velocityThreshold: () -> Float,"
+        errorLine2="                           ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="            positionalThreshold: (distance: Float) -> Float,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="            velocityThreshold: () -> Float,"
+        errorLine2="                               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ClickableText has parameter &apos;onClick&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onClick: (Int) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ClickableText has parameter &apos;onHover&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onHover: ((Int?) -> Unit),"
+        errorLine2="             ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ClickableText has parameter &apos;onClick&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onClick: (Int) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitVerticalTouchSlopOrCancellation has parameter &apos;onTouchSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitVerticalPointerSlopOrCancellation has parameter &apos;onTouchSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method detectVerticalDragGestures has parameter &apos;onVerticalDrag&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitHorizontalTouchSlopOrCancellation has parameter &apos;onTouchSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitHorizontalPointerSlopOrCancellation has parameter &apos;onPointerSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method detectHorizontalDragGestures has parameter &apos;onHorizontalDrag&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onHorizontalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DraggableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="fun DraggableState(onDelta: (Float) -> Unit): DraggableState ="
+        errorLine2="                            ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberDraggableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="fun rememberDraggableState(onDelta: (Float) -> Unit): DraggableState {"
+        errorLine2="                                    ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method draggable has parameter &apos;onDragStopped&apos; with type Function3&lt;? super CoroutineScope, ? super Float, ? super Continuation&lt;? super Unit>, ? extends Object>."
+        errorLine1="    onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {},"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;motionFromChange&apos; with type Function1&lt;? super PointerInputChange, ? extends Float>."
+        errorLine1="    val motionFromChange: (PointerInputChange) -> Float = if (orientation == Orientation.Vertical) {"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DefaultDraggableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="private class DefaultDraggableState(val onDelta: (Float) -> Unit) : DraggableState {"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Unit> of &apos;getOnDelta&apos;."
+        errorLine1="private class DefaultDraggableState(val onDelta: (Float) -> Unit) : DraggableState {"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;contentType&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        contentType: (index: Int) -> Any? = { null },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyItemScope, ? super Integer, ? extends Unit>."
+        errorLine1="        itemContent: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;lineOf&apos; with type Function1&lt;? super Integer, ? extends Integer>."
+        errorLine1="        val lineOf: (Int) -> Int = {"
+        errorLine2="                    ~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateScrollScope.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method item has parameter &apos;span&apos; with type Function1&lt;? super LazyGridItemSpanScope, GridItemSpan>."
+        errorLine1="        span: (LazyGridItemSpanScope.() -> GridItemSpan)? = null,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super Integer, GridItemSpan>."
+        errorLine1="        span: (LazyGridItemSpanScope.(index: Int) -> GridItemSpan)? = null,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;contentType&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        contentType: (index: Int) -> Any? = { null },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyGridItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable LazyGridItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super T, GridItemSpan>."
+        errorLine1="    noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function3&lt;? super LazyGridItemSpanScope, ? super Integer, ? super T, GridItemSpan>."
+        errorLine1="    noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super T, GridItemSpan>."
+        errorLine1="    noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function3&lt;? super LazyGridItemSpanScope, ? super Integer, ? super T, GridItemSpan>."
+        errorLine1="    noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;var872790a8&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super Integer, ? extends GridItemSpan>."
+        errorLine1="                span = span?.let { { span() } } ?: DefaultSpan,"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;varb56803de&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super Integer, ? extends GridItemSpan>."
+        errorLine1="                span = span ?: DefaultSpan,"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;LazyGridItemSpanScope, Integer, GridItemSpan> of &apos;getDefaultSpan&apos;."
+        errorLine1="        val DefaultSpan: LazyGridItemSpanScope.(Int) -> GridItemSpan = { GridItemSpan(1) }"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((index: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;span&apos; with type Function2&lt;? super LazyGridItemSpanScope, ? super Integer, GridItemSpan>."
+        errorLine1="    val span: LazyGridItemSpanScope.(Int) -> GridItemSpan,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;LazyGridItemSpanScope, Integer, GridItemSpan> of &apos;getSpan&apos;."
+        errorLine1="    val span: LazyGridItemSpanScope.(Int) -> GridItemSpan,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;type&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val type: ((index: Int) -> Any?),"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;item&apos; with type Function2&lt;? super LazyGridItemScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable LazyGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;LazyGridItemScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable LazyGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method measureLazyGrid has parameter &apos;layout&apos; with type Function3&lt;? super Integer, ? super Integer, ? super Function1&lt;? super PlacementScope, Unit>, ? extends MeasureResult>."
+        errorLine1="    layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setPrefetchInfoRetriever$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Integer, ? extends List&lt;Pair&lt;Integer, Constraints>>>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, List&lt;Pair&lt;Integer, Constraints>>> of &apos;getPrefetchInfoRetriever$lint_module&apos;."
+        errorLine1="    internal var prefetchInfoRetriever: (line: Int) -> List&lt;Pair&lt;Int, Constraints>> by"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Object> of &apos;getKey&apos;."
+        errorLine1="        val key: ((index: Int) -> Any)? get() = null"
+        errorLine2="            ~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Object> of &apos;getType&apos;."
+        errorLine1="        val type: ((index: Int) -> Any?) get() = { null }"
+        errorLine2="            ~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;keyFactory&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="                    val keyFactory = it.value.key"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Pager has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)?,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Pager has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PagerLayoutIntervalContent has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    val pageContent: @Composable PagerScope.(page: Int) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;PagerScope, Integer, Unit> of &apos;getPageContent&apos;."
+        errorLine1="    val pageContent: @Composable PagerScope.(page: Int) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PagerLayoutIntervalContent has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    val key: ((index: Int) -> Any)?,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Object> of &apos;getKey&apos;."
+        errorLine1="    val key: ((index: Int) -> Any)?,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PagerIntervalContent has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((page: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PagerIntervalContent has parameter &apos;item&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;PagerScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberPagerItemProviderLambda has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberPagerItemProviderLambda has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)?,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberPagerItemProviderLambda has parameter &apos;pageCount&apos; with type Function0&lt;Integer>."
+        errorLine1="    pageCount: () -> Int"
+        errorLine2="               ~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;indexForKeyMapping&apos; with type Function1&lt;? super Object, ? extends Integer>."
+        errorLine1="            val indexForKeyMapping: (Any) -> Int = { needle ->"
+        errorLine2="                                    ~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollByAction&apos; with type Function2&lt;? super Float, ? super Float, ? extends Boolean>."
+        errorLine1="            val scrollByAction: ((x: Float, y: Float) -> Boolean)? = if (userScrollEnabled) {"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollToIndexAction&apos; with type Function1&lt;? super Integer, ? extends Boolean>."
+        errorLine1="            val scrollToIndexAction: ((Int) -> Boolean)? = if (userScrollEnabled) {"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyListInterval has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((index: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyListInterval has parameter &apos;type&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val type: ((index: Int) -> Any?),"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyListInterval has parameter &apos;item&apos; with type Function2&lt;? super LazyItemScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;LazyItemScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;contentType&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        contentType: (index: Int) -> Any? = { null },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function1&lt;? super Integer, StaggeredGridItemSpan>."
+        errorLine1="        span: ((index: Int) -> StaggeredGridItemSpan)? = null,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyStaggeredGridItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable LazyStaggeredGridItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function2&lt;? super Integer, ? super T, StaggeredGridItemSpan>."
+        errorLine1="    noinline span: ((index: Int, item: T) -> StaggeredGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function2&lt;? super Integer, ? super T, StaggeredGridItemSpan>."
+        errorLine1="    noinline span: ((index: Int, item: T) -> StaggeredGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyStaggeredGridInterval has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((index: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyStaggeredGridInterval has parameter &apos;type&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val type: ((index: Int) -> Any?),"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyStaggeredGridInterval has parameter &apos;span&apos; with type Function1&lt;? super Integer, StaggeredGridItemSpan>."
+        errorLine1="    val span: ((index: Int) -> StaggeredGridItemSpan)?,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, StaggeredGridItemSpan> of &apos;getSpan&apos;."
+        errorLine1="    val span: ((index: Int) -> StaggeredGridItemSpan)?,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyStaggeredGridInterval has parameter &apos;item&apos; with type Function2&lt;? super LazyStaggeredGridItemScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable LazyStaggeredGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;LazyStaggeredGridItemScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable LazyStaggeredGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyStaggeredGridScrollPosition has parameter &apos;fillIndices&apos; with type Function2&lt;? super Integer, ? super Integer, int[]&gt;."
+        errorLine1="    private val fillIndices: (targetIndex: Int, laneCount: Int) -> IntArray"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridScrollPosition.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;span&apos; with type Function1&lt;? super Integer, ? extends StaggeredGridItemSpan>."
+        errorLine1="            val span = value.span"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSpan.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalPager has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)? = null,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalPager has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalPager has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)? = null,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalPager has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalPager has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)? = null,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalPager has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalPager has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)? = null,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalPager has parameter &apos;pageContent&apos; with type Function2&lt;? super PagerScope, ? super Integer, Unit>."
+        errorLine1="    pageContent: @Composable PagerScope.(page: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method measurePager has parameter &apos;layout&apos; with type Function3&lt;? super Integer, ? super Integer, ? super Function1&lt;? super PlacementScope, Unit>, ? extends MeasureResult>."
+        errorLine1="    layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method createPagesAfterList has parameter &apos;getAndMeasure&apos; with type Function1&lt;? super Integer, MeasuredPage>."
+        errorLine1="    getAndMeasure: (Int) -> MeasuredPage"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method createPagesBeforeList has parameter &apos;getAndMeasure&apos; with type Function1&lt;? super Integer, MeasuredPage>."
+        errorLine1="    getAndMeasure: (Int) -> MeasuredPage"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberPagerMeasurePolicy has parameter &apos;pageCount&apos; with type Function0&lt;Integer>."
+        errorLine1="    pageCount: () -> Int,"
+        errorLine2="               ~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberPagerState has parameter &apos;pageCount&apos; with type Function0&lt;Integer>."
+        errorLine1="    pageCount: () -> Int"
+        errorLine2="               ~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PagerStateImpl has parameter &apos;updatedPageCount&apos; with type Function0&lt;Integer>."
+        errorLine1="    updatedPageCount: () -> Int"
+        errorLine2="                      ~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setPageCountState has parameter &apos;&lt;set-?>&apos; with type MutableState&lt;Function0&lt;Integer>>."
+        errorLine1="    var pageCountState = mutableStateOf(updatedPageCount)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type MutableState&lt;Function0&lt;Integer>> of &apos;getPageCountState&apos;."
+        errorLine1="    var pageCountState = mutableStateOf(updatedPageCount)"
+        errorLine2="        ~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ScrollableState has parameter &apos;consumeScrollDelta&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="fun ScrollableState(consumeScrollDelta: (Float) -> Float): ScrollableState {"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberScrollableState has parameter &apos;consumeScrollDelta&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="fun rememberScrollableState(consumeScrollDelta: (Float) -> Float): ScrollableState {"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DefaultScrollableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="private class DefaultScrollableState(val onDelta: (Float) -> Float) : ScrollableState {"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Float> of &apos;getOnDelta&apos;."
+        errorLine1="private class DefaultScrollableState(val onDelta: (Float) -> Float) : ScrollableState {"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method adjustByBoundary has parameter &apos;boundaryFun&apos; with type Function1&lt;? super Integer, TextRange>."
+        errorLine1="            boundaryFun: (Int) -> TextRange"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustment.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setOnPositionChangeCallback$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, Unit> of &apos;getOnPositionChangeCallback$lint_module&apos;."
+        errorLine1="    internal var onPositionChangeCallback: ((Long) -> Unit)? = null"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setOnSelectionUpdateSelectAll$lint_module has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Boolean, ? super Long, Unit>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Boolean, Long, Unit> of &apos;getOnSelectionUpdateSelectAll$lint_module&apos;."
+        errorLine1="    internal var onSelectionUpdateSelectAll: ("
+        errorLine2="                                             ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setOnSelectableChangeCallback$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, Unit> of &apos;getOnSelectableChangeCallback$lint_module&apos;."
+        errorLine1="    internal var onSelectableChangeCallback: ((Long) -> Unit)? = null"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setAfterSelectableUnsubscribe$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, Unit> of &apos;getAfterSelectableUnsubscribe$lint_module&apos;."
+        errorLine1="    internal var afterSelectableUnsubscribe: ((Long) -> Unit)? = null"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method performFling has parameter &apos;onSettlingDistanceUpdated&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onSettlingDistanceUpdated: (Float) -> Unit"
+        errorLine2="                                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method fling has parameter &apos;onRemainingScrollOffsetUpdate&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onRemainingScrollOffsetUpdate: (Float) -> Unit"
+        errorLine2="                                       ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method shortSnap has parameter &apos;onRemainingScrollOffsetUpdate&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onRemainingScrollOffsetUpdate: (Float) -> Unit"
+        errorLine2="                                       ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method longSnap has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onAnimationStep: (remainingScrollOffset: Float) -> Unit"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method runApproach has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method approach has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateDecay has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateSnap has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method approachAnimation has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method approachAnimation has parameter &apos;onAnimationStep&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        onAnimationStep: (delta: Float) -> Unit"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method detectTransformGestures has parameter &apos;onGesture&apos; with type Function4&lt;? super Offset, ? super Offset, ? super Float, ? super Float, Unit>."
+        errorLine1="    onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) -> Unit"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method TransformableState has parameter &apos;onTransformation&apos; with type Function3&lt;? super Float, ? super Offset, ? super Float, Unit>."
+        errorLine1="    onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberTransformableState has parameter &apos;onTransformation&apos; with type Function3&lt;? super Float, ? super Offset, ? super Float, Unit>."
+        errorLine1="    onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DefaultTransformableState has parameter &apos;onTransformation&apos; with type Function3&lt;? super Float, ? super Offset, ? super Float, Unit>."
+        errorLine1="    val onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;Float, Offset, Float, Unit> of &apos;getOnTransformation&apos;."
+        errorLine1="    val onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateToZero has parameter &apos;beforeFrame&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="        beforeFrame: (valueDelta: Float) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationState.kt"/>
     </issue>
 
 </issues>
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
index c9c1a87..7cedc56 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
@@ -447,28 +447,6 @@
     }
 
     @Test
-    fun regularCompositionIsUsedInPrefetchTimeCalculation() {
-        val itemProvider = itemProvider({ 1 }) {
-            Box(Modifier.fillMaxSize())
-        }
-        val prefetchState = LazyLayoutPrefetchState()
-        rule.setContent {
-            LazyLayout(itemProvider, prefetchState = prefetchState) { constraint ->
-                val item = measure(0, constraint)[0]
-                layout(100, 100) {
-                    item.place(0, 0)
-                }
-            }
-        }
-
-        rule.runOnIdle {
-            val timeTracker = requireNotNull(prefetchState.prefetcher?.timeTracker)
-            assertThat(timeTracker.compositionTimeNs).isGreaterThan(0L)
-            assertThat(timeTracker.measurementTimeNs).isGreaterThan(0L)
-        }
-    }
-
-    @Test
     fun skippingItemBlockWhenKeyIsObservableButDidntChange() {
         val stateList = mutableStateListOf(0)
         var itemCalls = 0
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
index 2763637..416fc19 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
@@ -49,7 +49,9 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.LookaheadScope
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.SemanticsProperties
@@ -86,6 +88,7 @@
 
     private val isVertical: Boolean get() = config.isVertical
     private val reverseLayout: Boolean get() = config.reverseLayout
+    private val isInLookaheadScope: Boolean get() = config.isInLookaheadScope
 
     @get:Rule
     val rule = createComposeRule()
@@ -1842,6 +1845,7 @@
         }
     }
 
+    @OptIn(ExperimentalComposeUiApi::class)
     @Composable
     private fun LazyList(
         arrangement: Arrangement.HorizontalOrVertical? = null,
@@ -1854,63 +1858,70 @@
         endPadding: Dp = 0.dp,
         content: LazyListScope.() -> Unit
     ) {
-        state = rememberLazyListState(startIndex)
-        if (isVertical) {
-            val verticalArrangement =
-                arrangement ?: if (!reverseLayout) Arrangement.Top else Arrangement.Bottom
-            val horizontalAlignment = if (crossAxisAlignment == CrossAxisAlignment.Start) {
-                Alignment.Start
-            } else if (crossAxisAlignment == CrossAxisAlignment.Center) {
-                Alignment.CenterHorizontally
-            } else {
-                Alignment.End
-            }
-            LazyColumn(
-                state = state,
-                modifier = Modifier
-                    .requiredHeightIn(min = minSize, max = maxSize)
-                    .then(
-                        if (crossAxisSize != Dp.Unspecified) {
-                            Modifier.requiredWidth(crossAxisSize)
-                        } else {
-                            Modifier.fillMaxWidth()
-                        }
-                    )
-                    .testTag(ContainerTag),
-                verticalArrangement = verticalArrangement,
-                horizontalAlignment = horizontalAlignment,
-                reverseLayout = reverseLayout,
-                contentPadding = PaddingValues(top = startPadding, bottom = endPadding),
-                content = content
-            )
+        val container: @Composable (@Composable () -> Unit) -> Unit = if (isInLookaheadScope) {
+            { LookaheadScope { it() } }
         } else {
-            val horizontalArrangement =
-                arrangement ?: if (!reverseLayout) Arrangement.Start else Arrangement.End
-            val verticalAlignment = if (crossAxisAlignment == CrossAxisAlignment.Start) {
-                Alignment.Top
-            } else if (crossAxisAlignment == CrossAxisAlignment.Center) {
-                Alignment.CenterVertically
+            { it() }
+        }
+        container {
+            state = rememberLazyListState(startIndex)
+            if (isVertical) {
+                val verticalArrangement =
+                    arrangement ?: if (!reverseLayout) Arrangement.Top else Arrangement.Bottom
+                val horizontalAlignment = if (crossAxisAlignment == CrossAxisAlignment.Start) {
+                    Alignment.Start
+                } else if (crossAxisAlignment == CrossAxisAlignment.Center) {
+                    Alignment.CenterHorizontally
+                } else {
+                    Alignment.End
+                }
+                LazyColumn(
+                    state = state,
+                    modifier = Modifier
+                        .requiredHeightIn(min = minSize, max = maxSize)
+                        .then(
+                            if (crossAxisSize != Dp.Unspecified) {
+                                Modifier.requiredWidth(crossAxisSize)
+                            } else {
+                                Modifier.fillMaxWidth()
+                            }
+                        )
+                        .testTag(ContainerTag),
+                    verticalArrangement = verticalArrangement,
+                    horizontalAlignment = horizontalAlignment,
+                    reverseLayout = reverseLayout,
+                    contentPadding = PaddingValues(top = startPadding, bottom = endPadding),
+                    content = content
+                )
             } else {
-                Alignment.Bottom
+                val horizontalArrangement =
+                    arrangement ?: if (!reverseLayout) Arrangement.Start else Arrangement.End
+                val verticalAlignment = if (crossAxisAlignment == CrossAxisAlignment.Start) {
+                    Alignment.Top
+                } else if (crossAxisAlignment == CrossAxisAlignment.Center) {
+                    Alignment.CenterVertically
+                } else {
+                    Alignment.Bottom
+                }
+                LazyRow(
+                    state = state,
+                    modifier = Modifier
+                        .requiredWidthIn(min = minSize, max = maxSize)
+                        .then(
+                            if (crossAxisSize != Dp.Unspecified) {
+                                Modifier.requiredHeight(crossAxisSize)
+                            } else {
+                                Modifier.fillMaxHeight()
+                            }
+                        )
+                        .testTag(ContainerTag),
+                    horizontalArrangement = horizontalArrangement,
+                    verticalAlignment = verticalAlignment,
+                    reverseLayout = reverseLayout,
+                    contentPadding = PaddingValues(start = startPadding, end = endPadding),
+                    content = content
+                )
             }
-            LazyRow(
-                state = state,
-                modifier = Modifier
-                    .requiredWidthIn(min = minSize, max = maxSize)
-                    .then(
-                        if (crossAxisSize != Dp.Unspecified) {
-                            Modifier.requiredHeight(crossAxisSize)
-                        } else {
-                            Modifier.fillMaxHeight()
-                        }
-                    )
-                    .testTag(ContainerTag),
-                horizontalArrangement = horizontalArrangement,
-                verticalAlignment = verticalAlignment,
-                reverseLayout = reverseLayout,
-                contentPadding = PaddingValues(start = startPadding, end = endPadding),
-                content = content
-            )
         }
     }
 
@@ -1952,19 +1963,22 @@
         @JvmStatic
         @Parameterized.Parameters(name = "{0}")
         fun params() = arrayOf(
-            Config(isVertical = true, reverseLayout = false),
-            Config(isVertical = false, reverseLayout = false),
-            Config(isVertical = true, reverseLayout = true),
-            Config(isVertical = false, reverseLayout = true),
+            Config(isVertical = true, reverseLayout = false, isInLookaheadScope = false),
+            Config(isVertical = false, reverseLayout = false, isInLookaheadScope = false),
+            Config(isVertical = true, reverseLayout = true, isInLookaheadScope = false),
+            Config(isVertical = false, reverseLayout = true, isInLookaheadScope = false),
+            Config(isVertical = true, reverseLayout = false, isInLookaheadScope = true)
         )
 
         class Config(
             val isVertical: Boolean,
-            val reverseLayout: Boolean
+            val reverseLayout: Boolean,
+            val isInLookaheadScope: Boolean
         ) {
             override fun toString() =
                 (if (isVertical) "LazyColumn" else "LazyRow") +
-                    (if (reverseLayout) "(reverse)" else "")
+                    (if (reverseLayout) "(reverse)" else "") +
+                    (if (isInLookaheadScope) "(in LookaheadScope)" else "")
         }
     }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
index 2b0b778..19191a5 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListTest.kt
@@ -17,7 +17,12 @@
 package androidx.compose.foundation.lazy.list
 
 import android.os.Build
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
 import androidx.compose.foundation.AutoTestFrameClock
+import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.VelocityTrackerCalculationThreshold
 import androidx.compose.foundation.background
 import androidx.compose.foundation.gestures.Orientation
@@ -25,6 +30,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -44,6 +50,7 @@
 import androidx.compose.foundation.text.BasicText
 import androidx.compose.foundation.text.matchers.isZero
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.SideEffect
@@ -54,6 +61,7 @@
 import androidx.compose.testutils.WithTouchSlop
 import androidx.compose.testutils.assertPixels
 import androidx.compose.testutils.assertShape
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
 import androidx.compose.ui.draw.drawBehind
@@ -67,7 +75,11 @@
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.input.pointer.util.VelocityTracker
 import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.LookaheadScope
+import androidx.compose.ui.layout.findRootCoordinates
 import androidx.compose.ui.layout.layout
+import androidx.compose.ui.layout.positionInRoot
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.SemanticsActions
 import androidx.compose.ui.semantics.SemanticsProperties
@@ -106,6 +118,7 @@
 import java.util.concurrent.CountDownLatch
 import kotlin.math.abs
 import kotlin.math.roundToInt
+import kotlin.test.assertEquals
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
@@ -2171,6 +2184,640 @@
     }
 
     @Test
+    fun testLookaheadPositionWithOnlyInBoundChanges() {
+        testLookaheadPositionWithPlacementAnimator(
+            initialList = listOf(0, 1, 2, 3),
+            targetList = listOf(3, 2, 1, 0),
+            initialExpectedLookaheadPositions = listOf(0, 100, 200, 300),
+            targetExpectedLookaheadPositions = listOf(300, 200, 100, 0)
+        )
+    }
+
+    @Test
+    fun testLookaheadPositionWithCustomStartingIndex() {
+        testLookaheadPositionWithPlacementAnimator(
+            initialList = listOf(0, 1, 2, 3, 4),
+            targetList = listOf(4, 3, 2, 1, 0),
+            initialExpectedLookaheadPositions = listOf(null, 0, 100, 200, 300),
+            targetExpectedLookaheadPositions = listOf(300, 200, 100, 0, -100),
+            startingIndex = 1
+        )
+    }
+
+    @Test
+    fun testLookaheadPositionWithTwoInBoundTwoOutBound() {
+        testLookaheadPositionWithPlacementAnimator(
+            initialList = listOf(0, 1, 2, 3, 4, 5),
+            targetList = listOf(5, 4, 2, 1, 3, 0),
+            initialExpectedLookaheadPositions = listOf(null, null, 0, 100, 200, 300),
+            targetExpectedLookaheadPositions = listOf(300, 100, 0, 200, -100, -200),
+            startingIndex = 2
+        )
+    }
+
+    private fun testLookaheadPositionWithPlacementAnimator(
+        initialList: List<Int>,
+        targetList: List<Int>,
+        initialExpectedLookaheadPositions: List<Int?>,
+        targetExpectedLookaheadPositions: List<Int?>,
+        startingIndex: Int = 0
+    ) {
+        var list by mutableStateOf(initialList)
+        val lookaheadPosition = mutableMapOf<Int, Int>()
+        val postLookaheadPosition = mutableMapOf<Int, Int>()
+        rule.mainClock.autoAdvance = false
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LazyListInLookaheadScope(
+                    list = list,
+                    startingIndex = startingIndex,
+                    lookaheadPosition = lookaheadPosition,
+                    postLookaheadPosition = postLookaheadPosition
+                )
+            }
+        }
+        rule.runOnIdle {
+            repeat(list.size) {
+                assertEquals(initialExpectedLookaheadPositions[it], lookaheadPosition[it])
+                assertEquals(initialExpectedLookaheadPositions[it], postLookaheadPosition[it])
+            }
+            lookaheadPosition.clear()
+            postLookaheadPosition.clear()
+            list = targetList
+        }
+        rule.waitForIdle()
+        repeat(20) {
+            rule.mainClock.advanceTimeByFrame()
+            repeat(list.size) {
+                assertEquals(targetExpectedLookaheadPositions[it], lookaheadPosition[it])
+            }
+        }
+        repeat(list.size) {
+            if (lookaheadPosition[it]?.let { offset -> offset + ItemSize >= 0 } != false) {
+                assertEquals(lookaheadPosition[it], postLookaheadPosition[it])
+            }
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
+    @Composable
+    private fun LazyListInLookaheadScope(
+        list: List<Int>,
+        startingIndex: Int,
+        lookaheadPosition: MutableMap<Int, Int>,
+        postLookaheadPosition: MutableMap<Int, Int>
+    ) {
+        LookaheadScope {
+            LazyColumnOrRow(
+                if (vertical) {
+                    Modifier.requiredHeight(ItemSize.dp * (list.size - startingIndex))
+                } else {
+                    Modifier.requiredWidth(ItemSize.dp * (list.size - startingIndex))
+                },
+                state = rememberLazyListState(
+                    initialFirstVisibleItemIndex = startingIndex
+                ),
+
+                ) {
+                items(list, key = { it }) { item ->
+                    Box(
+                        Modifier
+                            .animateItemPlacement(tween(160))
+                            .trackPositions(
+                                lookaheadPosition,
+                                postLookaheadPosition,
+                                this@LookaheadScope,
+                                item
+                            )
+                            .requiredSize(ItemSize.dp)
+                    )
+                }
+            }
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    private fun Modifier.trackPositions(
+        lookaheadPosition: MutableMap<Int, Int>,
+        postLookaheadPosition: MutableMap<Int, Int>,
+        lookaheadScope: LookaheadScope,
+        item: Int
+    ): Modifier = this.layout { measurable, constraints ->
+        measurable
+            .measure(constraints)
+            .run {
+                layout(width, height) {
+                    if (isLookingAhead) {
+                        lookaheadPosition[item] =
+                            with(lookaheadScope) {
+                                coordinates!!
+                                    .findRootCoordinates()
+                                    .localLookaheadPositionOf(
+                                        coordinates!!
+                                    )
+                                    .let {
+                                        if (vertical) {
+                                            it.y
+                                        } else {
+                                            it.x
+                                        }.roundToInt()
+                                    }
+                            }
+                    } else {
+                        postLookaheadPosition[item] =
+                            coordinates!!
+                                .positionInRoot()
+                                .let {
+                                    if (vertical) it.y else it.x
+                                }
+                                .roundToInt()
+                    }
+                    place(0, 0)
+                }
+            }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
+    @Test
+    fun animContentSizeWithPlacementAnimator() {
+        val lookaheadPosition = mutableMapOf<Int, Int>()
+        val postLookaheadPosition = mutableMapOf<Int, Int>()
+        var large by mutableStateOf(false)
+        var animateSizeChange by mutableStateOf(false)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LookaheadScope {
+                    LazyColumnOrRow {
+                        items(4, key = { it }) {
+                            Box(
+                                Modifier
+                                    .animateItemPlacement(tween(160, easing = LinearEasing))
+                                    .trackPositions(
+                                        lookaheadPosition,
+                                        postLookaheadPosition,
+                                        this@LookaheadScope,
+                                        it
+                                    )
+                                    .then(
+                                        if (animateSizeChange) Modifier.animateContentSize(
+                                            tween(160)
+                                        ) else Modifier
+                                    )
+                                    .requiredSize(if (large) ItemSize.dp * 2 else ItemSize.dp)
+                            )
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        repeat(4) {
+            assertEquals(it * ItemSize, lookaheadPosition[it])
+            assertEquals(it * ItemSize, postLookaheadPosition[it])
+        }
+
+        rule.mainClock.autoAdvance = false
+        large = true
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        rule.mainClock.advanceTimeByFrame()
+
+        repeat(20) { frame ->
+            val fraction = (frame * 16 / 160f).coerceAtMost(1f)
+            repeat(4) {
+                assertEquals(it * ItemSize * 2, lookaheadPosition[it])
+                assertEquals(
+                    (it * ItemSize * (1 + fraction)).roundToInt(),
+                    postLookaheadPosition[it]
+                )
+            }
+            rule.mainClock.advanceTimeByFrame()
+        }
+
+        // Enable animateContentSize
+        animateSizeChange = true
+        large = false
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        rule.mainClock.advanceTimeByFrame()
+
+        repeat(20) { frame ->
+            val fraction = (frame * 16 / 160f).coerceAtMost(1f)
+            repeat(4) {
+                // Verify that item target offsets are not affected by animateContentSize
+                assertEquals(it * ItemSize, lookaheadPosition[it])
+                assertEquals(
+                    (it * (2 - fraction) * ItemSize).roundToInt(),
+                    postLookaheadPosition[it]
+                )
+            }
+            rule.mainClock.advanceTimeByFrame()
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
+    @Test
+    fun animVisibilityWithPlacementAnimator() {
+        val lookaheadPosition = mutableMapOf<Int, Int>()
+        val postLookaheadPosition = mutableMapOf<Int, Int>()
+        var visible by mutableStateOf(false)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LookaheadScope {
+                    LazyColumnOrRow {
+                        items(4, key = { it }) {
+                            if (vertical) {
+                                Column(
+                                    Modifier
+                                        .animateItemPlacement(tween(160, easing = LinearEasing))
+                                        .trackPositions(
+                                            lookaheadPosition,
+                                            postLookaheadPosition,
+                                            this@LookaheadScope,
+                                            it
+                                        )
+                                ) {
+                                    Box(Modifier.requiredSize(ItemSize.dp))
+                                    AnimatedVisibility(visible = visible) {
+                                        Box(Modifier.requiredSize(ItemSize.dp))
+                                    }
+                                }
+                            } else {
+                                Row(
+                                    Modifier
+                                        .animateItemPlacement(tween(160, easing = LinearEasing))
+                                        .trackPositions(
+                                            lookaheadPosition,
+                                            postLookaheadPosition,
+                                            this@LookaheadScope,
+                                            it
+                                        )
+                                ) {
+                                    Box(Modifier.requiredSize(ItemSize.dp))
+                                    AnimatedVisibility(visible = visible) {
+                                        Box(Modifier.requiredSize(ItemSize.dp))
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+        repeat(4) {
+            assertEquals(it * ItemSize, lookaheadPosition[it])
+            assertEquals(it * ItemSize, postLookaheadPosition[it])
+        }
+
+        rule.mainClock.autoAdvance = false
+        visible = true
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        rule.mainClock.advanceTimeByFrame()
+
+        repeat(20) { frame ->
+            val fraction = (frame * 16 / 160f).coerceAtMost(1f)
+            repeat(4) {
+                assertEquals(it * ItemSize * 2, lookaheadPosition[it])
+                assertEquals(
+                    (it * ItemSize * (1 + fraction)).roundToInt(),
+                    postLookaheadPosition[it]
+                )
+            }
+            rule.mainClock.advanceTimeByFrame()
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun resizeLazyList() {
+        val lookaheadPositions = mutableMapOf<Int, Offset>()
+        val postLookaheadPositions = mutableMapOf<Int, Offset>()
+        var postLookaheadSize by mutableStateOf(ItemSize * 2)
+        rule.setContent {
+            LookaheadScope {
+                CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                    LazyColumnOrRow(Modifier.layout { measurable, _ ->
+                        val constraints = if (isLookingAhead) {
+                            Constraints.fixed(4 * ItemSize, 4 * ItemSize)
+                        } else {
+                            Constraints.fixed(postLookaheadSize, postLookaheadSize)
+                        }
+                        measurable.measure(constraints).run {
+                            layout(width, height) {
+                                place(0, 0)
+                            }
+                        }
+                    }) {
+                        items(4) {
+                            Box(
+                                Modifier
+                                    .requiredSize(ItemSize.dp)
+                                    .layout { measurable, constraints ->
+                                        measurable
+                                            .measure(constraints)
+                                            .run {
+                                                layout(width, height) {
+                                                    if (isLookingAhead) {
+                                                        lookaheadPositions[it] = coordinates!!
+                                                            .findRootCoordinates()
+                                                            .localLookaheadPositionOf(coordinates!!)
+                                                    } else {
+                                                        postLookaheadPositions[it] =
+                                                            coordinates!!.positionInRoot()
+                                                    }
+                                                }
+                                            }
+                                    })
+                        }
+                    }
+                }
+            }
+        }
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+        postLookaheadSize = (2.9f * ItemSize).toInt()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+        postLookaheadSize = (3.4f * ItemSize).toInt()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(ItemSize * 3, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+
+        // Shrinking post-lookahead size
+        postLookaheadSize = (2.7f * ItemSize).toInt()
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+
+        // Shrinking post-lookahead size
+        postLookaheadSize = (1.2f * ItemSize).toInt()
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun lookaheadSizeSmallerThanPostLookahead() {
+        val lookaheadPositions = mutableMapOf<Int, Offset>()
+        val postLookaheadPositions = mutableMapOf<Int, Offset>()
+        var lookaheadSize by mutableStateOf(ItemSize * 2)
+        var postLookaheadSize by mutableStateOf(ItemSize * 4)
+        rule.setContent {
+            LookaheadScope {
+                CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                    LazyColumnOrRow(Modifier.layout { measurable, _ ->
+                        val constraints = if (isLookingAhead) {
+                            Constraints.fixed(lookaheadSize, lookaheadSize)
+                        } else {
+                            Constraints.fixed(postLookaheadSize, postLookaheadSize)
+                        }
+                        measurable.measure(constraints).run {
+                            layout(width, height) {
+                                place(0, 0)
+                            }
+                        }
+                    }) {
+                        items(4) {
+                            Box(
+                                Modifier
+                                    .requiredSize(ItemSize.dp)
+                                    .layout { measurable, constraints ->
+                                        measurable
+                                            .measure(constraints)
+                                            .run {
+                                                layout(width, height) {
+                                                    if (isLookingAhead) {
+                                                        lookaheadPositions[it] = coordinates!!
+                                                            .findRootCoordinates()
+                                                            .localLookaheadPositionOf(coordinates!!)
+                                                    } else {
+                                                        postLookaheadPositions[it] =
+                                                            coordinates!!.positionInRoot()
+                                                    }
+                                                }
+                                            }
+                                    })
+                        }
+                    }
+                }
+            }
+        }
+        // postLookaheadSize was initialized to 4 * ItemSize
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(ItemSize * 3, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+        postLookaheadSize = (2.9f * ItemSize).toInt()
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+        postLookaheadSize = 2 * ItemSize
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+
+        // Growing post-lookahead size
+        postLookaheadSize = (2.7f * ItemSize).toInt()
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(ItemSize * 2, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+
+        // Shrinking post-lookahead size
+        postLookaheadSize = (1.2f * ItemSize).toInt()
+        postLookaheadPositions.clear()
+        rule.runOnIdle {
+            repeat(4) {
+                assertEquals(it * ItemSize, lookaheadPositions[it]?.mainAxisPosition)
+            }
+            assertEquals(0, postLookaheadPositions[0]?.mainAxisPosition)
+            assertEquals(ItemSize, postLookaheadPositions[1]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[2]?.mainAxisPosition)
+            assertEquals(null, postLookaheadPositions[3]?.mainAxisPosition)
+        }
+    }
+    private val Offset.mainAxisPosition get() = (if (vertical) y else x).roundToInt()
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun postLookaheadItemsComposed() {
+        lateinit var state: LazyListState
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LookaheadScope {
+                    state = rememberLazyListState()
+                    LazyColumnOrRow(Modifier.requiredSize(300.dp), state) {
+                        items(12, key = { it }) {
+                            Box(
+                                Modifier
+                                    .testTag("$it")
+                                    .then(
+                                        if (it == 0) {
+                                            Modifier.layout { measurable, constraints ->
+                                                val p = measurable.measure(constraints)
+                                                val size = if (isLookingAhead) 300 else 30
+                                                layout(size, size) {
+                                                    p.place(0, 0)
+                                                }
+                                            }
+                                        } else
+                                            Modifier.size(30.dp)
+                                    )
+                            )
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+
+        // Based on lookahead item 0 would be the only item needed, but post-lookahead calculation
+        // indicates 10 items will be needed to fill the viewport.
+        for (i in 0 until 10) {
+            rule.onNodeWithTag("$i")
+                .assertIsPlaced()
+        }
+        for (i in 10 until 12) {
+            rule.onNodeWithTag("$i")
+                .assertDoesNotExist()
+        }
+    }
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun postLookaheadItemsComposedBasedOnScrollDelta() {
+        var lookaheadSize by mutableStateOf(30)
+        var postLookaheadSize by mutableStateOf(lookaheadSize)
+        lateinit var state: LazyListState
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LookaheadScope {
+                    state = rememberLazyListState()
+                    LazyColumnOrRow(Modifier.requiredSize(300.dp), state) {
+                        items(12, key = { it }) {
+                            Box(
+                                Modifier
+                                    .testTag("$it")
+                                    .then(
+                                        if (it == 2) {
+                                            Modifier.layout { measurable, constraints ->
+                                                val p = measurable.measure(constraints)
+                                                val size = if (isLookingAhead)
+                                                    lookaheadSize
+                                                else
+                                                    postLookaheadSize
+                                                layout(size, size) {
+                                                    p.place(0, 0)
+                                                }
+                                            }
+                                        } else
+                                            Modifier.size(30.dp)
+                                    )
+                            )
+                        }
+                    }
+                }
+            }
+        }
+        rule.waitForIdle()
+
+        for (i in 0 until 12) {
+            if (i < 10) {
+                rule.onNodeWithTag("$i")
+                    .assertIsPlaced()
+            } else {
+                rule.onNodeWithTag("$i")
+                    .assertDoesNotExist()
+            }
+        }
+
+        lookaheadSize = 300
+        rule.runOnIdle {
+            runBlocking {
+                state.scrollBy(60f)
+            }
+        }
+        rule.waitForIdle()
+
+        rule.onNodeWithTag("0").assertIsNotPlaced()
+        rule.onNodeWithTag("1").assertIsNotPlaced()
+        for (i in 2 until 12) {
+            rule.onNodeWithTag("$i").assertIsPlaced()
+        }
+
+        postLookaheadSize = 300
+        for (i in 0 until 12) {
+            if (i == 2) {
+                rule.onNodeWithTag("$i").assertIsPlaced()
+            } else {
+                rule.onNodeWithTag("$i").assertIsNotPlaced()
+            }
+        }
+    }
+
+    @Test
     fun usingFillParentMaxSizeOnInfinityConstraintsIsIgnored() {
         rule.setContentWithTestViewConfiguration {
             Layout(content = {
@@ -2311,4 +2958,6 @@
                 endVelocity = 0f
             )
         }
-    }
\ No newline at end of file
+    }
+
+private const val ItemSize = 100
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
index 377a6ab..3d3b62e 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldInputServiceIntegrationTest.kt
@@ -444,6 +444,54 @@
         }
     }
 
+    @Test
+    fun updateTextLayoutResultCalledOnGlobalPositionChanged() {
+        var offset by mutableStateOf(IntOffset(0, 10))
+        val value = TextFieldValue("abc\nefg", TextRange(6))
+        lateinit var textLayoutResult: TextLayoutResult
+        val focusRequester = FocusRequester()
+
+        setContent {
+            Box(Modifier.offset { offset }) {
+                CoreTextField(
+                    value = value,
+                    modifier = Modifier.focusRequester(focusRequester),
+                    onValueChange = { },
+                    onTextLayout = { textLayoutResult = it }
+                )
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(platformTextInputService.lastInputValue).isNull()
+            assertThat(platformTextInputService.textLayoutResult).isNull()
+            assertThat(platformTextInputService.textLayoutPositionInWindow).isNull()
+            assertThat(platformTextInputService.innerTextFieldBounds).isNull()
+            assertThat(platformTextInputService.decorationBoxBounds).isNull()
+        }
+
+        rule.runOnUiThread {
+            focusRequester.requestFocus()
+        }
+
+        rule.runOnIdle {
+            assertThat(platformTextInputService.lastInputValue).isEqualTo(value)
+            assertThat(platformTextInputService.textLayoutResult).isNotNull()
+            assertThat(platformTextInputService.textLayoutResult).isEqualTo(textLayoutResult)
+            assertThat(platformTextInputService.textLayoutPositionInWindow)
+                .isEqualTo(offset.toOffset())
+            assertThat(platformTextInputService.innerTextFieldBounds).isNotNull()
+            assertThat(platformTextInputService.decorationBoxBounds).isNotNull()
+        }
+
+        offset = IntOffset(10, 20)
+
+        rule.runOnIdle {
+            assertThat(platformTextInputService.textLayoutPositionInWindow)
+                .isEqualTo(offset.toOffset())
+        }
+    }
+
     private fun setContent(content: @Composable () -> Unit) {
         rule.setContent {
             focusManager = LocalFocusManager.current
@@ -464,6 +512,11 @@
         var lastInputValue: TextFieldValue? = null
         var lastInputImeOptions: ImeOptions? = null
 
+        var textLayoutResult: TextLayoutResult? = null
+        var textLayoutPositionInWindow: Offset? = null
+        var innerTextFieldBounds: Rect? = null
+        var decorationBoxBounds: Rect? = null
+
         override fun startInput(
             value: TextFieldValue,
             imeOptions: ImeOptions,
@@ -498,5 +551,19 @@
         override fun notifyFocusedRect(rect: Rect) {
             focusedRect = rect
         }
+
+        override fun updateTextLayoutResult(
+            textFieldValue: TextFieldValue,
+            textLayoutResult: TextLayoutResult,
+            textLayoutPositionInWindow: Offset,
+            innerTextFieldBounds: Rect,
+            decorationBoxBounds: Rect
+        ) {
+            lastInputValue = textFieldValue
+            this.textLayoutResult = textLayoutResult
+            this.textLayoutPositionInWindow = textLayoutPositionInWindow
+            this.innerTextFieldBounds = innerTextFieldBounds
+            this.decorationBoxBounds = decorationBoxBounds
+        }
     }
 }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
index 7725cf0..08cbe9d 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text2/TextFieldCursorTest.kt
@@ -80,6 +80,7 @@
 import com.google.common.truth.Truth.assertThat
 import kotlin.math.ceil
 import kotlin.math.floor
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 
@@ -533,6 +534,7 @@
             .assertCursor(cursorTopCenterInLtr)
     }
 
+    @Ignore("b/285407485")
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun brushChanged_doesntResetTimer() {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
index 26dd173..3ed0be0 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
@@ -55,6 +55,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.unit.toOffset
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
@@ -349,6 +350,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 283292820)
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun selectionChanges_cursorNotBlinking() = with(rule.density) {
         rule.mainClock.autoAdvance = false
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher.android.kt
index 3498cb7..bfec568 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetcher.android.kt
@@ -20,7 +20,6 @@
 import android.view.Display
 import android.view.View
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState.AverageTimeTracker
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.RememberObserver
 import androidx.compose.runtime.collection.mutableVectorOf
@@ -72,7 +71,26 @@
  *    Frame 4 - prefetch [e], [f]
  *    Something similar is not possible with LazyColumn yet.
  *
- * 2) Prefetch is not aware of item type.
+ * 2) Prefetching time estimation only captured during the prefetch.
+ *    We currently don't track the time of the regular subcompose call happened during the regular
+ *    measure pass, only the ones which are done during the prefetching. The downside is we build
+ *    our prefetch information only after scrolling has started and items are showing up. Your very
+ *    first scroll won't know if it's safe to prefetch. Why:
+ *    a) SubcomposeLayout is not exposing an API to understand if subcompose() call is going to
+ *    do the real work. The work could be skipped if the same lambda was passed as for the
+ *    previous invocation or if there were no recompositions scheduled. We could workaround it
+ *    by keeping the extra state in LazyListState about what items we already composed and to
+ *    only measure the first composition for the given slot, or consider exposing extra
+ *    information in SubcomposeLayoutState API.
+ *    b) It allows us to nicely decouple the logic, now the prefetching logic is build on
+ *    top of the regular LazyColumn measuring functionallity and the main logic knows nothing
+ *    about prefetch
+ *    c) Maybe the better approach would be to wait till the low-level runtime infra is ready to
+ *    do subcompositions on the different threads which illuminates the need to calculate the
+ *    deadlines completely.
+ *    Tracking bug: b/187393381.
+ *
+ * 3) Prefetch is not aware of item type.
  *    RecyclerView separates timing metadata about different item types. For example, in play
  *    store style UI, this allows RecyclerView to separately estimate the cost of a header,
  *    separator, and item row. In this implementation, all of these would be averaged together in
@@ -103,6 +121,14 @@
      */
     private val prefetchRequests = mutableVectorOf<PrefetchRequest>()
 
+    /**
+     * Average time the prefetching operations takes. Keeping it allows us to not start the work
+     * if in this frame we are most likely not going to finish the work in time to not delay the
+     * next frame.
+     */
+    private var averagePrecomposeTimeNs: Long = 0
+    private var averagePremeasureTimeNs: Long = 0
+
     private var prefetchScheduled = false
 
     private val choreographer = Choreographer.getInstance()
@@ -114,10 +140,6 @@
         calculateFrameIntervalIfNeeded(view)
     }
 
-    override val timeTracker: AverageTimeTracker = object : AverageTimeTracker() {
-        override fun currentTime(): Long = System.nanoTime()
-    }
-
     /**
      * Callback to be executed when the prefetching is needed.
      * [prefetchRequests] will be used as an input.
@@ -143,14 +165,15 @@
                     val beforeTimeNs = System.nanoTime()
                     // check if there is enough time left in this frame. otherwise, we schedule
                     // a next frame callback in which we will post the message in the handler again.
-                    if (enoughTimeLeft(beforeTimeNs, nextFrameNs, timeTracker.compositionTimeNs)) {
+                    if (enoughTimeLeft(beforeTimeNs, nextFrameNs, averagePrecomposeTimeNs)) {
                         val key = itemProvider.getKey(request.index)
                         val contentType = itemProvider.getContentType(request.index)
                         val content = itemContentFactory.getContent(request.index, key, contentType)
-                        timeTracker.trackComposition {
-                            request.precomposeHandle =
-                                subcomposeLayoutState.precompose(key, content)
-                        }
+                        request.precomposeHandle = subcomposeLayoutState.precompose(key, content)
+                        averagePrecomposeTimeNs = calculateAverageTime(
+                            System.nanoTime() - beforeTimeNs,
+                            averagePrecomposeTimeNs
+                        )
                     } else {
                         scheduleForNextFrame = true
                     }
@@ -159,16 +182,18 @@
                 check(!request.measured) { "request already measured" }
                 trace("compose:lazylist:prefetch:measure") {
                     val beforeTimeNs = System.nanoTime()
-                    if (enoughTimeLeft(beforeTimeNs, nextFrameNs, timeTracker.measurementTimeNs)) {
+                    if (enoughTimeLeft(beforeTimeNs, nextFrameNs, averagePremeasureTimeNs)) {
                         val handle = request.precomposeHandle!!
-                        timeTracker.trackMeasurement {
-                            repeat(handle.placeablesCount) { placeableIndex ->
-                                handle.premeasure(
-                                    placeableIndex,
-                                    request.constraints
-                                )
-                            }
+                        repeat(handle.placeablesCount) { placeableIndex ->
+                            handle.premeasure(
+                                placeableIndex,
+                                request.constraints
+                            )
                         }
+                        averagePremeasureTimeNs = calculateAverageTime(
+                            System.nanoTime() - beforeTimeNs,
+                            averagePremeasureTimeNs
+                        )
                         // we finished this request
                         prefetchRequests.removeAt(0)
                     } else {
@@ -201,6 +226,18 @@
         }
     }
 
+    private fun calculateAverageTime(new: Long, current: Long): Long {
+        // Calculate a weighted moving average of time taken to compose an item. We use weighted
+        // moving average to bias toward more recent measurements, and to minimize storage /
+        // computation cost. (the idea is taken from RecycledViewPool)
+        return if (current == 0L) {
+            new
+        } else {
+            // dividing first to avoid a potential overflow
+            current / 4 * 3 + new / 4
+        }
+    }
+
     override fun schedulePrefetch(
         index: Int,
         constraints: Constraints
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/MathUtils.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/MathUtils.kt
index ba1dcff1..4a2851a 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/MathUtils.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text2/input/internal/MathUtils.kt
@@ -33,4 +33,4 @@
     // HD 2-12 Overflow iff the arguments have different signs and
     // the sign of the result is different from the sign of x
     return if (this xor right and (this xor result) < 0) defaultValue() else result
-}
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
index 8bb9b13f..f54c401 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/AnchoredDraggable.kt
@@ -215,9 +215,7 @@
 @ExperimentalFoundationApi
 class AnchoredDraggableState<T>(
     initialValue: T,
-    @Suppress("PrimitiveInLambda")
     internal val positionalThreshold: (totalDistance: Float) -> Float,
-    @Suppress("PrimitiveInLambda")
     internal val velocityThreshold: () -> Float,
     val animationSpec: AnimationSpec<Float>,
     internal val confirmValueChange: (newValue: T) -> Boolean = { true }
@@ -244,9 +242,7 @@
     constructor(
         initialValue: T,
         anchors: DraggableAnchors<T>,
-        @Suppress("PrimitiveInLambda")
         positionalThreshold: (totalDistance: Float) -> Float,
-        @Suppress("PrimitiveInLambda")
         velocityThreshold: () -> Float,
         animationSpec: AnimationSpec<Float>,
         confirmValueChange: (newValue: T) -> Boolean = { true }
@@ -630,9 +626,7 @@
         @ExperimentalFoundationApi
         fun <T : Any> Saver(
             animationSpec: AnimationSpec<Float>,
-            @Suppress("PrimitiveInLambda")
             positionalThreshold: (distance: Float) -> Float,
-            @Suppress("PrimitiveInLambda")
             velocityThreshold: () -> Float,
             confirmValueChange: (T) -> Boolean = { true },
         ) = Saver<AnchoredDraggableState<T>, T>(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
index 3022dc5..5826647 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/DragGestureDetector.kt
@@ -284,7 +284,6 @@
  */
 suspend fun AwaitPointerEventScope.awaitVerticalTouchSlopOrCancellation(
     pointerId: PointerId,
-    @Suppress("PrimitiveInLambda")
     onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
@@ -296,7 +295,6 @@
 internal suspend fun AwaitPointerEventScope.awaitVerticalPointerSlopOrCancellation(
     pointerId: PointerId,
     pointerType: PointerType,
-    @Suppress("PrimitiveInLambda")
     onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
@@ -384,11 +382,9 @@
  * @see detectHorizontalDragGestures
  */
 suspend fun PointerInputScope.detectVerticalDragGestures(
-    @Suppress("PrimitiveInLambda")
     onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
-    @Suppress("PrimitiveInLambda")
     onVerticalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
 ) {
     awaitEachGesture {
@@ -439,7 +435,6 @@
  */
 suspend fun AwaitPointerEventScope.awaitHorizontalTouchSlopOrCancellation(
     pointerId: PointerId,
-    @Suppress("PrimitiveInLambda")
     onTouchSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
@@ -451,7 +446,6 @@
 internal suspend fun AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation(
     pointerId: PointerId,
     pointerType: PointerType,
-    @Suppress("PrimitiveInLambda")
     onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
@@ -536,11 +530,9 @@
  * @see detectDragGestures
  */
 suspend fun PointerInputScope.detectHorizontalDragGestures(
-    @Suppress("PrimitiveInLambda")
     onDragStart: (Offset) -> Unit = { },
     onDragEnd: () -> Unit = { },
     onDragCancel: () -> Unit = { },
-    @Suppress("PrimitiveInLambda")
     onHorizontalDrag: (change: PointerInputChange, dragAmount: Float) -> Unit
 ) {
     awaitEachGesture {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
index 6e27416..ca3d8a2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt
@@ -122,10 +122,7 @@
  *
  * @param onDelta callback invoked when drag occurs. The callback receives the delta in pixels.
  */
-fun DraggableState(
-    @Suppress("PrimitiveInLambda")
-    onDelta: (Float) -> Unit
-): DraggableState =
+fun DraggableState(onDelta: (Float) -> Unit): DraggableState =
     DefaultDraggableState(onDelta)
 
 /**
@@ -140,10 +137,7 @@
  * @param onDelta callback invoked when drag occurs. The callback receives the delta in pixels.
  */
 @Composable
-fun rememberDraggableState(
-    @Suppress("PrimitiveInLambda")
-    onDelta: (Float) -> Unit
-): DraggableState {
+fun rememberDraggableState(onDelta: (Float) -> Unit): DraggableState {
     val onDeltaState = rememberUpdatedState(onDelta)
     return remember { DraggableState { onDeltaState.value.invoke(it) } }
 }
@@ -187,9 +181,7 @@
     enabled: Boolean = true,
     interactionSource: MutableInteractionSource? = null,
     startDragImmediately: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {},
-    @Suppress("PrimitiveInLambda")
     onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {},
     reverseDirection: Boolean = false
 ): Modifier = this then DraggableElement(
@@ -542,7 +534,6 @@
     pointerId: PointerId,
     onDrag: (PointerInputChange) -> Unit
 ): Boolean {
-    @Suppress("PrimitiveInLambda")
     val motionFromChange: (PointerInputChange) -> Float = if (orientation == Orientation.Vertical) {
         { it.positionChangeIgnoreConsumed().y }
     } else {
@@ -557,10 +548,7 @@
     )?.let(onDrag) != null
 }
 
-private class DefaultDraggableState(
-    @Suppress("PrimitiveInLambda")
-    val onDelta: (Float) -> Unit
-) : DraggableState {
+private class DefaultDraggableState(val onDelta: (Float) -> Unit) : DraggableState {
 
     private val dragScope: DragScope = object : DragScope {
         override fun dragBy(pixels: Float): Unit = onDelta(pixels)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
index 1eca953..e56a7a43 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
@@ -122,10 +122,7 @@
  * callback receives the delta in pixels. Callers should update their state in this lambda and
  * return the amount of delta consumed
  */
-fun ScrollableState(
-    @Suppress("PrimitiveInLambda")
-    consumeScrollDelta: (Float) -> Float
-): ScrollableState {
+fun ScrollableState(consumeScrollDelta: (Float) -> Float): ScrollableState {
     return DefaultScrollableState(consumeScrollDelta)
 }
 
@@ -144,10 +141,7 @@
  * return the amount of delta consumed
  */
 @Composable
-fun rememberScrollableState(
-    @Suppress("PrimitiveInLambda")
-    consumeScrollDelta: (Float) -> Float
-): ScrollableState {
+fun rememberScrollableState(consumeScrollDelta: (Float) -> Float): ScrollableState {
     val lambdaState = rememberUpdatedState(consumeScrollDelta)
     return remember { ScrollableState { lambdaState.value.invoke(it) } }
 }
@@ -164,10 +158,7 @@
     fun scrollBy(pixels: Float): Float
 }
 
-private class DefaultScrollableState(
-    @Suppress("PrimitiveInLambda")
-    val onDelta: (Float) -> Float
-) : ScrollableState {
+private class DefaultScrollableState(val onDelta: (Float) -> Float) : ScrollableState {
 
     private val scrollScope: ScrollScope = object : ScrollScope {
         override fun scrollBy(pixels: Float): Float {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
index 0aa0142..8d8c460 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformGestureDetector.kt
@@ -46,7 +46,6 @@
  */
 suspend fun PointerInputScope.detectTransformGestures(
     panZoomLock: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     onGesture: (centroid: Offset, pan: Offset, zoom: Float, rotation: Float) -> Unit
 ) {
     awaitEachGesture {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
index 9372ab6..39b957b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
@@ -94,7 +94,6 @@
  * for pan and degrees for rotation. Callers should update their state in this lambda.
  */
 fun TransformableState(
-    @Suppress("PrimitiveInLambda")
     onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit
 ): TransformableState = DefaultTransformableState(onTransformation)
 
@@ -114,7 +113,6 @@
  */
 @Composable
 fun rememberTransformableState(
-    @Suppress("PrimitiveInLambda")
     onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit
 ): TransformableState {
     val lambdaState = rememberUpdatedState(onTransformation)
@@ -232,7 +230,6 @@
 }
 
 private class DefaultTransformableState(
-    @Suppress("PrimitiveInLambda")
     val onTransformation: (zoomChange: Float, panChange: Offset, rotationChange: Float) -> Unit
 ) : TransformableState {
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationState.kt
index 177e729..e35bf2d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/UpdatableAnimationState.kt
@@ -84,7 +84,6 @@
      */
     @OptIn(ExperimentalContracts::class)
     suspend fun animateToZero(
-        @Suppress("PrimitiveInLambda")
         beforeFrame: (valueDelta: Float) -> Unit,
         afterFrame: () -> Unit,
     ) {
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 ced560d..a9a6dc3 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
@@ -112,7 +112,6 @@
      */
     suspend fun ScrollScope.performFling(
         initialVelocity: Float,
-        @Suppress("PrimitiveInLambda")
         onSettlingDistanceUpdated: (Float) -> Unit
     ): Float {
         val (remainingOffset, remainingState) = fling(initialVelocity, onSettlingDistanceUpdated)
@@ -126,7 +125,6 @@
 
     private suspend fun ScrollScope.fling(
         initialVelocity: Float,
-        @Suppress("PrimitiveInLambda")
         onRemainingScrollOffsetUpdate: (Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
         // If snapping from scroll (short snap) or fling (long snap)
@@ -144,7 +142,6 @@
 
     private suspend fun ScrollScope.shortSnap(
         velocity: Float,
-        @Suppress("PrimitiveInLambda")
         onRemainingScrollOffsetUpdate: (Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
         debugLog { "Short Snapping" }
@@ -168,7 +165,6 @@
 
     private suspend fun ScrollScope.longSnap(
         initialVelocity: Float,
-        @Suppress("PrimitiveInLambda")
         onAnimationStep: (remainingScrollOffset: Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
         debugLog { "Long Snapping" }
@@ -206,7 +202,6 @@
     private suspend fun ScrollScope.runApproach(
         initialTargetOffset: Float,
         initialVelocity: Float,
-        @Suppress("PrimitiveInLambda")
         onAnimationStep: (delta: Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
 
@@ -311,7 +306,6 @@
     animation: ApproachAnimation<Float, AnimationVector1D>,
     snapLayoutInfoProvider: SnapLayoutInfoProvider,
     density: Density,
-    @Suppress("PrimitiveInLambda")
     onAnimationStep: (delta: Float) -> Unit
 ): AnimationResult<Float, AnimationVector1D> {
 
@@ -355,7 +349,6 @@
     targetOffset: Float,
     animationState: AnimationState<Float, AnimationVector1D>,
     decayAnimationSpec: DecayAnimationSpec<Float>,
-    @Suppress("PrimitiveInLambda")
     onAnimationStep: (delta: Float) -> Unit
 ): AnimationResult<Float, AnimationVector1D> {
     var previousValue = 0f
@@ -407,7 +400,6 @@
     cancelOffset: Float,
     animationState: AnimationState<Float, AnimationVector1D>,
     snapAnimationSpec: AnimationSpec<Float>,
-    @Suppress("PrimitiveInLambda")
     onAnimationStep: (delta: Float) -> Unit
 ): AnimationResult<Float, AnimationVector1D> {
     var consumedUpToNow = 0f
@@ -463,7 +455,6 @@
         scope: ScrollScope,
         offset: Float,
         velocity: Float,
-        @Suppress("PrimitiveInLambda")
         onAnimationStep: (delta: Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
         val animationState = AnimationState(initialValue = 0f, initialVelocity = velocity)
@@ -490,7 +481,6 @@
         scope: ScrollScope,
         offset: Float,
         velocity: Float,
-        @Suppress("PrimitiveInLambda")
         onAnimationStep: (delta: Float) -> Unit
     ): AnimationResult<Float, AnimationVector1D> {
         val animationState = AnimationState(initialValue = 0f, initialVelocity = velocity)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt
index cde40f1..98ea94e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt
@@ -77,11 +77,8 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any? = { null },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyItemScope.(index: Int) -> Unit
     ) {
         error("The method is not implemented")
@@ -90,9 +87,7 @@
     @Deprecated("Use the non deprecated overload", level = DeprecationLevel.HIDDEN)
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyItemScope.(index: Int) -> Unit
     ) {
         items(count, key, { null }, itemContent)
@@ -175,7 +170,6 @@
  */
 inline fun <T> LazyListScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
@@ -190,7 +184,6 @@
 @Deprecated("Use the non deprecated overload", level = DeprecationLevel.HIDDEN)
 inline fun <T> LazyListScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
 ) = itemsIndexed(items, key, itemContent = itemContent)
@@ -247,7 +240,6 @@
  */
 inline fun <T> LazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
@@ -262,7 +254,6 @@
 @Deprecated("Use the non deprecated overload", level = DeprecationLevel.HIDDEN)
 inline fun <T> LazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
 ) = itemsIndexed(items, key, itemContent = itemContent)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 6f41836..99f6a33 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -34,6 +34,7 @@
 import androidx.compose.foundation.overscroll
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.snapshots.Snapshot
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -79,6 +80,8 @@
     val itemProviderLambda = rememberLazyListItemProviderLambda(state, content)
 
     val semanticState = rememberLazyListSemanticState(state, isVertical)
+    val scope = rememberCoroutineScope()
+    state.coroutineScope = scope
 
     val measurePolicy = rememberLazyListMeasurePolicy(
         itemProviderLambda,
@@ -182,6 +185,8 @@
     verticalArrangement
 ) {
     { containerConstraints ->
+        // Tracks if the lookahead pass has occurred
+        val hasLookaheadPassOccurred = state.hasLookaheadPassOccurred || isLookingAhead
         checkScrollableContainerConstraints(
             containerConstraints,
             if (isVertical) Orientation.Vertical else Orientation.Horizontal
@@ -307,6 +312,12 @@
             beyondBoundsInfo = state.beyondBoundsInfo
         )
 
+        val scrollToBeConsumed = if (isLookingAhead || !hasLookaheadPassOccurred) {
+            state.scrollToBeConsumed
+        } else {
+            state.scrollDeltaBetweenPasses
+        }
+
         measureLazyList(
             itemsCount = itemsCount,
             measuredItemProvider = measuredItemProvider,
@@ -316,7 +327,7 @@
             spaceBetweenItems = spaceBetweenItems,
             firstVisibleItemIndex = firstVisibleItemIndex,
             firstVisibleItemScrollOffset = firstVisibleScrollOffset,
-            scrollToBeConsumed = state.scrollToBeConsumed,
+            scrollToBeConsumed = scrollToBeConsumed,
             constraints = contentConstraints,
             isVertical = isVertical,
             headerIndexes = itemProvider.headerIndexes,
@@ -327,6 +338,9 @@
             placementAnimator = state.placementAnimator,
             beyondBoundsItemCount = beyondBoundsItemCount,
             pinnedItems = pinnedItems,
+            hasLookaheadPassOccurred = hasLookaheadPassOccurred,
+            isLookingAhead = isLookingAhead,
+            postLookaheadLayoutInfo = state.postLookaheadLayoutInfo,
             layout = { width, height, placement ->
                 layout(
                     containerConstraints.constrainWidth(width + totalHorizontalPadding),
@@ -336,7 +350,7 @@
                 )
             }
         ).also {
-            state.applyMeasureResult(it)
+            state.applyMeasureResult(it, isLookingAhead)
         }
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt
index 4b05ce1..585f230 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListIntervalContent.kt
@@ -78,10 +78,7 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyListInterval(
-    @Suppress("PrimitiveInLambda")
     override val key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     override val type: ((index: Int) -> Any?),
-    @Suppress("PrimitiveInLambda")
     val item: @Composable LazyItemScope.(index: Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
index ec0fb82..7ad2893 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
@@ -56,7 +56,9 @@
         layoutHeight: Int,
         positionedItems: MutableList<LazyListMeasuredItem>,
         itemProvider: LazyListMeasuredItemProvider,
-        isVertical: Boolean
+        isVertical: Boolean,
+        isLookingAhead: Boolean,
+        hasLookaheadOccurred: Boolean
     ) {
         if (!positionedItems.fastAny { it.hasAnimations } && activeKeys.isEmpty()) {
             // no animations specified - no work needed
@@ -66,6 +68,7 @@
 
         val previousFirstVisibleIndex = firstVisibleIndex
         firstVisibleIndex = positionedItems.firstOrNull()?.index ?: 0
+
         val previousKeyToIndexMap = keyIndexMap
         keyIndexMap = itemProvider.keyIndexMap
 
@@ -78,6 +81,9 @@
             IntOffset(consumedScroll, 0)
         }
 
+        // Only setup animations when we have access to target value in the current pass, which
+        // means lookahead pass, or regular pass when not in a lookahead scope.
+        val shouldSetupAnimation = isLookingAhead || !hasLookaheadOccurred
         // first add all items we had in the previous run
         movingAwayKeys.addAll(activeKeys)
         // iterate through the items which are visible (without animated offsets)
@@ -102,12 +108,15 @@
                         )
                     }
                 } else {
-                    item.forEachNode { _, node ->
-                        if (node.rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized) {
-                            node.rawOffset += scrollOffset
+                    if (shouldSetupAnimation) {
+                        item.forEachNode { _, node ->
+                            if (node.rawOffset != LazyLayoutAnimateItemModifierNode.NotInitialized
+                            ) {
+                                node.rawOffset += scrollOffset
+                            }
                         }
+                        startAnimationsIfNeeded(item)
                     }
-                    startAnimationsIfNeeded(item)
                 }
             } else {
                 // no animation, clean up if needed
@@ -116,20 +125,22 @@
         }
 
         var accumulatedOffset = 0
-        movingInFromStartBound.sortByDescending { previousKeyToIndexMap.getIndex(it.key) }
-        movingInFromStartBound.fastForEach { item ->
-            accumulatedOffset += item.size
-            val mainAxisOffset = 0 - accumulatedOffset
-            initializeNode(item, mainAxisOffset)
-            startAnimationsIfNeeded(item)
-        }
-        accumulatedOffset = 0
-        movingInFromEndBound.sortBy { previousKeyToIndexMap.getIndex(it.key) }
-        movingInFromEndBound.fastForEach { item ->
-            val mainAxisOffset = mainAxisLayoutSize + accumulatedOffset
-            accumulatedOffset += item.size
-            initializeNode(item, mainAxisOffset)
-            startAnimationsIfNeeded(item)
+        if (shouldSetupAnimation) {
+            movingInFromStartBound.sortByDescending { previousKeyToIndexMap.getIndex(it.key) }
+            movingInFromStartBound.fastForEach { item ->
+                accumulatedOffset += item.size
+                val mainAxisOffset = 0 - accumulatedOffset
+                initializeNode(item, mainAxisOffset)
+                startAnimationsIfNeeded(item)
+            }
+            accumulatedOffset = 0
+            movingInFromEndBound.sortBy { previousKeyToIndexMap.getIndex(it.key) }
+            movingInFromEndBound.fastForEach { item ->
+                val mainAxisOffset = mainAxisLayoutSize + accumulatedOffset
+                accumulatedOffset += item.size
+                initializeNode(item, mainAxisOffset)
+                startAnimationsIfNeeded(item)
+            }
         }
 
         movingAwayKeys.forEach { key ->
@@ -168,9 +179,11 @@
             val mainAxisOffset = 0 - accumulatedOffset
 
             item.position(mainAxisOffset, layoutWidth, layoutHeight)
-            positionedItems.add(item)
-            startAnimationsIfNeeded(item)
+            if (shouldSetupAnimation) {
+                startAnimationsIfNeeded(item)
+            }
         }
+
         accumulatedOffset = 0
         movingAwayToEndBound.sortBy { keyIndexMap.getIndex(it.key) }
         movingAwayToEndBound.fastForEach { item ->
@@ -178,10 +191,16 @@
             accumulatedOffset += item.size
 
             item.position(mainAxisOffset, layoutWidth, layoutHeight)
-            positionedItems.add(item)
-            startAnimationsIfNeeded(item)
+            if (shouldSetupAnimation) {
+                startAnimationsIfNeeded(item)
+            }
         }
 
+        // This adds the new items to the list of positioned items while keeping the index of
+        // the positioned items sorted in ascending order.
+        positionedItems.addAll(0, movingAwayToStartBound.apply { reverse() })
+        positionedItems.addAll(movingAwayToEndBound)
+
         movingInFromStartBound.clear()
         movingInFromEndBound.clear()
         movingAwayToStartBound.clear()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
index a352409..3a7dce6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
@@ -27,6 +27,8 @@
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.constrainHeight
 import androidx.compose.ui.unit.constrainWidth
+import androidx.compose.ui.util.fastAny
+import androidx.compose.ui.util.fastFirstOrNull
 import androidx.compose.ui.util.fastForEach
 import kotlin.math.abs
 import kotlin.math.roundToInt
@@ -57,6 +59,9 @@
     placementAnimator: LazyListItemPlacementAnimator,
     beyondBoundsItemCount: Int,
     pinnedItems: List<Int>,
+    hasLookaheadPassOccurred: Boolean,
+    isLookingAhead: Boolean,
+    postLookaheadLayoutInfo: LazyListLayoutInfo?,
     @Suppress("PrimitiveInLambda")
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): LazyListMeasureResult {
@@ -70,6 +75,7 @@
             canScrollForward = false,
             consumedScroll = 0f,
             measureResult = layout(constraints.minWidth, constraints.minHeight) {},
+            scrollBackAmount = 0f,
             visibleItemsInfo = emptyList(),
             viewportStartOffset = -beforeContentPadding,
             viewportEndOffset = mainAxisAvailableSize + afterContentPadding,
@@ -77,7 +83,7 @@
             reverseLayout = reverseLayout,
             orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
             afterContentPadding = afterContentPadding,
-            mainAxisItemSpacing = spaceBetweenItems
+            mainAxisItemSpacing = spaceBetweenItems,
         )
     } else {
         var currentFirstItemIndex = firstVisibleItemIndex
@@ -172,6 +178,7 @@
             index++
         }
 
+        val preScrollBackScrollDelta = scrollDelta
         // we didn't fill the whole viewport with items starting from firstVisibleItemIndex.
         // lets try to scroll back if we have enough items before firstVisibleItemIndex.
         if (currentMainAxisOffset < maxOffset) {
@@ -208,6 +215,16 @@
             scrollToBeConsumed
         }
 
+        val unconsumedScroll = scrollToBeConsumed - consumedScroll
+        // When scrolling to the bottom via gesture, there could be scrollback due to
+        // not being able to consume the whole scroll. In that case, the amount of
+        // scrollBack is the inverse of unconsumed scroll.
+        val scrollBackAmount: Float =
+            if (isLookingAhead && scrollDelta > preScrollBackScrollDelta && unconsumedScroll <= 0) {
+                scrollDelta - preScrollBackScrollDelta + unconsumedScroll
+            } else
+                0f
+
         // the initial offset for items from visibleItems list
         require(currentFirstItemScrollOffset >= 0) { "negative currentFirstItemScrollOffset" }
         val visibleItemsScrollOffset = -currentFirstItemScrollOffset
@@ -248,7 +265,10 @@
             measuredItemProvider = measuredItemProvider,
             itemsCount = itemsCount,
             beyondBoundsItemCount = beyondBoundsItemCount,
-            pinnedItems = pinnedItems
+            pinnedItems = pinnedItems,
+            consumedScroll = consumedScroll,
+            isLookingAhead = isLookingAhead,
+            lastPostLookaheadLayoutInfo = postLookaheadLayoutInfo
         )
 
         // Update maxCrossAxis with extra items
@@ -287,7 +307,9 @@
             layoutHeight = layoutHeight,
             positionedItems = positionedItems,
             itemProvider = measuredItemProvider,
-            isVertical = isVertical
+            isVertical = isVertical,
+            isLookingAhead = isLookingAhead,
+            hasLookaheadOccurred = hasLookaheadPassOccurred
         )
 
         val headerItem = if (headerIndexes.isNotEmpty()) {
@@ -311,18 +333,19 @@
             measureResult = layout(layoutWidth, layoutHeight) {
                 positionedItems.fastForEach {
                     if (it !== headerItem) {
-                        it.place(this)
+                        it.place(this, isLookingAhead)
                     }
                 }
                 // the header item should be placed (drawn) after all other items
-                headerItem?.place(this)
+                headerItem?.place(this, isLookingAhead)
             },
-            viewportStartOffset = -beforeContentPadding,
-            viewportEndOffset = maxOffset + afterContentPadding,
+            scrollBackAmount = scrollBackAmount,
             visibleItemsInfo = if (noExtraItems) positionedItems else positionedItems.fastFilter {
                 (it.index >= visibleItems.first().index && it.index <= visibleItems.last().index) ||
                     it === headerItem
             },
+            viewportStartOffset = -beforeContentPadding,
+            viewportEndOffset = maxOffset + afterContentPadding,
             totalItemsCount = itemsCount,
             reverseLayout = reverseLayout,
             orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal,
@@ -337,7 +360,10 @@
     measuredItemProvider: LazyListMeasuredItemProvider,
     itemsCount: Int,
     beyondBoundsItemCount: Int,
-    pinnedItems: List<Int>
+    pinnedItems: List<Int>,
+    consumedScroll: Float,
+    isLookingAhead: Boolean,
+    lastPostLookaheadLayoutInfo: LazyListLayoutInfo?
 ): List<LazyListMeasuredItem> {
     var list: MutableList<LazyListMeasuredItem>? = null
 
@@ -357,6 +383,60 @@
         }
     }
 
+    if (isLookingAhead) {
+        // Check if there's any item that needs to be composed based on last postLookaheadLayoutInfo
+        if (lastPostLookaheadLayoutInfo != null &&
+            lastPostLookaheadLayoutInfo.visibleItemsInfo.isNotEmpty()
+        ) {
+            // Find first item with index > end. Note that `visibleItemsInfo.last()` may not have
+            // the largest index as the last few items could be added to animate item placement.
+            val firstItem = lastPostLookaheadLayoutInfo.visibleItemsInfo.run {
+                var found: LazyListItemInfo? = null
+                for (i in size - 1 downTo 0) {
+                    if (this[i].index > end && (i == 0 || this[i - 1].index <= end)) {
+                        found = this[i]
+                        break
+                    }
+                }
+                found
+            }
+            val lastVisibleItem = lastPostLookaheadLayoutInfo.visibleItemsInfo.last()
+            if (firstItem != null) {
+                for (i in firstItem.index..lastVisibleItem.index) {
+                    if (list?.fastAny { it.index == i } != null) {
+                        if (list == null) list = mutableListOf()
+                        list?.add(measuredItemProvider.getAndMeasure(i))
+                    }
+                }
+            }
+
+            // Calculate the additional offset to subcompose based on what was shown in the
+            // previous post-loookahead pass and the scroll consumed.
+            val additionalOffset =
+                lastPostLookaheadLayoutInfo.viewportEndOffset - lastVisibleItem.offset -
+                    lastVisibleItem.size - consumedScroll
+            if (additionalOffset > 0) {
+                var index = lastVisibleItem.index + 1
+                var totalOffset = 0
+                while (index < itemsCount && totalOffset < additionalOffset) {
+                    val item = if (index <= end) {
+                        visibleItems.fastFirstOrNull { it.index == index }
+                    } else null
+                        ?: list?.fastFirstOrNull { it.index == index }
+                    if (item != null) {
+                        index++
+                        totalOffset += item.sizeWithSpacings
+                    } else {
+                        if (list == null) list = mutableListOf()
+                        list?.add(measuredItemProvider.getAndMeasure(index))
+                        index++
+                        totalOffset += list!!.last().sizeWithSpacings
+                    }
+                }
+            }
+        }
+    }
+
     return list ?: emptyList()
 }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
index d291659..9a7c9999 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasureResult.kt
@@ -35,6 +35,8 @@
     val consumedScroll: Float,
     /** MeasureResult defining the layout.*/
     measureResult: MeasureResult,
+    /** The amount of scroll-back that happened due to reaching the end of the list. **/
+    val scrollBackAmount: Float,
     // properties representing the info needed for LazyListLayoutInfo:
     /** see [LazyListLayoutInfo.visibleItemsInfo] */
     override val visibleItemsInfo: List<LazyListItemInfo>,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
index b7993d7..70f38cc 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItem.kt
@@ -18,6 +18,7 @@
 
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode
+import androidx.compose.foundation.lazy.layout.LazyLayoutAnimateItemModifierNode.Companion.NotInitialized
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.unit.IntOffset
@@ -134,6 +135,7 @@
 
     fun place(
         scope: Placeable.PlacementScope,
+        isLookingAhead: Boolean
     ) = with(scope) {
         require(mainAxisLayoutSize != Unset) { "position() should be called first" }
         repeat(placeablesCount) { index ->
@@ -143,14 +145,26 @@
             var offset = getOffset(index)
             val animateNode = getParentData(index) as? LazyLayoutAnimateItemModifierNode
             if (animateNode != null) {
-                val animatedOffset = offset + animateNode.placementDelta
-                // cancel the animation if current and target offsets are both out of the bounds.
-                if ((offset.mainAxis <= minOffset && animatedOffset.mainAxis <= minOffset) ||
-                    (offset.mainAxis >= maxOffset && animatedOffset.mainAxis >= maxOffset)
-                ) {
-                    animateNode.cancelAnimation()
+                if (isLookingAhead) {
+                    // Skip animation in lookahead pass
+                    animateNode.lookaheadOffset = offset
+                } else {
+                    val targetOffset = if (animateNode.lookaheadOffset != NotInitialized) {
+                        animateNode.lookaheadOffset
+                    } else {
+                        offset
+                    }
+                    val animatedOffset = targetOffset + animateNode.placementDelta
+                    // cancel the animation if current and target offsets are both out of the bounds
+                    if ((targetOffset.mainAxis <= minOffset &&
+                            animatedOffset.mainAxis <= minOffset) ||
+                        (targetOffset.mainAxis >= maxOffset &&
+                            animatedOffset.mainAxis >= maxOffset)
+                    ) {
+                        animateNode.cancelAnimation()
+                    }
+                    offset = animatedOffset
                 }
-                offset = animatedOffset
             }
             if (reverseLayout) {
                 offset = offset.copy { mainAxisOffset ->
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index 1d2cf7a..fb2fe0a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -16,6 +16,13 @@
 
 package androidx.compose.foundation.lazy
 
+import androidx.compose.animation.core.AnimationState
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.VectorConverter
+import androidx.compose.animation.core.animateTo
+import androidx.compose.animation.core.copy
+import androidx.compose.animation.core.spring
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.gestures.Orientation
@@ -42,7 +49,10 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
 import kotlin.math.abs
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 /**
  * Creates a [LazyListState] that is remembered across compositions.
@@ -82,6 +92,12 @@
     firstVisibleItemIndex: Int = 0,
     firstVisibleItemScrollOffset: Int = 0
 ) : ScrollableState {
+
+    internal var hasLookaheadPassOccurred: Boolean = false
+        private set
+    internal var postLookaheadLayoutInfo: LazyListLayoutInfo? = null
+        private set
+
     /**
      * The holder class for the current scroll position.
      */
@@ -385,18 +401,69 @@
     /**
      *  Updates the state with the new calculated scroll position and consumed scroll.
      */
-    internal fun applyMeasureResult(result: LazyListMeasureResult) {
-        scrollPosition.updateFromMeasureResult(result)
-        scrollToBeConsumed -= result.consumedScroll
-        layoutInfoState.value = result
+    internal fun applyMeasureResult(result: LazyListMeasureResult, isLookingAhead: Boolean) {
+        if (!isLookingAhead && hasLookaheadPassOccurred) {
+            // If there was already a lookahead pass, record this result as postLookahead result
+            postLookaheadLayoutInfo = result
+        } else {
+            if (isLookingAhead) {
+                hasLookaheadPassOccurred = true
+            }
+            scrollPosition.updateFromMeasureResult(result)
+            scrollToBeConsumed -= result.consumedScroll
+            layoutInfoState.value = result
 
-        canScrollForward = result.canScrollForward
-        canScrollBackward = (result.firstVisibleItem?.index ?: 0) != 0 ||
-            result.firstVisibleItemScrollOffset != 0
+            canScrollForward = result.canScrollForward
+            canScrollBackward = (result.firstVisibleItem?.index ?: 0) != 0 ||
+                result.firstVisibleItemScrollOffset != 0
 
-        numMeasurePasses++
+            if (isLookingAhead) updateScrollDeltaForPostLookahead(result.scrollBackAmount)
+            numMeasurePasses++
 
-        cancelPrefetchIfVisibleItemsChanged(result)
+            cancelPrefetchIfVisibleItemsChanged(result)
+        }
+    }
+
+    internal var coroutineScope: CoroutineScope? = null
+
+    internal val scrollDeltaBetweenPasses: Float
+        get() = _scrollDeltaBetweenPasses.value
+
+    private var _scrollDeltaBetweenPasses: AnimationState<Float, AnimationVector1D> =
+        AnimationState(Float.VectorConverter, 0f, 0f)
+
+    // Updates the scroll delta between lookahead & post-lookahead pass
+    private fun updateScrollDeltaForPostLookahead(delta: Float) {
+        if (delta <= with(density) { DeltaThresholdForScrollAnimation.toPx() }) {
+            // If the delta is within the threshold, scroll by the delta amount instead of animating
+            return
+        }
+
+        // Scroll delta is updated during lookahead, we don't need to trigger lookahead when
+        // the delta changes.
+        Snapshot.withoutReadObservation {
+            val currentDelta = _scrollDeltaBetweenPasses.value
+
+            if (_scrollDeltaBetweenPasses.isRunning) {
+                _scrollDeltaBetweenPasses = _scrollDeltaBetweenPasses.copy(currentDelta - delta)
+                coroutineScope?.launch {
+                    _scrollDeltaBetweenPasses.animateTo(
+                        0f,
+                        spring(stiffness = Spring.StiffnessMediumLow, visibilityThreshold = 0.5f),
+                        true
+                    )
+                }
+            } else {
+                _scrollDeltaBetweenPasses = AnimationState(Float.VectorConverter, -delta)
+                coroutineScope?.launch {
+                    _scrollDeltaBetweenPasses.animateTo(
+                        0f,
+                        spring(stiffness = Spring.StiffnessMediumLow, visibilityThreshold = 0.5f),
+                        true
+                    )
+                }
+            }
+        }
     }
 
     /**
@@ -425,6 +492,8 @@
     }
 }
 
+private val DeltaThresholdForScrollAnimation = 1.dp
+
 private object EmptyLazyListLayoutInfo : LazyListLayoutInfo {
     override val visibleItemsInfo = emptyList<LazyListItemInfo>()
     override val viewportStartOffset = 0
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateScrollScope.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
index 1f3426f..b29a04f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
@@ -77,7 +77,6 @@
         isVertical: Boolean
     ): Int {
         val visibleItems = layoutInfo.visibleItemsInfo
-        @Suppress("PrimitiveInLambda")
         val lineOf: (Int) -> Int = {
             if (isVertical) visibleItems[it].row else visibleItems[it].column
         }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
index 9198c1e..f54d52e 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt
@@ -391,7 +391,6 @@
      */
     fun item(
         key: Any? = null,
-        @Suppress("PrimitiveInLambda")
         span: (LazyGridItemSpanScope.() -> GridItemSpan)? = null,
         contentType: Any? = null,
         content: @Composable LazyGridItemScope.() -> Unit
@@ -417,13 +416,9 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         span: (LazyGridItemSpanScope.(index: Int) -> GridItemSpan)? = null,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any? = { null },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyGridItemScope.(index: Int) -> Unit
     )
 }
@@ -448,9 +443,7 @@
  */
 inline fun <T> LazyGridScope.items(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,
     noinline contentType: (item: T) -> Any? = { null },
     crossinline itemContent: @Composable LazyGridItemScope.(item: T) -> Unit
@@ -483,9 +476,7 @@
  */
 inline fun <T> LazyGridScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item: T) -> Unit
@@ -519,7 +510,6 @@
 inline fun <T> LazyGridScope.items(
     items: Array<T>,
     noinline key: ((item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,
     noinline contentType: (item: T) -> Any? = { null },
     crossinline itemContent: @Composable LazyGridItemScope.(item: T) -> Unit
@@ -552,9 +542,7 @@
  */
 inline fun <T> LazyGridScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item: T) -> Unit
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt
index 0c2ccb5..9faae07 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridIntervalContent.kt
@@ -41,7 +41,6 @@
         contentType: Any?,
         content: @Composable LazyGridItemScope.() -> Unit
     ) {
-        @Suppress("PrimitiveInLambda") // temp var
         intervals.addInterval(
             1,
             LazyGridInterval(
@@ -61,7 +60,6 @@
         contentType: (index: Int) -> Any?,
         itemContent: @Composable LazyGridItemScope.(index: Int) -> Unit
     ) {
-        @Suppress("PrimitiveInLambda") // temp var
         intervals.addInterval(
             count,
             LazyGridInterval(
@@ -75,19 +73,14 @@
     }
 
     private companion object {
-        @Suppress("PrimitiveInLambda")
         val DefaultSpan: LazyGridItemSpanScope.(Int) -> GridItemSpan = { GridItemSpan(1) }
     }
 }
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridInterval(
-    @Suppress("PrimitiveInLambda")
     override val key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     val span: LazyGridItemSpanScope.(Int) -> GridItemSpan,
-    @Suppress("PrimitiveInLambda")
     override val type: ((index: Int) -> Any?),
-    @Suppress("PrimitiveInLambda")
     val item: @Composable LazyGridItemScope.(Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
index 0f95dd1..f768d21 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
@@ -59,7 +59,6 @@
     placementAnimator: LazyGridItemPlacementAnimator,
     spanLayoutProvider: LazyGridSpanLayoutProvider,
     pinnedItems: List<Int>,
-    @Suppress("PrimitiveInLambda")
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): LazyGridMeasureResult {
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
index f649ee1..2ab8a16 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
@@ -223,7 +223,6 @@
     /**
      * Finds items on a line and their measurement constraints. Used for prefetching.
      */
-    @Suppress("PrimitiveInLambda")
     internal var prefetchInfoRetriever: (line: Int) -> List<Pair<Int, Constraints>> by
         mutableStateOf({ emptyList() })
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayout.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayout.kt
index ffc8ddc..3ad7f4f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayout.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayout.kt
@@ -81,8 +81,7 @@
                     with(
                         LazyLayoutMeasureScopeImpl(
                             itemContentFactory,
-                            this,
-                            prefetchState?.prefetcher?.timeTracker
+                            this
                         )
                     ) {
                         measurePolicy(constraints)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
index dc2161f..8a81ca6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
@@ -74,6 +74,12 @@
     }
 
     /**
+     * Tracks the offset of the item in the lookahead pass. When set, this is the animation target
+     * that placementDelta should be applied to.
+     */
+    var lookaheadOffset: IntOffset = NotInitialized
+
+    /**
      * Animate the placement by the given [delta] offset.
      */
     fun animatePlacementDelta(delta: IntOffset) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
index 807f551..90665f1 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
@@ -67,15 +67,11 @@
         /**
          * Returns item key based on a local index for the current interval.
          */
-        val key: ((index: Int) -> Any)?
-            @Suppress("PrimitiveInLambda")
-            get() = null
+        val key: ((index: Int) -> Any)? get() = null
 
         /**
          * Returns item type based on a local index for the current interval.
          */
-        val type: ((index: Int) -> Any?)
-            @Suppress("PrimitiveInLambda")
-            get() = { null }
+        val type: ((index: Int) -> Any?) get() = { null }
     }
 }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
index d0c2794..386b389 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
@@ -77,7 +77,6 @@
                     fromIndex = first,
                     toIndex = last,
                 ) {
-                    @Suppress("PrimitiveInLambda")
                     val keyFactory = it.value.key
                     val start = maxOf(first, it.startIndex)
                     val end = minOf(last, it.startIndex + it.size - 1)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope.kt
index 2a8bb45..c8b3c0d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutMeasureScope.kt
@@ -99,8 +99,7 @@
 @ExperimentalFoundationApi
 internal class LazyLayoutMeasureScopeImpl internal constructor(
     private val itemContentFactory: LazyLayoutItemContentFactory,
-    private val subcomposeMeasureScope: SubcomposeMeasureScope,
-    private val timeTracker: LazyLayoutPrefetchState.AverageTimeTracker?
+    private val subcomposeMeasureScope: SubcomposeMeasureScope
 ) : LazyLayoutMeasureScope, MeasureScope by subcomposeMeasureScope {
 
     private val itemProvider = itemContentFactory.itemProvider()
@@ -119,32 +118,12 @@
             val key = itemProvider.getKey(index)
             val contentType = itemProvider.getContentType(index)
             val itemContent = itemContentFactory.getContent(index, key, contentType)
-            val measurables = trackComposition {
-                subcomposeMeasureScope.subcompose(key, itemContent)
+            val measurables = subcomposeMeasureScope.subcompose(key, itemContent)
+            List(measurables.size) { i ->
+                measurables[i].measure(constraints)
+            }.also {
+                placeablesCache[index] = it
             }
-            trackMeasurement {
-                List(measurables.size) { i ->
-                    measurables[i].measure(constraints)
-                }.also {
-                    placeablesCache[index] = it
-                }
-            }
-        }
-    }
-
-    private inline fun <T> trackComposition(block: () -> T): T {
-        return if (timeTracker != null) {
-            timeTracker.trackComposition(block)
-        } else {
-            block()
-        }
-    }
-
-    private inline fun <T> trackMeasurement(block: () -> T): T {
-        return if (timeTracker != null) {
-            timeTracker.trackMeasurement(block)
-        } else {
-            block()
         }
     }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState.kt
index 1184ff7..6937c59 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPrefetchState.kt
@@ -48,55 +48,6 @@
 
     internal interface Prefetcher {
         fun schedulePrefetch(index: Int, constraints: Constraints): PrefetchHandle
-
-        val timeTracker: AverageTimeTracker
-    }
-
-    internal abstract class AverageTimeTracker {
-
-        /**
-         * Average time the prefetching operations takes. Keeping it allows us to not start the work
-         * if in this frame we are most likely not going to finish the work in time to not delay the
-         * next frame.
-         */
-        var compositionTimeNs: Long = 0
-            private set
-        var measurementTimeNs: Long = 0
-            private set
-
-        abstract fun currentTime(): Long
-
-        inline fun <T> trackComposition(block: () -> T): T {
-            val beforeTimeNs = currentTime()
-            val returnValue = block()
-            compositionTimeNs = calculateAverageTime(
-                currentTime() - beforeTimeNs,
-                compositionTimeNs
-            )
-            return returnValue
-        }
-
-        inline fun <T> trackMeasurement(block: () -> T): T {
-            val beforeTimeNs = currentTime()
-            val returnValue = block()
-            measurementTimeNs = calculateAverageTime(
-                currentTime() - beforeTimeNs,
-                measurementTimeNs
-            )
-            return returnValue
-        }
-
-        private fun calculateAverageTime(new: Long, current: Long): Long {
-            // Calculate a weighted moving average of time taken to compose an item. We use weighted
-            // moving average to bias toward more recent measurements, and to minimize storage /
-            // computation cost. (the idea is taken from RecycledViewPool)
-            return if (current == 0L) {
-                new
-            } else {
-                // dividing first to avoid a potential overflow
-                current / 4 * 3 + new / 4
-            }
-        }
     }
 }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
index bacdff6..b7e1ca9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutSemantics.kt
@@ -54,7 +54,6 @@
             userScrollEnabled
         ) {
             val isVertical = orientation == Orientation.Vertical
-            @Suppress("PrimitiveInLambda")
             val indexForKeyMapping: (Any) -> Int = { needle ->
                 val itemProvider = itemProviderLambda()
                 var result = -1
@@ -89,7 +88,6 @@
                 reverseScrolling = reverseScrolling
             )
 
-            @Suppress("PrimitiveInLambda")
             val scrollByAction: ((x: Float, y: Float) -> Boolean)? = if (userScrollEnabled) {
                 { x, y ->
                     val delta = if (isVertical) {
@@ -107,7 +105,6 @@
                 null
             }
 
-            @Suppress("PrimitiveInLambda")
             val scrollToIndexAction: ((Int) -> Boolean)? = if (userScrollEnabled) {
                 { index ->
                     val itemProvider = itemProviderLambda()
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt
index 799c3cc..cca7a11 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridDsl.kt
@@ -292,13 +292,9 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any? = { null },
-        @Suppress("PrimitiveInLambda")
         span: ((index: Int) -> StaggeredGridItemSpan)? = null,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyStaggeredGridItemScope.(index: Int) -> Unit
     )
 }
@@ -363,10 +359,8 @@
  */
 inline fun <T> LazyStaggeredGridScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
-    @Suppress("PrimitiveInLambda")
     noinline span: ((index: Int, item: T) -> StaggeredGridItemSpan)? = null,
     crossinline itemContent: @Composable LazyStaggeredGridItemScope.(index: Int, item: T) -> Unit
 ) {
@@ -443,10 +437,8 @@
  */
 inline fun <T> LazyStaggeredGridScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
-    @Suppress("PrimitiveInLambda")
     noinline span: ((index: Int, item: T) -> StaggeredGridItemSpan)? = null,
     crossinline itemContent: @Composable LazyStaggeredGridItemScope.(index: Int, item: T) -> Unit
 ) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt
index 1cf248f..dc7406d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridIntervalContent.kt
@@ -70,12 +70,8 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyStaggeredGridInterval(
-    @Suppress("PrimitiveInLambda")
     override val key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     override val type: ((index: Int) -> Any?),
-    @Suppress("PrimitiveInLambda")
     val span: ((index: Int) -> StaggeredGridItemSpan)?,
-    @Suppress("PrimitiveInLambda")
     val item: @Composable LazyStaggeredGridItemScope.(Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
index 51ef3b9..0ff47af 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
@@ -1003,11 +1003,7 @@
     private val measureScope: LazyLayoutMeasureScope,
     private val resolvedSlots: LazyStaggeredGridSlots
 ) {
-    private fun childConstraints(requestedSlot: Int, requestedSpan: Int): Constraints {
-        val slotCount = resolvedSlots.sizes.size
-        val slot = requestedSlot.coerceAtMost(slotCount - 1)
-        val span = requestedSpan.coerceAtMost(slotCount - slot)
-
+    private fun childConstraints(slot: Int, span: Int): Constraints {
         // resolved slots contain [offset, size] pair per each slot.
         val crossAxisSize = if (span == 1) {
             resolvedSlots.sizes[slot]
@@ -1028,11 +1024,16 @@
     fun getAndMeasure(index: Int, span: SpanRange): LazyStaggeredGridMeasuredItem {
         val key = itemProvider.getKey(index)
         val contentType = itemProvider.getContentType(index)
-        val placeables = measureScope.measure(index, childConstraints(span.start, span.size))
+
+        val slotCount = resolvedSlots.sizes.size
+        val spanStart = span.start.coerceAtMost(slotCount - 1)
+        val spanSize = span.size.coerceAtMost(slotCount - spanStart)
+
+        val placeables = measureScope.measure(index, childConstraints(spanStart, spanSize))
         return createItem(
             index,
-            span.start,
-            span.size,
+            spanStart,
+            spanSize,
             key,
             contentType,
             placeables
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridScrollPosition.kt
index 6d5e67e..7f8809d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridScrollPosition.kt
@@ -31,7 +31,6 @@
 internal class LazyStaggeredGridScrollPosition(
     initialIndices: IntArray,
     initialOffsets: IntArray,
-    @Suppress("PrimitiveInLambda")
     private val fillIndices: (targetIndex: Int, laneCount: Int) -> IntArray
 ) : SnapshotMutationPolicy<IntArray> {
     var indices by mutableStateOf(initialIndices, this)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSpan.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSpan.kt
index f240d66..11a754a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSpan.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridSpan.kt
@@ -49,7 +49,6 @@
     fun isFullSpan(itemIndex: Int): Boolean {
         if (itemIndex !in 0 until intervals.size) return false
         intervals[itemIndex].run {
-            @Suppress("PrimitiveInLambda")
             val span = value.span
             val localIndex = itemIndex - startIndex
 
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 0725f5c..ffb2dea 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
@@ -84,14 +84,12 @@
     /** A [NestedScrollConnection] that dictates how this [Pager] behaves with nested lists.  **/
     pageNestedScrollConnection: NestedScrollConnection,
     /** a stable and unique key representing the Page **/
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)?,
     /** The alignment to align pages horizontally. Required when isVertical is true */
     horizontalAlignment: Alignment.Horizontal,
     /** The alignment to align pages vertically. Required when isVertical is false */
     verticalAlignment: Alignment.Vertical,
     /** The content of the list */
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     require(beyondBoundsPageCount >= 0) {
@@ -221,9 +219,7 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 private class PagerLayoutIntervalContent(
-    @Suppress("PrimitiveInLambda")
     val pageContent: @Composable PagerScope.(page: Int) -> Unit,
-    @Suppress("PrimitiveInLambda")
     val key: ((index: Int) -> Any)?,
     val pageCount: Int
 ) : LazyLayoutIntervalContent<PagerIntervalContent>() {
@@ -235,9 +231,7 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class PagerIntervalContent(
-    @Suppress("PrimitiveInLambda")
     override val key: ((page: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     val item: @Composable PagerScope.(page: Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
 
@@ -245,11 +239,8 @@
 @Composable
 private fun rememberPagerItemProviderLambda(
     state: PagerState,
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     pageCount: () -> Int
 ): () -> PagerLazyLayoutItemProvider {
     val latestContent = rememberUpdatedState(pageContent)
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 fd32aff..d64b834 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
@@ -116,12 +116,10 @@
     flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)? = null,
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Horizontal)
     },
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
@@ -226,12 +224,10 @@
     flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)? = null,
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Horizontal)
     },
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
@@ -306,12 +302,10 @@
     flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)? = null,
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Vertical)
     },
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
@@ -415,12 +409,10 @@
     flingBehavior: SnapFlingBehavior = PagerDefaults.flingBehavior(state = state),
     userScrollEnabled: Boolean = true,
     reverseLayout: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)? = null,
     pageNestedScrollConnection: NestedScrollConnection = remember(state) {
         PagerDefaults.pageNestedScrollConnection(state, Orientation.Vertical)
     },
-    @Suppress("PrimitiveInLambda")
     pageContent: @Composable PagerScope.(page: Int) -> Unit
 ) {
     Pager(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
index 787d64b..264680a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
@@ -57,7 +57,6 @@
     pageAvailableSize: Int,
     beyondBoundsPageCount: Int,
     pinnedPages: List<Int>,
-    @Suppress("PrimitiveInLambda")
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): PagerMeasureResult {
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
@@ -420,7 +419,6 @@
     pagesCount: Int,
     beyondBoundsPageCount: Int,
     pinnedPages: List<Int>,
-    @Suppress("PrimitiveInLambda")
     getAndMeasure: (Int) -> MeasuredPage
 ): List<MeasuredPage> {
     var list: MutableList<MeasuredPage>? = null
@@ -446,7 +444,6 @@
     currentFirstPage: Int,
     beyondBoundsPageCount: Int,
     pinnedPages: List<Int>,
-    @Suppress("PrimitiveInLambda")
     getAndMeasure: (Int) -> MeasuredPage
 ): List<MeasuredPage> {
     var list: MutableList<MeasuredPage>? = null
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
index 74f468d..d803fb0b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasurePolicy.kt
@@ -50,7 +50,6 @@
     pageSize: PageSize,
     horizontalAlignment: Alignment.Horizontal?,
     verticalAlignment: Alignment.Vertical?,
-    @Suppress("PrimitiveInLambda")
     pageCount: () -> Int,
 ) = remember<LazyLayoutMeasureScope.(Constraints) -> MeasureResult>(
     contentPadding,
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 3435f66..37aafef0 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
@@ -74,7 +74,6 @@
 fun rememberPagerState(
     initialPage: Int = 0,
     initialPageOffsetFraction: Float = 0f,
-    @Suppress("PrimitiveInLambda")
     pageCount: () -> Int
 ): PagerState {
     return rememberSaveable(saver = PagerStateImpl.Saver) {
@@ -128,11 +127,9 @@
 internal class PagerStateImpl(
     initialPage: Int,
     initialPageOffsetFraction: Float,
-    @Suppress("PrimitiveInLambda")
     updatedPageCount: () -> Int
 ) : PagerState(initialPage, initialPageOffsetFraction) {
 
-    @Suppress("PrimitiveInLambda")
     var pageCountState = mutableStateOf(updatedPageCount)
     override val pageCount: Int get() = pageCountState.value.invoke()
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
index 3832970..05b8dad 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/ClickableText.kt
@@ -75,7 +75,6 @@
     overflow: TextOverflow = TextOverflow.Clip,
     maxLines: Int = Int.MAX_VALUE,
     onTextLayout: (TextLayoutResult) -> Unit = {},
-    @Suppress("PrimitiveInLambda")
     onClick: (Int) -> Unit
 ) {
     val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
@@ -143,7 +142,6 @@
 @Composable
 fun ClickableText(
     text: AnnotatedString,
-    @Suppress("PrimitiveInLambda")
     onHover: ((Int?) -> Unit),
     modifier: Modifier = Modifier,
     style: TextStyle = TextStyle.Default,
@@ -151,7 +149,6 @@
     overflow: TextOverflow = TextOverflow.Clip,
     maxLines: Int = Int.MAX_VALUE,
     onTextLayout: (TextLayoutResult) -> Unit = {},
-    @Suppress("PrimitiveInLambda")
     onClick: (Int) -> Unit
 ) {
     val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
index e5eb2d3..06f02e7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
@@ -208,7 +208,7 @@
 
     // CompositionLocals
     // If the text field is disabled or read-only, we should not deal with the input service
-    val textInputService = if (!enabled || readOnly) null else LocalTextInputService.current
+    val textInputService = LocalTextInputService.current
     val density = LocalDensity.current
     val fontFamilyResolver = LocalFontFamilyResolver.current
     val selectionBackgroundColor = LocalTextSelectionColors.current.backgroundColor
@@ -384,6 +384,7 @@
 
     val onPositionedModifier = Modifier.onGloballyPositioned {
         state.layoutCoordinates = it
+        state.layoutResult?.innerTextFieldCoordinates = it
         if (enabled) {
             if (state.handleState == HandleState.Selection) {
                 if (state.showFloatingToolbar) {
@@ -401,8 +402,14 @@
                     manager.isSelectionHandleInVisibleBound(isStartHandle = true)
             }
             notifyFocusedRect(state, value, offsetMapping)
+            state.layoutResult?.let { layoutResult ->
+                state.inputSession?.let { inputSession ->
+                    if (state.hasFocus) {
+                        TextFieldDelegate.updateTextLayoutResult(inputSession, value, layoutResult)
+                    }
+                }
+            }
         }
-        state.layoutResult?.innerTextFieldCoordinates = it
     }
 
     val isPassword = visualTransformation is PasswordVisualTransformation
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
index c93715b..8f8a6d6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldDelegate.kt
@@ -16,12 +16,14 @@
 
 package androidx.compose.foundation.text
 
+import androidx.compose.foundation.text.selection.visibleBounds
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Canvas
 import androidx.compose.ui.graphics.Paint
 import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.positionInWindow
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.Paragraph
 import androidx.compose.ui.text.SpanStyle
@@ -178,6 +180,36 @@
         }
 
         /**
+         * Notify the input service of layout and position changes.
+         *
+         * @param textInputSession the current input session
+         * @param textFieldValue the editor state
+         * @param textLayoutResult the layout result
+         */
+        @JvmStatic
+        internal fun updateTextLayoutResult(
+            textInputSession: TextInputSession,
+            textFieldValue: TextFieldValue,
+            textLayoutResult: TextLayoutResultProxy
+        ) {
+            textLayoutResult.innerTextFieldCoordinates?.let { innerTextFieldCoordinates ->
+                if (!innerTextFieldCoordinates.isAttached) return
+                textLayoutResult.decorationBoxCoordinates?.let { decorationBoxCoordinates ->
+                    textInputSession.updateTextLayoutResult(
+                        textFieldValue,
+                        textLayoutResult.value,
+                        innerTextFieldCoordinates.positionInWindow(),
+                        innerTextFieldCoordinates.visibleBounds(),
+                        innerTextFieldCoordinates.localBoundingBoxOf(
+                            decorationBoxCoordinates,
+                            clipBounds = false
+                        )
+                    )
+                }
+            }
+        }
+
+        /**
          * Called when edit operations are passed from TextInputService
          *
          * @param ops A list of edit operations.
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustment.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustment.kt
index 833fa7b..b108673 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustment.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustment.kt
@@ -150,7 +150,6 @@
         private fun adjustByBoundary(
             textLayoutResult: TextLayoutResult,
             newRawSelection: TextRange,
-            @Suppress("PrimitiveInLambda")
             boundaryFun: (Int) -> TextRange
         ): TextRange {
             if (textLayoutResult.layoutInput.text.isEmpty()) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
index c4671e8..5622db3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
@@ -59,20 +59,17 @@
     /**
      * The callback to be invoked when the position change was triggered.
      */
-    @Suppress("PrimitiveInLambda")
     internal var onPositionChangeCallback: ((Long) -> Unit)? = null
 
     /**
      * The callback to be invoked when the selection is initiated.
      */
-    @Suppress("PrimitiveInLambda")
     internal var onSelectionUpdateStartCallback:
         ((Boolean, LayoutCoordinates, Offset, SelectionAdjustment) -> Unit)? = null
 
     /**
      * The callback to be invoked when the selection is initiated with selectAll [Selection].
      */
-    @Suppress("PrimitiveInLambda")
     internal var onSelectionUpdateSelectAll: (
         (Boolean, Long) -> Unit
     )? = null
@@ -81,7 +78,6 @@
      * The callback to be invoked when the selection is updated.
      * If the first offset is null it means that the start of selection is unknown for the caller.
      */
-    @Suppress("PrimitiveInLambda")
     internal var onSelectionUpdateCallback:
         ((Boolean, LayoutCoordinates, Offset, Offset, Boolean, SelectionAdjustment) -> Boolean)? =
         null
@@ -94,13 +90,11 @@
     /**
      * The callback to be invoked when one of the selectable has changed.
      */
-    @Suppress("PrimitiveInLambda")
     internal var onSelectableChangeCallback: ((Long) -> Unit)? = null
 
     /**
      * The callback to be invoked after a selectable is unsubscribed from this [SelectionRegistrar].
      */
-    @Suppress("PrimitiveInLambda")
     internal var afterSelectableUnsubscribe: ((Long) -> Unit)? = null
 
     override var subselections: Map<Long, Selection> by mutableStateOf(emptyMap())
diff --git a/compose/integration-tests/docs-snippets/lint-baseline.xml b/compose/integration-tests/docs-snippets/lint-baseline.xml
new file mode 100644
index 0000000..9cab9d9
--- /dev/null
+++ b/compose/integration-tests/docs-snippets/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Counter has parameter &apos;updateCount&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    fun Counter(count: Int, updateCount: (Int) -> Unit) {"
+        errorLine2="                                         ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
index 9ed0796..f75a353 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
@@ -75,11 +75,7 @@
 
 private object PreviewSnippet5 {
     @Composable
-    fun Counter(
-        count: Int,
-        @Suppress("PrimitiveInLambda")
-        updateCount: (Int) -> Unit
-    ) {
+    fun Counter(count: Int, updateCount: (Int) -> Unit) {
         Button(
             onClick = { updateCount(count + 1) },
             colors = buttonColors(
diff --git a/compose/material/material-icons-core/api/public_plus_experimental_1.5.0-beta01.txt b/compose/material/material-icons-core/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..b95d770
--- /dev/null
+++ b/compose/material/material-icons-core/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,1036 @@
+// Signature format: 4.0
+package androidx.compose.material.icons {
+
+  public final class Icons {
+    method public androidx.compose.material.icons.Icons.Filled getDefault();
+    property public final androidx.compose.material.icons.Icons.Filled Default;
+    field public static final androidx.compose.material.icons.Icons INSTANCE;
+  }
+
+  public static final class Icons.Filled {
+    field public static final androidx.compose.material.icons.Icons.Filled INSTANCE;
+  }
+
+  public static final class Icons.Outlined {
+    field public static final androidx.compose.material.icons.Icons.Outlined INSTANCE;
+  }
+
+  public static final class Icons.Rounded {
+    field public static final androidx.compose.material.icons.Icons.Rounded INSTANCE;
+  }
+
+  public static final class Icons.Sharp {
+    field public static final androidx.compose.material.icons.Icons.Sharp INSTANCE;
+  }
+
+  public static final class Icons.TwoTone {
+    field public static final androidx.compose.material.icons.Icons.TwoTone INSTANCE;
+  }
+
+  public final class IconsKt {
+    method public static inline androidx.compose.ui.graphics.vector.ImageVector materialIcon(String name, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.vector.ImageVector.Builder,androidx.compose.ui.graphics.vector.ImageVector.Builder> block);
+    method public static inline androidx.compose.ui.graphics.vector.ImageVector.Builder materialPath(androidx.compose.ui.graphics.vector.ImageVector.Builder, optional float fillAlpha, optional float strokeAlpha, optional int pathFillType, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
+  }
+
+}
+
+package androidx.compose.material.icons.filled {
+
+  public final class AccountBoxKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountBox(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class AccountCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountCircle(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class AddCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAddCircle(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class AddKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAdd(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ArrowBackKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowBack(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ArrowDropDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowDropDown(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ArrowForwardKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowForward(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class BuildKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getBuild(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class CallKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCall(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class CheckCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheckCircle(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class CheckKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheck(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ClearKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClear(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class CloseKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClose(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class CreateKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCreate(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class DateRangeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDateRange(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class DeleteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDelete(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class DoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDone(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class EditKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEdit(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class EmailKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEmail(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ExitToAppKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getExitToApp(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class FaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFace(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class FavoriteBorderKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavoriteBorder(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class FavoriteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavorite(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class HomeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getHome(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class InfoKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getInfo(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class KeyboardArrowDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowDown(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class KeyboardArrowLeftKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowLeft(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class KeyboardArrowRightKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowRight(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class KeyboardArrowUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowUp(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ListKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getList(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class LocationOnKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLocationOn(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class LockKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLock(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class MailOutlineKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMailOutline(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class MenuKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMenu(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class MoreVertKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMoreVert(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class NotificationsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getNotifications(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class PersonKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPerson(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class PhoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPhone(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class PlaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlace(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class PlayArrowKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlayArrow(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class RefreshKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getRefresh(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class SearchKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSearch(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class SendKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSend(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class SettingsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSettings(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ShareKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShare(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ShoppingCartKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShoppingCart(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class StarKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getStar(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class ThumbUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getThumbUp(androidx.compose.material.icons.Icons.Filled);
+  }
+
+  public final class WarningKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getWarning(androidx.compose.material.icons.Icons.Filled);
+  }
+
+}
+
+package androidx.compose.material.icons.outlined {
+
+  public final class AccountBoxKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountBox(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class AccountCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountCircle(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class AddCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAddCircle(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class AddKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAdd(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ArrowBackKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowBack(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ArrowDropDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowDropDown(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ArrowForwardKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowForward(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class BuildKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getBuild(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class CallKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCall(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class CheckCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheckCircle(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class CheckKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheck(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ClearKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClear(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class CloseKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClose(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class CreateKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCreate(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class DateRangeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDateRange(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class DeleteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDelete(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class DoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDone(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class EditKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEdit(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class EmailKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEmail(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ExitToAppKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getExitToApp(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class FaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFace(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class FavoriteBorderKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavoriteBorder(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class FavoriteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavorite(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class HomeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getHome(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class InfoKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getInfo(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class KeyboardArrowDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowDown(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class KeyboardArrowLeftKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowLeft(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class KeyboardArrowRightKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowRight(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class KeyboardArrowUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowUp(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ListKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getList(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class LocationOnKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLocationOn(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class LockKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLock(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class MailOutlineKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMailOutline(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class MenuKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMenu(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class MoreVertKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMoreVert(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class NotificationsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getNotifications(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class PersonKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPerson(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class PhoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPhone(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class PlaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlace(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class PlayArrowKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlayArrow(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class RefreshKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getRefresh(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class SearchKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSearch(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class SendKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSend(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class SettingsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSettings(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ShareKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShare(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ShoppingCartKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShoppingCart(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class StarKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getStar(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class ThumbUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getThumbUp(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+  public final class WarningKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getWarning(androidx.compose.material.icons.Icons.Outlined);
+  }
+
+}
+
+package androidx.compose.material.icons.rounded {
+
+  public final class AccountBoxKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountBox(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class AccountCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountCircle(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class AddCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAddCircle(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class AddKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAdd(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ArrowBackKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowBack(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ArrowDropDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowDropDown(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ArrowForwardKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowForward(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class BuildKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getBuild(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class CallKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCall(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class CheckCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheckCircle(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class CheckKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheck(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ClearKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClear(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class CloseKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClose(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class CreateKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCreate(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class DateRangeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDateRange(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class DeleteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDelete(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class DoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDone(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class EditKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEdit(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class EmailKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEmail(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ExitToAppKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getExitToApp(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class FaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFace(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class FavoriteBorderKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavoriteBorder(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class FavoriteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavorite(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class HomeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getHome(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class InfoKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getInfo(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class KeyboardArrowDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowDown(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class KeyboardArrowLeftKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowLeft(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class KeyboardArrowRightKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowRight(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class KeyboardArrowUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowUp(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ListKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getList(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class LocationOnKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLocationOn(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class LockKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLock(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class MailOutlineKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMailOutline(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class MenuKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMenu(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class MoreVertKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMoreVert(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class NotificationsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getNotifications(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class PersonKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPerson(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class PhoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPhone(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class PlaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlace(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class PlayArrowKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlayArrow(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class RefreshKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getRefresh(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class SearchKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSearch(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class SendKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSend(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class SettingsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSettings(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ShareKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShare(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ShoppingCartKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShoppingCart(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class StarKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getStar(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class ThumbUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getThumbUp(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+  public final class WarningKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getWarning(androidx.compose.material.icons.Icons.Rounded);
+  }
+
+}
+
+package androidx.compose.material.icons.sharp {
+
+  public final class AccountBoxKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountBox(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class AccountCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountCircle(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class AddCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAddCircle(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class AddKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAdd(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ArrowBackKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowBack(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ArrowDropDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowDropDown(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ArrowForwardKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowForward(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class BuildKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getBuild(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class CallKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCall(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class CheckCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheckCircle(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class CheckKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheck(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ClearKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClear(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class CloseKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClose(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class CreateKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCreate(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class DateRangeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDateRange(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class DeleteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDelete(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class DoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDone(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class EditKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEdit(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class EmailKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEmail(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ExitToAppKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getExitToApp(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class FaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFace(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class FavoriteBorderKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavoriteBorder(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class FavoriteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavorite(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class HomeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getHome(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class InfoKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getInfo(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class KeyboardArrowDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowDown(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class KeyboardArrowLeftKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowLeft(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class KeyboardArrowRightKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowRight(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class KeyboardArrowUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowUp(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ListKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getList(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class LocationOnKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLocationOn(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class LockKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLock(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class MailOutlineKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMailOutline(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class MenuKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMenu(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class MoreVertKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMoreVert(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class NotificationsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getNotifications(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class PersonKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPerson(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class PhoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPhone(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class PlaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlace(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class PlayArrowKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlayArrow(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class RefreshKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getRefresh(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class SearchKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSearch(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class SendKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSend(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class SettingsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSettings(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ShareKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShare(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ShoppingCartKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShoppingCart(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class StarKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getStar(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class ThumbUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getThumbUp(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+  public final class WarningKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getWarning(androidx.compose.material.icons.Icons.Sharp);
+  }
+
+}
+
+package androidx.compose.material.icons.twotone {
+
+  public final class AccountBoxKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountBox(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class AccountCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAccountCircle(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class AddCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAddCircle(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class AddKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getAdd(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ArrowBackKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowBack(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ArrowDropDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowDropDown(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ArrowForwardKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getArrowForward(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class BuildKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getBuild(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class CallKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCall(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class CheckCircleKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheckCircle(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class CheckKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCheck(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ClearKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClear(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class CloseKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getClose(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class CreateKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getCreate(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class DateRangeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDateRange(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class DeleteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDelete(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class DoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getDone(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class EditKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEdit(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class EmailKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getEmail(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ExitToAppKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getExitToApp(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class FaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFace(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class FavoriteBorderKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavoriteBorder(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class FavoriteKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getFavorite(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class HomeKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getHome(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class InfoKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getInfo(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class KeyboardArrowDownKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowDown(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class KeyboardArrowLeftKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowLeft(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class KeyboardArrowRightKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowRight(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class KeyboardArrowUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getKeyboardArrowUp(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ListKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getList(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class LocationOnKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLocationOn(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class LockKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getLock(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class MailOutlineKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMailOutline(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class MenuKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMenu(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class MoreVertKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getMoreVert(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class NotificationsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getNotifications(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class PersonKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPerson(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class PhoneKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPhone(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class PlaceKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlace(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class PlayArrowKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getPlayArrow(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class RefreshKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getRefresh(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class SearchKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSearch(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class SendKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSend(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class SettingsKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getSettings(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ShareKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShare(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ShoppingCartKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getShoppingCart(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class StarKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getStar(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class ThumbUpKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getThumbUp(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+  public final class WarningKt {
+    method public static androidx.compose.ui.graphics.vector.ImageVector getWarning(androidx.compose.material.icons.Icons.TwoTone);
+  }
+
+}
+
diff --git a/compose/material/material-icons-core/build.gradle b/compose/material/material-icons-core/build.gradle
index 615b415..dc8b062 100644
--- a/compose/material/material-icons-core/build.gradle
+++ b/compose/material/material-icons-core/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import androidx.compose.material.icons.generator.tasks.IconGenerationTask
 
 
@@ -32,6 +33,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material/material-icons-core/lint-baseline.xml b/compose/material/material-icons-core/lint-baseline.xml
deleted file mode 100644
index c800509..0000000
--- a/compose/material/material-icons-core/lint-baseline.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="LintError"
-        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: Java heap space&#xA;Stack: `OutOfMemoryError:OpenAddressLinearProbingHashTable.rehash(OpenAddressLinearProbingHashTable.kt:93)←OpenAddressLinearProbingHashTable.put(OpenAddressLinearProbingHashTable.kt:83)←SlicedMapImpl.put(SlicedMapImpl.java:79)←BindingTraceContext.record(BindingTraceContext.java:137)←CliBindingTraceForLint.record(Fe10UastEnvironment.kt:388)←QualifiedExpressionResolver.storeResult(QualifiedExpressionResolver.kt:750)←QualifiedExpressionResolver.access$storeResult(QualifiedExpressionResolver.kt:53)←QualifiedExpressionResolver$processSingleImport$1.invoke(QualifiedExpressionResolver.kt:346)←QualifiedExpressionResolver$processSingleImport$1.invoke(QualifiedExpressionResolver.kt:344)←CallOnceFunction.invoke(CallOnceFunction.kt:13)←LazyExplicitImportScope.storeReferencesToDescriptors$frontend(LazyExplicitImportScope.kt:120)←LazyImportResolverForKtImportDirective$forceResolveImportDirective$1.invoke(LazyImportScope.kt:172)←LazyImportResolverForKtImportDirective$forceResolveImportDirective$1.invoke(LazyImportScope.kt:169)←LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:578)←LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:651)←LazyImportResolverForKtImportDirective.forceResolveImport(LazyImportScope.kt:231)←LazyImportResolverForKtImportDirective$forceResolveNonDefaultImportsTask$1.invoke(LazyImportScope.kt:184)←LazyImportResolverForKtImportDirective$forceResolveNonDefaultImportsTask$1.invoke(LazyImportScope.kt:181)←LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:408)←LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:527)←LazyImportResolverForKtImportDirective.forceResolveNonDefaultImports(LazyImportScope.kt:214)←FileScopeFactory$FilesScopesBuilder$importResolver$1.forceResolveNonDefaultImports(FileScopeFactory.kt:170)←LazyTopDownAnalyzer.resolveImportsInFile(LazyTopDownAnalyzer.kt:252)←LazyTopDownAnalyzer.resolveImportsInAllFiles(LazyTopDownAnalyzer.kt:247)←LazyTopDownAnalyzer.analyzeDeclarations(LazyTopDownAnalyzer.kt:229)←LazyTopDownAnalyzer.analyzeDeclarations$default(LazyTopDownAnalyzer.kt:58)←TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:130)←TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:99)←Fe10UastEnvironment.analyzeFiles(Fe10UastEnvironment.kt:170)←LintCliClient$LintCliUastParser.prepare(LintCliClient.kt:1850)←UastParser.prepare$default(UastParser.kt:59)←LintDriver.prepareUast(LintDriver.kt:2107)`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
-        <location
-            file="material-icons-core"/>
-    </issue>
-
-</issues>
diff --git a/compose/material/material-icons-extended/build.gradle b/compose/material/material-icons-extended/build.gradle
index b7e2fea..89ea04b 100644
--- a/compose/material/material-icons-extended/build.gradle
+++ b/compose/material/material-icons-extended/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import androidx.build.RunApiTasks
 import androidx.compose.material.icons.generator.tasks.IconGenerationTask
 
@@ -38,6 +39,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material/material-ripple/api/public_plus_experimental_1.5.0-beta01.txt b/compose/material/material-ripple/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..6dba36f
--- /dev/null
+++ b/compose/material/material-ripple/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,37 @@
+// Signature format: 4.0
+package androidx.compose.material.ripple {
+
+  @androidx.compose.runtime.Immutable public final class RippleAlpha {
+    ctor public RippleAlpha(float draggedAlpha, float focusedAlpha, float hoveredAlpha, float pressedAlpha);
+    method public float getDraggedAlpha();
+    method public float getFocusedAlpha();
+    method public float getHoveredAlpha();
+    method public float getPressedAlpha();
+    property public final float draggedAlpha;
+    property public final float focusedAlpha;
+    property public final float hoveredAlpha;
+    property public final float pressedAlpha;
+  }
+
+  public final class RippleKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.foundation.Indication rememberRipple(optional boolean bounded, optional float radius, optional long color);
+  }
+
+  public interface RippleTheme {
+    method @androidx.compose.runtime.Composable public long defaultColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ripple.RippleAlpha rippleAlpha();
+    field public static final androidx.compose.material.ripple.RippleTheme.Companion Companion;
+  }
+
+  public static final class RippleTheme.Companion {
+    method public androidx.compose.material.ripple.RippleAlpha defaultRippleAlpha(long contentColor, boolean lightTheme);
+    method public long defaultRippleColor(long contentColor, boolean lightTheme);
+  }
+
+  public final class RippleThemeKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> getLocalRippleTheme();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ripple.RippleTheme> LocalRippleTheme;
+  }
+
+}
+
diff --git a/compose/material/material-ripple/build.gradle b/compose/material/material-ripple/build.gradle
index 999f59f..9e6fbe8 100644
--- a/compose/material/material-ripple/build.gradle
+++ b/compose/material/material-ripple/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material/material/api/1.5.0-beta01.txt b/compose/material/material/api/1.5.0-beta01.txt
index 3ce6f1ce..8935416 100644
--- a/compose/material/material/api/1.5.0-beta01.txt
+++ b/compose/material/material/api/1.5.0-beta01.txt
@@ -42,73 +42,11 @@
     field public static final androidx.compose.material.BackdropScaffoldDefaults INSTANCE;
   }
 
-  public final class BackdropScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BackdropScaffold(kotlin.jvm.functions.Function0<kotlin.Unit> appBar, kotlin.jvm.functions.Function0<kotlin.Unit> backLayerContent, kotlin.jvm.functions.Function0<kotlin.Unit> frontLayerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BackdropScaffoldState scaffoldState, optional boolean gesturesEnabled, optional float peekHeight, optional float headerHeight, optional boolean persistentAppBar, optional boolean stickyFrontLayer, optional long backLayerBackgroundColor, optional long backLayerContentColor, optional androidx.compose.ui.graphics.Shape frontLayerShape, optional float frontLayerElevation, optional long frontLayerBackgroundColor, optional long frontLayerContentColor, optional long frontLayerScrimColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BackdropScaffoldState rememberBackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
-    ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
-    method public boolean isConcealed();
-    method public boolean isRevealed();
-    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final boolean isConcealed;
-    property public final boolean isRevealed;
-    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
-    field public static final androidx.compose.material.BackdropScaffoldState.Companion Companion;
-  }
-
-  public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BackdropValue {
-    method public static androidx.compose.material.BackdropValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BackdropValue[] values();
-    enum_constant public static final androidx.compose.material.BackdropValue Concealed;
-    enum_constant public static final androidx.compose.material.BackdropValue Revealed;
-  }
-
   public final class BadgeKt {
     method @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
     method @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public final class BottomDrawerState {
-    ctor @Deprecated public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.BottomDrawerValue getCurrentValue();
-    method public float getOffset();
-    method public androidx.compose.material.BottomDrawerValue getTargetValue();
-    method public boolean isClosed();
-    method public boolean isExpanded();
-    method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.BottomDrawerValue currentValue;
-    property public final boolean isClosed;
-    property public final boolean isExpanded;
-    property public final boolean isOpen;
-    property public final float offset;
-    property public final androidx.compose.material.BottomDrawerValue targetValue;
-    field public static final androidx.compose.material.BottomDrawerState.Companion Companion;
-  }
-
-  public static final class BottomDrawerState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(androidx.compose.ui.unit.Density density, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BottomDrawerValue {
-    method public static androidx.compose.material.BottomDrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BottomDrawerValue[] values();
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Closed;
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Expanded;
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Open;
-  }
-
   public final class BottomNavigationDefaults {
     method public float getElevation();
     property public final float Elevation;
@@ -128,54 +66,6 @@
     field public static final androidx.compose.material.BottomSheetScaffoldDefaults INSTANCE;
   }
 
-  public final class BottomSheetScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomSheetState BottomSheetScaffoldState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BottomSheetState BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
-    ctor public BottomSheetScaffoldState(androidx.compose.material.DrawerState drawerState, androidx.compose.material.BottomSheetState bottomSheetState, androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public androidx.compose.material.BottomSheetState getBottomSheetState();
-    method public androidx.compose.material.DrawerState getDrawerState();
-    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
-    property public final androidx.compose.material.BottomSheetState bottomSheetState;
-    property public final androidx.compose.material.DrawerState drawerState;
-    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState {
-    ctor @Deprecated public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
-    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.BottomSheetValue getCurrentValue();
-    method @Deprecated public float getOffset();
-    method public float getProgress();
-    method public boolean isCollapsed();
-    method public boolean isExpanded();
-    method public float requireOffset();
-    property public final androidx.compose.material.BottomSheetValue currentValue;
-    property public final boolean isCollapsed;
-    property public final boolean isExpanded;
-    property @Deprecated public final float offset;
-    property public final float progress;
-    field public static final androidx.compose.material.BottomSheetState.Companion Companion;
-  }
-
-  public static final class BottomSheetState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BottomSheetValue {
-    method public static androidx.compose.material.BottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BottomSheetValue[] values();
-    enum_constant public static final androidx.compose.material.BottomSheetValue Collapsed;
-    enum_constant public static final androidx.compose.material.BottomSheetValue Expanded;
-  }
-
   @androidx.compose.runtime.Stable public interface ButtonColors {
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
@@ -219,8 +109,6 @@
 
   public final class CardKt {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable 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 long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Stable public interface CheckboxColors {
@@ -239,38 +127,6 @@
     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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ChipColors {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconContentColor(boolean enabled);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ChipDefaults {
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors chipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors filterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
-    method public float getLeadingIconSize();
-    method public float getMinHeight();
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedBorder();
-    method public float getOutlinedBorderSize();
-    method public float getSelectedIconSize();
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors outlinedChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors outlinedFilterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
-    property public final float LeadingIconSize;
-    property public final float MinHeight;
-    property public final float OutlinedBorderSize;
-    property public final float SelectedIconSize;
-    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedBorder;
-    field public static final float ContentOpacity = 0.87f;
-    field public static final androidx.compose.material.ChipDefaults INSTANCE;
-    field public static final float LeadingIconOpacity = 0.54f;
-    field public static final float OutlinedBorderOpacity = 0.12f;
-  }
-
-  public final class ChipKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Chip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.SelectableChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? selectedIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-  }
-
   @androidx.compose.runtime.Stable public final class Colors {
     ctor public Colors(long primary, long primaryVariant, long secondary, long secondaryVariant, long background, long surface, long error, long onPrimary, long onSecondary, long onBackground, long onSurface, long onError, boolean isLight);
     method public androidx.compose.material.Colors copy(optional long primary, optional long primaryVariant, optional long secondary, optional long secondaryVariant, optional long background, optional long surface, optional long error, optional long onPrimary, optional long onSecondary, optional long onBackground, optional long onSurface, optional long onError, optional boolean isLight);
@@ -337,20 +193,6 @@
     enum_constant public static final androidx.compose.material.DismissDirection StartToEnd;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
-    ctor public DismissState(androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.DismissDirection? getDismissDirection();
-    method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.DismissDirection? dismissDirection;
-    field public static final androidx.compose.material.DismissState.Companion Companion;
-  }
-
-  public static final class DismissState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.DismissState,androidx.compose.material.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-  }
-
   public enum DismissValue {
     method public static androidx.compose.material.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.compose.material.DismissValue[] values();
@@ -373,20 +215,14 @@
   }
 
   public final class DrawerKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomDrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomDrawerState BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
     method @androidx.compose.runtime.Composable public static void ModalDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.DrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomDrawerState rememberBottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.DrawerState rememberDrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
   }
 
   @androidx.compose.runtime.Stable public final class DrawerState {
     ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public suspend Object? animateTo(androidx.compose.material.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public androidx.compose.material.DrawerValue getCurrentValue();
-    method @androidx.compose.material.ExperimentalMaterialApi public float getOffset();
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.material.DrawerValue getTargetValue();
     method public boolean isAnimationRunning();
     method public boolean isClosed();
     method public boolean isOpen();
@@ -396,8 +232,6 @@
     property public final boolean isAnimationRunning;
     property public final boolean isClosed;
     property public final boolean isOpen;
-    property @androidx.compose.material.ExperimentalMaterialApi public final float offset;
-    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.DrawerValue targetValue;
     field public static final androidx.compose.material.DrawerState.Companion Companion;
   }
 
@@ -423,25 +257,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> LocalElevationOverlay;
   }
 
-  @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterialApi {
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface ExposedDropdownMenuBoxScope {
-    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ExposedDropdownMenuDefaults {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded, optional kotlin.jvm.functions.Function0<kotlin.Unit> onIconClick);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    field public static final androidx.compose.material.ExposedDropdownMenuDefaults INSTANCE;
-  }
-
-  public final class ExposedDropdownMenuKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
-  }
-
   @kotlin.jvm.JvmInline public final value class FabPosition {
     field public static final androidx.compose.material.FabPosition.Companion Companion;
   }
@@ -453,12 +268,6 @@
     property public final int End;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FixedThreshold implements androidx.compose.material.ThresholdConfig {
-    ctor public FixedThreshold(float offset);
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-    method public androidx.compose.material.FixedThreshold copy-0680j_4(float offset);
-  }
-
   public final class FloatingActionButtonDefaults {
     method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation);
     method @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float hoveredElevation, optional float focusedElevation);
@@ -474,12 +283,6 @@
     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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
-    ctor public FractionalThreshold(float fraction);
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-    method public androidx.compose.material.FractionalThreshold copy(float fraction);
-  }
-
   public final class IconButtonKt {
     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.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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
@@ -492,15 +295,7 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
     method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
-  }
-
-  public final class ListItemKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ListItem(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? secondaryText, optional boolean singleLineSecondaryText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailing, kotlin.jvm.functions.Function0<kotlin.Unit> text);
   }
 
   public final class MaterialTheme {
@@ -531,43 +326,6 @@
     field public static final androidx.compose.material.ModalBottomSheetDefaults INSTANCE;
   }
 
-  public final class ModalBottomSheetKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHalfExpanded);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState {
-    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional boolean isSkipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public androidx.compose.material.ModalBottomSheetValue getCurrentValue();
-    method public androidx.compose.material.ModalBottomSheetValue getTargetValue();
-    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public boolean isVisible();
-    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.ModalBottomSheetValue currentValue;
-    property public final boolean isVisible;
-    property public final androidx.compose.material.ModalBottomSheetValue targetValue;
-    field public static final androidx.compose.material.ModalBottomSheetState.Companion Companion;
-  }
-
-  public static final class ModalBottomSheetState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum ModalBottomSheetValue {
-    method public static androidx.compose.material.ModalBottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.ModalBottomSheetValue[] values();
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Expanded;
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue HalfExpanded;
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Hidden;
-  }
-
   public final class NavigationRailDefaults {
     method public float getElevation();
     property public final float Elevation;
@@ -643,12 +401,6 @@
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public interface SelectableChipColors {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled, boolean selected);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean selected);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean selected);
-  }
-
   @androidx.compose.runtime.Immutable public final class Shapes {
     ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
     method public androidx.compose.material.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
@@ -677,7 +429,6 @@
   }
 
   public final class SliderKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material.SliderColors colors);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
@@ -733,25 +484,6 @@
 
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class SwipeProgress<T> {
-    ctor public SwipeProgress(T from, T to, float fraction);
-    method public float getFraction();
-    method public T getFrom();
-    method public T getTo();
-    property public final float fraction;
-    property public final T from;
-    property public final T to;
-  }
-
-  public final class SwipeToDismissKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material.DismissState state, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material.DismissDirection> directions, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissDirection,? extends androidx.compose.material.ThresholdConfig> dismissThresholds, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.DismissState rememberDismissState(optional androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
   }
 
   public final class SwipeableDefaults {
@@ -765,38 +497,6 @@
     field public static final float StiffResistanceFactor = 20.0f;
   }
 
-  public final class SwipeableKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
-    ctor public SwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final T getCurrentValue();
-    method public final float getDirection();
-    method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
-    method public final androidx.compose.runtime.State<java.lang.Float> getOverflow();
-    method public final androidx.compose.material.SwipeProgress<T> getProgress();
-    method public final T getTargetValue();
-    method public final boolean isAnimationRunning();
-    method public final float performDrag(float delta);
-    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final T currentValue;
-    property @androidx.compose.material.ExperimentalMaterialApi public final float direction;
-    property public final boolean isAnimationRunning;
-    property public final androidx.compose.runtime.State<java.lang.Float> offset;
-    property public final androidx.compose.runtime.State<java.lang.Float> overflow;
-    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.SwipeProgress<T> progress;
-    property @androidx.compose.material.ExperimentalMaterialApi public final T targetValue;
-    field public static final androidx.compose.material.SwipeableState.Companion Companion;
-  }
-
-  public static final class SwipeableState.Companion {
-    method public <T> androidx.compose.runtime.saveable.Saver<androidx.compose.material.SwipeableState<T>,T> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-  }
-
   @androidx.compose.runtime.Stable public interface SwitchColors {
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
@@ -856,27 +556,15 @@
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface TextFieldColorsWithIcons extends androidx.compose.material.TextFieldColors {
-    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
-  }
-
   @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void BorderBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> border);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding);
     method public float getFocusedBorderThickness();
     method public float getMinHeight();
     method public float getMinWidth();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getOutlinedTextFieldShape();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getTextFieldShape();
     method public float getUnfocusedBorderThickness();
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
     method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
     method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
     property public final float FocusedBorderThickness;
     property public final float MinHeight;
     property public final float MinWidth;
@@ -906,10 +594,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ThresholdConfig {
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-  }
-
   @androidx.compose.runtime.Immutable public final class Typography {
     ctor public Typography(optional androidx.compose.ui.text.font.FontFamily defaultFontFamily, optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
     method public androidx.compose.material.Typography copy(optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
@@ -943,37 +627,3 @@
 
 }
 
-package androidx.compose.material.pullrefresh {
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshDefaults {
-    method public float getRefreshThreshold();
-    method public float getRefreshingOffset();
-    property public final float RefreshThreshold;
-    property public final float RefreshingOffset;
-    field public static final androidx.compose.material.pullrefresh.PullRefreshDefaults INSTANCE;
-  }
-
-  public final class PullRefreshIndicatorKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void PullRefreshIndicator(boolean refreshing, androidx.compose.material.pullrefresh.PullRefreshState state, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional boolean scale);
-  }
-
-  public final class PullRefreshIndicatorTransformKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefreshIndicatorTransform(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean scale);
-  }
-
-  public final class PullRefreshKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean enabled);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> onPull, kotlin.jvm.functions.Function2<? super java.lang.Float,? super kotlin.coroutines.Continuation<? super java.lang.Float>,?> onRelease, optional boolean enabled);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshState {
-    method public float getProgress();
-    property public final float progress;
-  }
-
-  public final class PullRefreshStateKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.pullrefresh.PullRefreshState rememberPullRefreshState(boolean refreshing, kotlin.jvm.functions.Function0<kotlin.Unit> onRefresh, optional float refreshThreshold, optional float refreshingOffset);
-  }
-
-}
-
diff --git a/compose/material/material/api/public_plus_experimental_1.5.0-beta01.txt b/compose/material/material/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..3ce6f1ce
--- /dev/null
+++ b/compose/material/material/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,979 @@
+// Signature format: 4.0
+package androidx.compose.material {
+
+  public final class AndroidAlertDialog_androidKt {
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> buttons, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.ui.window.DialogProperties properties);
+    method @androidx.compose.runtime.Composable public static void AlertDialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, kotlin.jvm.functions.Function0<kotlin.Unit> confirmButton, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? dismissButton, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? text, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.ui.window.DialogProperties properties);
+  }
+
+  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 @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> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, 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 AppBarDefaults {
+    method public float getBottomAppBarElevation();
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method public float getTopAppBarElevation();
+    property public final float BottomAppBarElevation;
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float TopAppBarElevation;
+    field public static final androidx.compose.material.AppBarDefaults INSTANCE;
+  }
+
+  public final class AppBarKt {
+    method @androidx.compose.runtime.Composable public static void BottomAppBar(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional androidx.compose.ui.graphics.Shape? cutoutShape, optional float elevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TopAppBar(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void TopAppBar(kotlin.jvm.functions.Function0<kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? navigationIcon, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> actions, optional long backgroundColor, optional long contentColor, optional float elevation);
+  }
+
+  public final class BackdropScaffoldDefaults {
+    method public float getFrontLayerElevation();
+    method @androidx.compose.runtime.Composable public long getFrontLayerScrimColor();
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.Shape getFrontLayerShape();
+    method public float getHeaderHeight();
+    method public float getPeekHeight();
+    property public final float FrontLayerElevation;
+    property public final float HeaderHeight;
+    property public final float PeekHeight;
+    property @androidx.compose.runtime.Composable public final long frontLayerScrimColor;
+    property @androidx.compose.runtime.Composable public final androidx.compose.ui.graphics.Shape frontLayerShape;
+    field public static final androidx.compose.material.BackdropScaffoldDefaults INSTANCE;
+  }
+
+  public final class BackdropScaffoldKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BackdropScaffold(kotlin.jvm.functions.Function0<kotlin.Unit> appBar, kotlin.jvm.functions.Function0<kotlin.Unit> backLayerContent, kotlin.jvm.functions.Function0<kotlin.Unit> frontLayerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BackdropScaffoldState scaffoldState, optional boolean gesturesEnabled, optional float peekHeight, optional float headerHeight, optional boolean persistentAppBar, optional boolean stickyFrontLayer, optional long backLayerBackgroundColor, optional long backLayerContentColor, optional androidx.compose.ui.graphics.Shape frontLayerShape, optional float frontLayerElevation, optional long frontLayerBackgroundColor, optional long frontLayerContentColor, optional long frontLayerScrimColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BackdropScaffoldState rememberBackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
+    ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
+    method public boolean isConcealed();
+    method public boolean isRevealed();
+    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final boolean isConcealed;
+    property public final boolean isRevealed;
+    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
+    field public static final androidx.compose.material.BackdropScaffoldState.Companion Companion;
+  }
+
+  public static final class BackdropScaffoldState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public enum BackdropValue {
+    method public static androidx.compose.material.BackdropValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.BackdropValue[] values();
+    enum_constant public static final androidx.compose.material.BackdropValue Concealed;
+    enum_constant public static final androidx.compose.material.BackdropValue Revealed;
+  }
+
+  public final class BadgeKt {
+    method @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
+    method @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class BottomDrawerState {
+    ctor @Deprecated public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material.BottomDrawerValue getCurrentValue();
+    method public float getOffset();
+    method public androidx.compose.material.BottomDrawerValue getTargetValue();
+    method public boolean isClosed();
+    method public boolean isExpanded();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material.BottomDrawerValue currentValue;
+    property public final boolean isClosed;
+    property public final boolean isExpanded;
+    property public final boolean isOpen;
+    property public final float offset;
+    property public final androidx.compose.material.BottomDrawerValue targetValue;
+    field public static final androidx.compose.material.BottomDrawerState.Companion Companion;
+  }
+
+  public static final class BottomDrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(androidx.compose.ui.unit.Density density, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public enum BottomDrawerValue {
+    method public static androidx.compose.material.BottomDrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.BottomDrawerValue[] values();
+    enum_constant public static final androidx.compose.material.BottomDrawerValue Closed;
+    enum_constant public static final androidx.compose.material.BottomDrawerValue Expanded;
+    enum_constant public static final androidx.compose.material.BottomDrawerValue Open;
+  }
+
+  public final class BottomNavigationDefaults {
+    method public float getElevation();
+    property public final float Elevation;
+    field public static final androidx.compose.material.BottomNavigationDefaults INSTANCE;
+  }
+
+  public final class BottomNavigationKt {
+    method @androidx.compose.runtime.Composable public static void BottomNavigation(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void BottomNavigationItem(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.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+  }
+
+  public final class BottomSheetScaffoldDefaults {
+    method public float getSheetElevation();
+    method public float getSheetPeekHeight();
+    property public final float SheetElevation;
+    property public final float SheetPeekHeight;
+    field public static final androidx.compose.material.BottomSheetScaffoldDefaults INSTANCE;
+  }
+
+  public final class BottomSheetScaffoldKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomSheetState BottomSheetScaffoldState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BottomSheetState BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
+    ctor public BottomSheetScaffoldState(androidx.compose.material.DrawerState drawerState, androidx.compose.material.BottomSheetState bottomSheetState, androidx.compose.material.SnackbarHostState snackbarHostState);
+    method public androidx.compose.material.BottomSheetState getBottomSheetState();
+    method public androidx.compose.material.DrawerState getDrawerState();
+    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
+    property public final androidx.compose.material.BottomSheetState bottomSheetState;
+    property public final androidx.compose.material.DrawerState drawerState;
+    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState {
+    ctor @Deprecated public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
+    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material.BottomSheetValue getCurrentValue();
+    method @Deprecated public float getOffset();
+    method public float getProgress();
+    method public boolean isCollapsed();
+    method public boolean isExpanded();
+    method public float requireOffset();
+    property public final androidx.compose.material.BottomSheetValue currentValue;
+    property public final boolean isCollapsed;
+    property public final boolean isExpanded;
+    property @Deprecated public final float offset;
+    property public final float progress;
+    field public static final androidx.compose.material.BottomSheetState.Companion Companion;
+  }
+
+  public static final class BottomSheetState.Companion {
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public enum BottomSheetValue {
+    method public static androidx.compose.material.BottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.BottomSheetValue[] values();
+    enum_constant public static final androidx.compose.material.BottomSheetValue Collapsed;
+    enum_constant public static final androidx.compose.material.BottomSheetValue Expanded;
+  }
+
+  @androidx.compose.runtime.Stable public interface ButtonColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+  }
+
+  public final class ButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ButtonColors buttonColors(optional long backgroundColor, optional long contentColor, optional long disabledBackgroundColor, optional long disabledContentColor);
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.ButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float disabledElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float disabledElevation, optional float hoveredElevation, optional float focusedElevation);
+    method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+    method public float getIconSize();
+    method public float getIconSpacing();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedBorder();
+    method public float getOutlinedBorderSize();
+    method public androidx.compose.foundation.layout.PaddingValues getTextButtonContentPadding();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ButtonColors outlinedButtonColors(optional long backgroundColor, optional long contentColor, optional long disabledContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ButtonColors textButtonColors(optional long backgroundColor, optional long contentColor, optional long disabledContentColor);
+    property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+    property public final float IconSize;
+    property public final float IconSpacing;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property public final float OutlinedBorderSize;
+    property public final androidx.compose.foundation.layout.PaddingValues TextButtonContentPadding;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedBorder;
+    field public static final androidx.compose.material.ButtonDefaults INSTANCE;
+    field public static final float OutlinedBorderOpacity = 0.12f;
+  }
+
+  @androidx.compose.runtime.Stable public interface ButtonElevation {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(boolean enabled, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+  }
+
+  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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.ButtonElevation? elevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ButtonColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  public final class CardKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable 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 long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Stable public interface CheckboxColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> borderColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> boxColor(boolean enabled, androidx.compose.ui.state.ToggleableState state);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> checkmarkColor(androidx.compose.ui.state.ToggleableState state);
+  }
+
+  public final class CheckboxDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.CheckboxColors colors(optional long checkedColor, optional long uncheckedColor, optional long checkmarkColor, optional long disabledColor, optional long disabledIndeterminateColor);
+    field public static final androidx.compose.material.CheckboxDefaults INSTANCE;
+  }
+
+  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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
+    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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ChipColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconContentColor(boolean enabled);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class ChipDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors chipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors filterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
+    method public float getLeadingIconSize();
+    method public float getMinHeight();
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedBorder();
+    method public float getOutlinedBorderSize();
+    method public float getSelectedIconSize();
+    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors outlinedChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors outlinedFilterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
+    property public final float LeadingIconSize;
+    property public final float MinHeight;
+    property public final float OutlinedBorderSize;
+    property public final float SelectedIconSize;
+    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedBorder;
+    field public static final float ContentOpacity = 0.87f;
+    field public static final androidx.compose.material.ChipDefaults INSTANCE;
+    field public static final float LeadingIconOpacity = 0.54f;
+    field public static final float OutlinedBorderOpacity = 0.12f;
+  }
+
+  public final class ChipKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Chip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.SelectableChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? selectedIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.Stable public final class Colors {
+    ctor public Colors(long primary, long primaryVariant, long secondary, long secondaryVariant, long background, long surface, long error, long onPrimary, long onSecondary, long onBackground, long onSurface, long onError, boolean isLight);
+    method public androidx.compose.material.Colors copy(optional long primary, optional long primaryVariant, optional long secondary, optional long secondaryVariant, optional long background, optional long surface, optional long error, optional long onPrimary, optional long onSecondary, optional long onBackground, optional long onSurface, optional long onError, optional boolean isLight);
+    method public long getBackground();
+    method public long getError();
+    method public long getOnBackground();
+    method public long getOnError();
+    method public long getOnPrimary();
+    method public long getOnSecondary();
+    method public long getOnSurface();
+    method public long getPrimary();
+    method public long getPrimaryVariant();
+    method public long getSecondary();
+    method public long getSecondaryVariant();
+    method public long getSurface();
+    method public boolean isLight();
+    property public final long background;
+    property public final long error;
+    property public final boolean isLight;
+    property public final long onBackground;
+    property public final long onError;
+    property public final long onPrimary;
+    property public final long onSecondary;
+    property public final long onSurface;
+    property public final long primary;
+    property public final long primaryVariant;
+    property public final long secondary;
+    property public final long secondaryVariant;
+    property public final long surface;
+  }
+
+  public final class ColorsKt {
+    method public static long contentColorFor(androidx.compose.material.Colors, long backgroundColor);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long contentColorFor(long backgroundColor);
+    method public static androidx.compose.material.Colors darkColors(optional long primary, optional long primaryVariant, optional long secondary, optional long secondaryVariant, optional long background, optional long surface, optional long error, optional long onPrimary, optional long onSecondary, optional long onBackground, optional long onSurface, optional long onError);
+    method public static long getPrimarySurface(androidx.compose.material.Colors);
+    method public static androidx.compose.material.Colors lightColors(optional long primary, optional long primaryVariant, optional long secondary, optional long secondaryVariant, optional long background, optional long surface, optional long error, optional long onPrimary, optional long onSecondary, optional long onBackground, optional long onSurface, optional long onError);
+  }
+
+  public final class ContentAlpha {
+    method @androidx.compose.runtime.Composable public float getDisabled();
+    method @androidx.compose.runtime.Composable public float getHigh();
+    method @androidx.compose.runtime.Composable public float getMedium();
+    property @androidx.compose.runtime.Composable public final float disabled;
+    property @androidx.compose.runtime.Composable public final float high;
+    property @androidx.compose.runtime.Composable public final float medium;
+    field public static final androidx.compose.material.ContentAlpha INSTANCE;
+  }
+
+  public final class ContentAlphaKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Float> getLocalContentAlpha();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Float> LocalContentAlpha;
+  }
+
+  public final class ContentColorKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> getLocalContentColor();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.graphics.Color> LocalContentColor;
+  }
+
+  public enum DismissDirection {
+    method public static androidx.compose.material.DismissDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.DismissDirection[] values();
+    enum_constant public static final androidx.compose.material.DismissDirection EndToStart;
+    enum_constant public static final androidx.compose.material.DismissDirection StartToEnd;
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
+    ctor public DismissState(androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
+    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material.DismissDirection? getDismissDirection();
+    method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
+    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material.DismissDirection? dismissDirection;
+    field public static final androidx.compose.material.DismissState.Companion Companion;
+  }
+
+  public static final class DismissState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.DismissState,androidx.compose.material.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DismissValue {
+    method public static androidx.compose.material.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.DismissValue[] values();
+    enum_constant public static final androidx.compose.material.DismissValue Default;
+    enum_constant public static final androidx.compose.material.DismissValue DismissedToEnd;
+    enum_constant public static final androidx.compose.material.DismissValue DismissedToStart;
+  }
+
+  public final class DividerKt {
+    method @androidx.compose.runtime.Composable public static void Divider(optional androidx.compose.ui.Modifier modifier, optional long color, optional float thickness, optional float startIndent);
+  }
+
+  public final class DrawerDefaults {
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    field public static final androidx.compose.material.DrawerDefaults INSTANCE;
+    field public static final float ScrimOpacity = 0.32f;
+  }
+
+  public final class DrawerKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomDrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomDrawerState BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.runtime.Composable public static void ModalDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.DrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomDrawerState rememberBottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material.DrawerState rememberDrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  @androidx.compose.runtime.Stable public final class DrawerState {
+    ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public suspend Object? animateTo(androidx.compose.material.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.material.DrawerValue getCurrentValue();
+    method @androidx.compose.material.ExperimentalMaterialApi public float getOffset();
+    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.material.DrawerValue getTargetValue();
+    method public boolean isAnimationRunning();
+    method public boolean isClosed();
+    method public boolean isOpen();
+    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? snapTo(androidx.compose.material.DrawerValue targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material.DrawerValue currentValue;
+    property public final boolean isAnimationRunning;
+    property public final boolean isClosed;
+    property public final boolean isOpen;
+    property @androidx.compose.material.ExperimentalMaterialApi public final float offset;
+    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.DrawerValue targetValue;
+    field public static final androidx.compose.material.DrawerState.Companion Companion;
+  }
+
+  public static final class DrawerState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.DrawerState,androidx.compose.material.DrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public enum DrawerValue {
+    method public static androidx.compose.material.DrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.DrawerValue[] values();
+    enum_constant public static final androidx.compose.material.DrawerValue Closed;
+    enum_constant public static final androidx.compose.material.DrawerValue Open;
+  }
+
+  public interface ElevationOverlay {
+    method @androidx.compose.runtime.Composable public long apply(long color, float elevation);
+  }
+
+  public final class ElevationOverlayKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteElevation();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> getLocalElevationOverlay();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteElevation;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> LocalElevationOverlay;
+  }
+
+  @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterialApi {
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface ExposedDropdownMenuBoxScope {
+    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class ExposedDropdownMenuDefaults {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded, optional kotlin.jvm.functions.Function0<kotlin.Unit> onIconClick);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    field public static final androidx.compose.material.ExposedDropdownMenuDefaults INSTANCE;
+  }
+
+  public final class ExposedDropdownMenuKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FabPosition {
+    field public static final androidx.compose.material.FabPosition.Companion Companion;
+  }
+
+  public static final class FabPosition.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    property public final int Center;
+    property public final int End;
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FixedThreshold implements androidx.compose.material.ThresholdConfig {
+    ctor public FixedThreshold(float offset);
+    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
+    method public androidx.compose.material.FixedThreshold copy-0680j_4(float offset);
+  }
+
+  public final class FloatingActionButtonDefaults {
+    method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float hoveredElevation, optional float focusedElevation);
+    field public static final androidx.compose.material.FloatingActionButtonDefaults INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public interface FloatingActionButtonElevation {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.unit.Dp> elevation(androidx.compose.foundation.interaction.InteractionSource interactionSource);
+  }
+
+  public final class FloatingActionButtonKt {
+    method @androidx.compose.runtime.Composable public static void ExtendedFloatingActionButton(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>? icon, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation);
+    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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
+    ctor public FractionalThreshold(float fraction);
+    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
+    method public androidx.compose.material.FractionalThreshold copy(float fraction);
+  }
+
+  public final class IconButtonKt {
+    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.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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class IconKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Icon(androidx.compose.ui.graphics.ImageBitmap bitmap, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable public static void Icon(androidx.compose.ui.graphics.painter.Painter painter, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Icon(androidx.compose.ui.graphics.vector.ImageVector imageVector, String? contentDescription, optional androidx.compose.ui.Modifier modifier, optional long tint);
+  }
+
+  public final class InteractiveComponentSizeKt {
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
+    method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
+    property @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
+    property @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
+  }
+
+  public final class ListItemKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ListItem(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? secondaryText, optional boolean singleLineSecondaryText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailing, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+  }
+
+  public final class MaterialTheme {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material.Colors getColors();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material.Shapes getShapes();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.material.Typography getTypography();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material.Colors colors;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material.Shapes shapes;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.material.Typography typography;
+    field public static final androidx.compose.material.MaterialTheme INSTANCE;
+  }
+
+  public final class MaterialThemeKt {
+    method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.compose.material.Colors colors, optional androidx.compose.material.Typography typography, optional androidx.compose.material.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class MenuDefaults {
+    method public androidx.compose.foundation.layout.PaddingValues getDropdownMenuItemContentPadding();
+    property public final androidx.compose.foundation.layout.PaddingValues DropdownMenuItemContentPadding;
+    field public static final androidx.compose.material.MenuDefaults INSTANCE;
+  }
+
+  public final class ModalBottomSheetDefaults {
+    method public float getElevation();
+    method @androidx.compose.runtime.Composable public long getScrimColor();
+    property public final float Elevation;
+    property @androidx.compose.runtime.Composable public final long scrimColor;
+    field public static final androidx.compose.material.ModalBottomSheetDefaults INSTANCE;
+  }
+
+  public final class ModalBottomSheetKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHalfExpanded);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState {
+    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional boolean isSkipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
+    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method public androidx.compose.material.ModalBottomSheetValue getCurrentValue();
+    method public androidx.compose.material.ModalBottomSheetValue getTargetValue();
+    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public boolean isVisible();
+    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final androidx.compose.material.ModalBottomSheetValue currentValue;
+    property public final boolean isVisible;
+    property public final androidx.compose.material.ModalBottomSheetValue targetValue;
+    field public static final androidx.compose.material.ModalBottomSheetState.Companion Companion;
+  }
+
+  public static final class ModalBottomSheetState.Companion {
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
+    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded);
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public enum ModalBottomSheetValue {
+    method public static androidx.compose.material.ModalBottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.ModalBottomSheetValue[] values();
+    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Expanded;
+    enum_constant public static final androidx.compose.material.ModalBottomSheetValue HalfExpanded;
+    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Hidden;
+  }
+
+  public final class NavigationRailDefaults {
+    method public float getElevation();
+    property public final float Elevation;
+    field public static final androidx.compose.material.NavigationRailDefaults INSTANCE;
+  }
+
+  public final class NavigationRailKt {
+    method @androidx.compose.runtime.Composable public static void NavigationRail(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float elevation, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? header, 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.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+  }
+
+  public final class OutlinedTextFieldKt {
+    method @Deprecated @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 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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.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 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.material.TextFieldColors colors);
+    method @Deprecated @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 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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.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 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.material.TextFieldColors colors);
+  }
+
+  public final class ProgressIndicatorDefaults {
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getProgressAnimationSpec();
+    method public float getStrokeWidth();
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> ProgressAnimationSpec;
+    property public final float StrokeWidth;
+    field public static final androidx.compose.material.ProgressIndicatorDefaults INSTANCE;
+    field public static final float IndicatorBackgroundOpacity = 0.24f;
+  }
+
+  public final class ProgressIndicatorKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long backgroundColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth);
+    method @androidx.compose.runtime.Composable public static void CircularProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional float strokeWidth, optional long backgroundColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long backgroundColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(optional androidx.compose.ui.Modifier modifier, optional long color, optional long backgroundColor, optional int strokeCap);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long backgroundColor);
+    method @androidx.compose.runtime.Composable public static void LinearProgressIndicator(float progress, optional androidx.compose.ui.Modifier modifier, optional long color, optional long backgroundColor, optional int strokeCap);
+  }
+
+  @androidx.compose.runtime.Stable public interface RadioButtonColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> radioColor(boolean enabled, boolean selected);
+  }
+
+  public final class RadioButtonDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.RadioButtonColors colors(optional long selectedColor, optional long unselectedColor, optional long disabledColor);
+    field public static final androidx.compose.material.RadioButtonDefaults INSTANCE;
+  }
+
+  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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.RadioButtonColors colors);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ResistanceConfig {
+    ctor public ResistanceConfig(float basis, optional float factorAtMin, optional float factorAtMax);
+    method public float computeResistance(float overflow);
+    method public float getBasis();
+    method public float getFactorAtMax();
+    method public float getFactorAtMin();
+    property public final float basis;
+    property public final float factorAtMax;
+    property public final float factorAtMin;
+  }
+
+  public final class ScaffoldKt {
+    method @androidx.compose.runtime.Composable public static void Scaffold(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit> topBar, optional kotlin.jvm.functions.Function0<kotlin.Unit> bottomBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit> floatingActionButton, optional int floatingActionButtonPosition, optional boolean isFloatingActionButtonDocked, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static androidx.compose.material.ScaffoldState rememberScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
+  }
+
+  @androidx.compose.runtime.Stable public final class ScaffoldState {
+    ctor public ScaffoldState(androidx.compose.material.DrawerState drawerState, androidx.compose.material.SnackbarHostState snackbarHostState);
+    method public androidx.compose.material.DrawerState getDrawerState();
+    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
+    property public final androidx.compose.material.DrawerState drawerState;
+    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public interface SelectableChipColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled, boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean selected);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean selected);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shapes {
+    ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
+    method public androidx.compose.material.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
+    method public androidx.compose.foundation.shape.CornerBasedShape getLarge();
+    method public androidx.compose.foundation.shape.CornerBasedShape getMedium();
+    method public androidx.compose.foundation.shape.CornerBasedShape getSmall();
+    property public final androidx.compose.foundation.shape.CornerBasedShape large;
+    property public final androidx.compose.foundation.shape.CornerBasedShape medium;
+    property public final androidx.compose.foundation.shape.CornerBasedShape small;
+  }
+
+  @androidx.compose.runtime.Stable public interface SliderColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> tickColor(boolean enabled, boolean active);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean active);
+  }
+
+  public final class SliderDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SliderColors colors(optional long thumbColor, optional long disabledThumbColor, optional long activeTrackColor, optional long inactiveTrackColor, optional long disabledActiveTrackColor, optional long disabledInactiveTrackColor, optional long activeTickColor, optional long inactiveTickColor, optional long disabledActiveTickColor, optional long disabledInactiveTickColor);
+    field public static final float DisabledActiveTrackAlpha = 0.32f;
+    field public static final float DisabledInactiveTrackAlpha = 0.12f;
+    field public static final float DisabledTickAlpha = 0.12f;
+    field public static final androidx.compose.material.SliderDefaults INSTANCE;
+    field public static final float InactiveTrackAlpha = 0.24f;
+    field public static final float TickAlpha = 0.54f;
+  }
+
+  public final class SliderKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material.SliderColors colors);
+    method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
+  }
+
+  public interface SnackbarData {
+    method public void dismiss();
+    method public String? getActionLabel();
+    method public androidx.compose.material.SnackbarDuration getDuration();
+    method public String getMessage();
+    method public void performAction();
+    property public abstract String? actionLabel;
+    property public abstract androidx.compose.material.SnackbarDuration duration;
+    property public abstract String message;
+  }
+
+  public final class SnackbarDefaults {
+    method @androidx.compose.runtime.Composable public long getBackgroundColor();
+    method @androidx.compose.runtime.Composable public long getPrimaryActionColor();
+    property @androidx.compose.runtime.Composable public final long backgroundColor;
+    property @androidx.compose.runtime.Composable public final long primaryActionColor;
+    field public static final androidx.compose.material.SnackbarDefaults INSTANCE;
+  }
+
+  public enum SnackbarDuration {
+    method public static androidx.compose.material.SnackbarDuration valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.SnackbarDuration[] values();
+    enum_constant public static final androidx.compose.material.SnackbarDuration Indefinite;
+    enum_constant public static final androidx.compose.material.SnackbarDuration Long;
+    enum_constant public static final androidx.compose.material.SnackbarDuration Short;
+  }
+
+  public final class SnackbarHostKt {
+    method @androidx.compose.runtime.Composable public static void SnackbarHost(androidx.compose.material.SnackbarHostState hostState, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarData,kotlin.Unit> snackbar);
+  }
+
+  @androidx.compose.runtime.Stable public final class SnackbarHostState {
+    ctor public SnackbarHostState();
+    method public androidx.compose.material.SnackbarData? getCurrentSnackbarData();
+    method public suspend Object? showSnackbar(String message, optional String? actionLabel, optional androidx.compose.material.SnackbarDuration duration, optional kotlin.coroutines.Continuation<? super androidx.compose.material.SnackbarResult>);
+    property public final androidx.compose.material.SnackbarData? currentSnackbarData;
+  }
+
+  public final class SnackbarKt {
+    method @androidx.compose.runtime.Composable public static void Snackbar(androidx.compose.material.SnackbarData snackbarData, optional androidx.compose.ui.Modifier modifier, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional long actionColor, optional float elevation);
+    method @androidx.compose.runtime.Composable public static void Snackbar(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional boolean actionOnNewLine, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public enum SnackbarResult {
+    method public static androidx.compose.material.SnackbarResult valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.material.SnackbarResult[] values();
+    enum_constant public static final androidx.compose.material.SnackbarResult ActionPerformed;
+    enum_constant public static final androidx.compose.material.SnackbarResult Dismissed;
+  }
+
+  public final class SurfaceKt {
+    method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class SwipeProgress<T> {
+    ctor public SwipeProgress(T from, T to, float fraction);
+    method public float getFraction();
+    method public T getFrom();
+    method public T getTo();
+    property public final float fraction;
+    property public final T from;
+    property public final T to;
+  }
+
+  public final class SwipeToDismissKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material.DismissState state, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material.DismissDirection> directions, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissDirection,? extends androidx.compose.material.ThresholdConfig> dismissThresholds, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.DismissState rememberDismissState(optional androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
+  }
+
+  public final class SwipeableDefaults {
+    method public androidx.compose.animation.core.SpringSpec<java.lang.Float> getAnimationSpec();
+    method public float getVelocityThreshold();
+    method public androidx.compose.material.ResistanceConfig? resistanceConfig(java.util.Set<java.lang.Float> anchors, optional float factorAtMin, optional float factorAtMax);
+    property public final androidx.compose.animation.core.SpringSpec<java.lang.Float> AnimationSpec;
+    property public final float VelocityThreshold;
+    field public static final androidx.compose.material.SwipeableDefaults INSTANCE;
+    field public static final float StandardResistanceFactor = 10.0f;
+    field public static final float StiffResistanceFactor = 20.0f;
+  }
+
+  public final class SwipeableKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
+    ctor public SwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
+    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public final T getCurrentValue();
+    method public final float getDirection();
+    method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
+    method public final androidx.compose.runtime.State<java.lang.Float> getOverflow();
+    method public final androidx.compose.material.SwipeProgress<T> getProgress();
+    method public final T getTargetValue();
+    method public final boolean isAnimationRunning();
+    method public final float performDrag(float delta);
+    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final T currentValue;
+    property @androidx.compose.material.ExperimentalMaterialApi public final float direction;
+    property public final boolean isAnimationRunning;
+    property public final androidx.compose.runtime.State<java.lang.Float> offset;
+    property public final androidx.compose.runtime.State<java.lang.Float> overflow;
+    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.SwipeProgress<T> progress;
+    property @androidx.compose.material.ExperimentalMaterialApi public final T targetValue;
+    field public static final androidx.compose.material.SwipeableState.Companion Companion;
+  }
+
+  public static final class SwipeableState.Companion {
+    method public <T> androidx.compose.runtime.saveable.Saver<androidx.compose.material.SwipeableState<T>,T> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
+  }
+
+  @androidx.compose.runtime.Stable public interface SwitchColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
+  }
+
+  public final class SwitchDefaults {
+    method @androidx.compose.runtime.Composable public androidx.compose.material.SwitchColors colors(optional long checkedThumbColor, optional long checkedTrackColor, optional float checkedTrackAlpha, optional long uncheckedThumbColor, optional long uncheckedTrackColor, optional float uncheckedTrackAlpha, optional long disabledCheckedThumbColor, optional long disabledCheckedTrackColor, optional long disabledUncheckedThumbColor, optional long disabledUncheckedTrackColor);
+    field public static final androidx.compose.material.SwitchDefaults INSTANCE;
+  }
+
+  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 boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SwitchColors colors);
+  }
+
+  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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+    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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional long selectedContentColor, optional long unselectedContentColor);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TabPosition {
+    method public float getLeft();
+    method public float getRight();
+    method public float getWidth();
+    property public final float left;
+    property public final float right;
+    property public final float width;
+  }
+
+  public final class TabRowDefaults {
+    method @androidx.compose.runtime.Composable public void Divider(optional androidx.compose.ui.Modifier modifier, optional float thickness, optional long color);
+    method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+    method public float getDividerThickness();
+    method public float getIndicatorHeight();
+    method public float getScrollableTabRowPadding();
+    method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material.TabPosition currentTabPosition);
+    property public final float DividerThickness;
+    property public final float IndicatorHeight;
+    property public final float ScrollableTabRowPadding;
+    field public static final float DividerOpacity = 0.12f;
+    field public static final androidx.compose.material.TabRowDefaults INSTANCE;
+  }
+
+  public final class TabRowKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void ScrollableTabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional float edgePadding, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void TabRow(int selectedTabIndex, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.material.TabPosition>,kotlin.Unit> indicator, optional kotlin.jvm.functions.Function0<kotlin.Unit> divider, kotlin.jvm.functions.Function0<kotlin.Unit> tabs);
+  }
+
+  @androidx.compose.runtime.Stable public interface TextFieldColors {
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> cursorColor(boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> indicatorColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> labelColor(boolean enabled, boolean error, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> placeholderColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> textColor(boolean enabled);
+    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface TextFieldColorsWithIcons extends androidx.compose.material.TextFieldColors {
+    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void BorderBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> border);
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding);
+    method public float getFocusedBorderThickness();
+    method public float getMinHeight();
+    method public float getMinWidth();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getOutlinedTextFieldShape();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getTextFieldShape();
+    method public float getUnfocusedBorderThickness();
+    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
+    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
+    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
+    property public final float FocusedBorderThickness;
+    property public final float MinHeight;
+    property public final float MinWidth;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape OutlinedTextFieldShape;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape TextFieldShape;
+    property public final float UnfocusedBorderThickness;
+    field public static final float BackgroundOpacity = 0.12f;
+    field public static final androidx.compose.material.TextFieldDefaults INSTANCE;
+    field public static final float IconOpacity = 0.54f;
+    field public static final float UnfocusedIndicatorLineOpacity = 0.42f;
+  }
+
+  public final class TextFieldKt {
+    method @Deprecated @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 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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.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 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.material.TextFieldColors colors);
+    method @Deprecated @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 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 androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material.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 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.material.TextFieldColors colors);
+  }
+
+  public final class TextKt {
+    method @androidx.compose.runtime.Composable public static void ProvideTextStyle(androidx.compose.ui.text.TextStyle value, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.Map<java.lang.String,androidx.compose.foundation.text.InlineTextContent> inlineContent, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional int minLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit>? onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method @Deprecated @androidx.compose.runtime.Composable public static void Text(String text, optional androidx.compose.ui.Modifier modifier, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional long letterSpacing, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional long lineHeight, optional int overflow, optional boolean softWrap, optional int maxLines, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.TextLayoutResult,kotlin.Unit> onTextLayout, optional androidx.compose.ui.text.TextStyle style);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> getLocalTextStyle();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ThresholdConfig {
+    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Typography {
+    ctor public Typography(optional androidx.compose.ui.text.font.FontFamily defaultFontFamily, optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
+    method public androidx.compose.material.Typography copy(optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
+    method public androidx.compose.ui.text.TextStyle getBody1();
+    method public androidx.compose.ui.text.TextStyle getBody2();
+    method public androidx.compose.ui.text.TextStyle getButton();
+    method public androidx.compose.ui.text.TextStyle getCaption();
+    method public androidx.compose.ui.text.TextStyle getH1();
+    method public androidx.compose.ui.text.TextStyle getH2();
+    method public androidx.compose.ui.text.TextStyle getH3();
+    method public androidx.compose.ui.text.TextStyle getH4();
+    method public androidx.compose.ui.text.TextStyle getH5();
+    method public androidx.compose.ui.text.TextStyle getH6();
+    method public androidx.compose.ui.text.TextStyle getOverline();
+    method public androidx.compose.ui.text.TextStyle getSubtitle1();
+    method public androidx.compose.ui.text.TextStyle getSubtitle2();
+    property public final androidx.compose.ui.text.TextStyle body1;
+    property public final androidx.compose.ui.text.TextStyle body2;
+    property public final androidx.compose.ui.text.TextStyle button;
+    property public final androidx.compose.ui.text.TextStyle caption;
+    property public final androidx.compose.ui.text.TextStyle h1;
+    property public final androidx.compose.ui.text.TextStyle h2;
+    property public final androidx.compose.ui.text.TextStyle h3;
+    property public final androidx.compose.ui.text.TextStyle h4;
+    property public final androidx.compose.ui.text.TextStyle h5;
+    property public final androidx.compose.ui.text.TextStyle h6;
+    property public final androidx.compose.ui.text.TextStyle overline;
+    property public final androidx.compose.ui.text.TextStyle subtitle1;
+    property public final androidx.compose.ui.text.TextStyle subtitle2;
+  }
+
+}
+
+package androidx.compose.material.pullrefresh {
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshDefaults {
+    method public float getRefreshThreshold();
+    method public float getRefreshingOffset();
+    property public final float RefreshThreshold;
+    property public final float RefreshingOffset;
+    field public static final androidx.compose.material.pullrefresh.PullRefreshDefaults INSTANCE;
+  }
+
+  public final class PullRefreshIndicatorKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void PullRefreshIndicator(boolean refreshing, androidx.compose.material.pullrefresh.PullRefreshState state, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional boolean scale);
+  }
+
+  public final class PullRefreshIndicatorTransformKt {
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefreshIndicatorTransform(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean scale);
+  }
+
+  public final class PullRefreshKt {
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean enabled);
+    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> onPull, kotlin.jvm.functions.Function2<? super java.lang.Float,? super kotlin.coroutines.Continuation<? super java.lang.Float>,?> onRelease, optional boolean enabled);
+  }
+
+  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshState {
+    method public float getProgress();
+    property public final float progress;
+  }
+
+  public final class PullRefreshStateKt {
+    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.pullrefresh.PullRefreshState rememberPullRefreshState(boolean refreshing, kotlin.jvm.functions.Function0<kotlin.Unit> onRefresh, optional float refreshThreshold, optional float refreshingOffset);
+  }
+
+}
+
diff --git a/compose/material/material/api/restricted_1.5.0-beta01.txt b/compose/material/material/api/restricted_1.5.0-beta01.txt
index 3ce6f1ce..8935416 100644
--- a/compose/material/material/api/restricted_1.5.0-beta01.txt
+++ b/compose/material/material/api/restricted_1.5.0-beta01.txt
@@ -42,73 +42,11 @@
     field public static final androidx.compose.material.BackdropScaffoldDefaults INSTANCE;
   }
 
-  public final class BackdropScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BackdropScaffold(kotlin.jvm.functions.Function0<kotlin.Unit> appBar, kotlin.jvm.functions.Function0<kotlin.Unit> backLayerContent, kotlin.jvm.functions.Function0<kotlin.Unit> frontLayerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BackdropScaffoldState scaffoldState, optional boolean gesturesEnabled, optional float peekHeight, optional float headerHeight, optional boolean persistentAppBar, optional boolean stickyFrontLayer, optional long backLayerBackgroundColor, optional long backLayerContentColor, optional androidx.compose.ui.graphics.Shape frontLayerShape, optional float frontLayerElevation, optional long frontLayerBackgroundColor, optional long frontLayerContentColor, optional long frontLayerScrimColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BackdropScaffoldState rememberBackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BackdropScaffoldState extends androidx.compose.material.SwipeableState<androidx.compose.material.BackdropValue> {
-    ctor public BackdropScaffoldState(androidx.compose.material.BackdropValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public suspend Object? conceal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
-    method public boolean isConcealed();
-    method public boolean isRevealed();
-    method public suspend Object? reveal(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final boolean isConcealed;
-    property public final boolean isRevealed;
-    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
-    field public static final androidx.compose.material.BackdropScaffoldState.Companion Companion;
-  }
-
-  public static final class BackdropScaffoldState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BackdropScaffoldState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BackdropValue,java.lang.Boolean> confirmStateChange, androidx.compose.material.SnackbarHostState snackbarHostState);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BackdropValue {
-    method public static androidx.compose.material.BackdropValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BackdropValue[] values();
-    enum_constant public static final androidx.compose.material.BackdropValue Concealed;
-    enum_constant public static final androidx.compose.material.BackdropValue Revealed;
-  }
-
   public final class BadgeKt {
     method @androidx.compose.runtime.Composable public static void Badge(optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? content);
     method @androidx.compose.runtime.Composable public static void BadgedBox(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> badge, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public final class BottomDrawerState {
-    ctor @Deprecated public BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.BottomDrawerValue getCurrentValue();
-    method public float getOffset();
-    method public androidx.compose.material.BottomDrawerValue getTargetValue();
-    method public boolean isClosed();
-    method public boolean isExpanded();
-    method public boolean isOpen();
-    method public suspend Object? open(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.BottomDrawerValue currentValue;
-    property public final boolean isClosed;
-    property public final boolean isExpanded;
-    property public final boolean isOpen;
-    property public final float offset;
-    property public final androidx.compose.material.BottomDrawerValue targetValue;
-    field public static final androidx.compose.material.BottomDrawerState.Companion Companion;
-  }
-
-  public static final class BottomDrawerState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(androidx.compose.ui.unit.Density density, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomDrawerState,androidx.compose.material.BottomDrawerValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BottomDrawerValue {
-    method public static androidx.compose.material.BottomDrawerValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BottomDrawerValue[] values();
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Closed;
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Expanded;
-    enum_constant public static final androidx.compose.material.BottomDrawerValue Open;
-  }
-
   public final class BottomNavigationDefaults {
     method public float getElevation();
     property public final float Elevation;
@@ -128,54 +66,6 @@
     field public static final androidx.compose.material.BottomSheetScaffoldDefaults INSTANCE;
   }
 
-  public final class BottomSheetScaffoldKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomSheetScaffold(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomSheetScaffoldState scaffoldState, optional kotlin.jvm.functions.Function0<kotlin.Unit>? topBar, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.SnackbarHostState,kotlin.Unit> snackbarHost, optional kotlin.jvm.functions.Function0<kotlin.Unit>? floatingActionButton, optional int floatingActionButtonPosition, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional float sheetPeekHeight, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit>? drawerContent, optional boolean drawerGesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long drawerScrimColor, optional long backgroundColor, optional long contentColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.PaddingValues,kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomSheetState BottomSheetScaffoldState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public static androidx.compose.material.BottomSheetState BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetScaffoldState rememberBottomSheetScaffoldState(optional androidx.compose.material.DrawerState drawerState, optional androidx.compose.material.BottomSheetState bottomSheetState, optional androidx.compose.material.SnackbarHostState snackbarHostState);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomSheetState rememberBottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetScaffoldState {
-    ctor public BottomSheetScaffoldState(androidx.compose.material.DrawerState drawerState, androidx.compose.material.BottomSheetState bottomSheetState, androidx.compose.material.SnackbarHostState snackbarHostState);
-    method public androidx.compose.material.BottomSheetState getBottomSheetState();
-    method public androidx.compose.material.DrawerState getDrawerState();
-    method public androidx.compose.material.SnackbarHostState getSnackbarHostState();
-    property public final androidx.compose.material.BottomSheetState bottomSheetState;
-    property public final androidx.compose.material.DrawerState drawerState;
-    property public final androidx.compose.material.SnackbarHostState snackbarHostState;
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public final class BottomSheetState {
-    ctor @Deprecated public BottomSheetState(androidx.compose.material.BottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmValueChange);
-    method public suspend Object? collapse(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.BottomSheetValue getCurrentValue();
-    method @Deprecated public float getOffset();
-    method public float getProgress();
-    method public boolean isCollapsed();
-    method public boolean isExpanded();
-    method public float requireOffset();
-    property public final androidx.compose.material.BottomSheetValue currentValue;
-    property public final boolean isCollapsed;
-    property public final boolean isExpanded;
-    property @Deprecated public final float offset;
-    property public final float progress;
-    field public static final androidx.compose.material.BottomSheetState.Companion Companion;
-  }
-
-  public static final class BottomSheetState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.BottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomSheetValue,java.lang.Boolean> confirmStateChange, androidx.compose.ui.unit.Density density);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum BottomSheetValue {
-    method public static androidx.compose.material.BottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.BottomSheetValue[] values();
-    enum_constant public static final androidx.compose.material.BottomSheetValue Collapsed;
-    enum_constant public static final androidx.compose.material.BottomSheetValue Expanded;
-  }
-
   @androidx.compose.runtime.Stable public interface ButtonColors {
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
@@ -219,8 +109,6 @@
 
   public final class CardKt {
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable 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 long backgroundColor, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
   @androidx.compose.runtime.Stable public interface CheckboxColors {
@@ -239,38 +127,6 @@
     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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.CheckboxColors colors);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ChipColors {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconContentColor(boolean enabled);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ChipDefaults {
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors chipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors filterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
-    method public float getLeadingIconSize();
-    method public float getMinHeight();
-    method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke getOutlinedBorder();
-    method public float getOutlinedBorderSize();
-    method public float getSelectedIconSize();
-    method @androidx.compose.runtime.Composable public androidx.compose.material.ChipColors outlinedChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconContentColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconContentColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.SelectableChipColors outlinedFilterChipColors(optional long backgroundColor, optional long contentColor, optional long leadingIconColor, optional long disabledBackgroundColor, optional long disabledContentColor, optional long disabledLeadingIconColor, optional long selectedBackgroundColor, optional long selectedContentColor, optional long selectedLeadingIconColor);
-    property public final float LeadingIconSize;
-    property public final float MinHeight;
-    property public final float OutlinedBorderSize;
-    property public final float SelectedIconSize;
-    property @androidx.compose.runtime.Composable public final androidx.compose.foundation.BorderStroke outlinedBorder;
-    field public static final float ContentOpacity = 0.87f;
-    field public static final androidx.compose.material.ChipDefaults INSTANCE;
-    field public static final float LeadingIconOpacity = 0.54f;
-    field public static final float OutlinedBorderOpacity = 0.12f;
-  }
-
-  public final class ChipKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Chip(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.ChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void FilterChip(boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.material.SelectableChipColors colors, optional kotlin.jvm.functions.Function0<kotlin.Unit>? leadingIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? selectedIcon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailingIcon, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
-  }
-
   @androidx.compose.runtime.Stable public final class Colors {
     ctor public Colors(long primary, long primaryVariant, long secondary, long secondaryVariant, long background, long surface, long error, long onPrimary, long onSecondary, long onBackground, long onSurface, long onError, boolean isLight);
     method public androidx.compose.material.Colors copy(optional long primary, optional long primaryVariant, optional long secondary, optional long secondaryVariant, optional long background, optional long surface, optional long error, optional long onPrimary, optional long onSecondary, optional long onBackground, optional long onSurface, optional long onError, optional boolean isLight);
@@ -337,20 +193,6 @@
     enum_constant public static final androidx.compose.material.DismissDirection StartToEnd;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public final class DismissState extends androidx.compose.material.SwipeableState<androidx.compose.material.DismissValue> {
-    ctor public DismissState(androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-    method public suspend Object? dismiss(androidx.compose.material.DismissDirection direction, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.material.DismissDirection? getDismissDirection();
-    method public boolean isDismissed(androidx.compose.material.DismissDirection direction);
-    method public suspend Object? reset(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.DismissDirection? dismissDirection;
-    field public static final androidx.compose.material.DismissState.Companion Companion;
-  }
-
-  public static final class DismissState.Companion {
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.DismissState,androidx.compose.material.DismissValue> Saver(kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
-  }
-
   public enum DismissValue {
     method public static androidx.compose.material.DismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
     method public static androidx.compose.material.DismissValue[] values();
@@ -373,20 +215,14 @@
   }
 
   public final class DrawerKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void BottomDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.BottomDrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.BottomDrawerState BottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
     method @androidx.compose.runtime.Composable public static void ModalDrawer(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> drawerContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.DrawerState drawerState, optional boolean gesturesEnabled, optional androidx.compose.ui.graphics.Shape drawerShape, optional float drawerElevation, optional long drawerBackgroundColor, optional long drawerContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.BottomDrawerState rememberBottomDrawerState(androidx.compose.material.BottomDrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.BottomDrawerValue,java.lang.Boolean> confirmStateChange);
     method @androidx.compose.runtime.Composable public static androidx.compose.material.DrawerState rememberDrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
   }
 
   @androidx.compose.runtime.Stable public final class DrawerState {
     ctor public DrawerState(androidx.compose.material.DrawerValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DrawerValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public suspend Object? animateTo(androidx.compose.material.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public androidx.compose.material.DrawerValue getCurrentValue();
-    method @androidx.compose.material.ExperimentalMaterialApi public float getOffset();
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.material.DrawerValue getTargetValue();
     method public boolean isAnimationRunning();
     method public boolean isClosed();
     method public boolean isOpen();
@@ -396,8 +232,6 @@
     property public final boolean isAnimationRunning;
     property public final boolean isClosed;
     property public final boolean isOpen;
-    property @androidx.compose.material.ExperimentalMaterialApi public final float offset;
-    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.DrawerValue targetValue;
     field public static final androidx.compose.material.DrawerState.Companion Companion;
   }
 
@@ -423,25 +257,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.material.ElevationOverlay> LocalElevationOverlay;
   }
 
-  @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterialApi {
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface ExposedDropdownMenuBoxScope {
-    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
-    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ExposedDropdownMenuDefaults {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded, optional kotlin.jvm.functions.Function0<kotlin.Unit> onIconClick);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long focusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    field public static final androidx.compose.material.ExposedDropdownMenuDefaults INSTANCE;
-  }
-
-  public final class ExposedDropdownMenuKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
-  }
-
   @kotlin.jvm.JvmInline public final value class FabPosition {
     field public static final androidx.compose.material.FabPosition.Companion Companion;
   }
@@ -453,12 +268,6 @@
     property public final int End;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FixedThreshold implements androidx.compose.material.ThresholdConfig {
-    ctor public FixedThreshold(float offset);
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-    method public androidx.compose.material.FixedThreshold copy-0680j_4(float offset);
-  }
-
   public final class FloatingActionButtonDefaults {
     method @Deprecated @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation);
     method @androidx.compose.runtime.Composable public androidx.compose.material.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float hoveredElevation, optional float focusedElevation);
@@ -474,12 +283,6 @@
     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.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.graphics.Shape shape, optional long backgroundColor, optional long contentColor, optional androidx.compose.material.FloatingActionButtonElevation elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class FractionalThreshold implements androidx.compose.material.ThresholdConfig {
-    ctor public FractionalThreshold(float fraction);
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-    method public androidx.compose.material.FractionalThreshold copy(float fraction);
-  }
-
   public final class IconButtonKt {
     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.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.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
@@ -492,15 +295,7 @@
   }
 
   public final class InteractiveComponentSizeKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumInteractiveComponentEnforcement();
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalMinimumTouchTargetEnforcement();
     method public static androidx.compose.ui.Modifier minimumInteractiveComponentSize(androidx.compose.ui.Modifier);
-    property @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumInteractiveComponentEnforcement;
-    property @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalMinimumTouchTargetEnforcement;
-  }
-
-  public final class ListItemKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ListItem(optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? icon, optional kotlin.jvm.functions.Function0<kotlin.Unit>? secondaryText, optional boolean singleLineSecondaryText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? overlineText, optional kotlin.jvm.functions.Function0<kotlin.Unit>? trailing, kotlin.jvm.functions.Function0<kotlin.Unit> text);
   }
 
   public final class MaterialTheme {
@@ -531,43 +326,6 @@
     field public static final androidx.compose.material.ModalBottomSheetDefaults INSTANCE;
   }
 
-  public final class ModalBottomSheetKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHalfExpanded);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class ModalBottomSheetState {
-    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional boolean isSkipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    ctor @Deprecated public ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method public androidx.compose.material.ModalBottomSheetValue getCurrentValue();
-    method public androidx.compose.material.ModalBottomSheetValue getTargetValue();
-    method public suspend Object? hide(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public boolean isVisible();
-    method public suspend Object? show(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final androidx.compose.material.ModalBottomSheetValue currentValue;
-    property public final boolean isVisible;
-    property public final androidx.compose.material.ModalBottomSheetValue targetValue;
-    field public static final androidx.compose.material.ModalBottomSheetState.Companion Companion;
-  }
-
-  public static final class ModalBottomSheetState.Companion {
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, boolean skipHalfExpanded, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmStateChange);
-    method @Deprecated public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded);
-    method public androidx.compose.runtime.saveable.Saver<androidx.compose.material.ModalBottomSheetState,?> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, boolean skipHalfExpanded, androidx.compose.ui.unit.Density density);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public enum ModalBottomSheetValue {
-    method public static androidx.compose.material.ModalBottomSheetValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.material.ModalBottomSheetValue[] values();
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Expanded;
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue HalfExpanded;
-    enum_constant public static final androidx.compose.material.ModalBottomSheetValue Hidden;
-  }
-
   public final class NavigationRailDefaults {
     method public float getElevation();
     property public final float Elevation;
@@ -643,12 +401,6 @@
     property public final androidx.compose.material.SnackbarHostState snackbarHostState;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi public interface SelectableChipColors {
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> backgroundColor(boolean enabled, boolean selected);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> contentColor(boolean enabled, boolean selected);
-    method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean selected);
-  }
-
   @androidx.compose.runtime.Immutable public final class Shapes {
     ctor public Shapes(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
     method public androidx.compose.material.Shapes copy(optional androidx.compose.foundation.shape.CornerBasedShape small, optional androidx.compose.foundation.shape.CornerBasedShape medium, optional androidx.compose.foundation.shape.CornerBasedShape large);
@@ -677,7 +429,6 @@
   }
 
   public final class SliderKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material.SliderColors colors);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.material.SliderColors colors);
   }
 
@@ -733,25 +484,6 @@
 
   public final class SurfaceKt {
     method @androidx.compose.runtime.Composable public static void Surface(optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @Deprecated @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.foundation.Indication? indication, optional boolean enabled, optional String? onClickLabel, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable 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 androidx.compose.foundation.BorderStroke? border, optional float elevation, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Immutable public final class SwipeProgress<T> {
-    ctor public SwipeProgress(T from, T to, float fraction);
-    method public float getFraction();
-    method public T getFrom();
-    method public T getTo();
-    property public final float fraction;
-    property public final T from;
-    property public final T to;
-  }
-
-  public final class SwipeToDismissKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material.DismissState state, optional androidx.compose.ui.Modifier modifier, optional java.util.Set<? extends androidx.compose.material.DismissDirection> directions, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissDirection,? extends androidx.compose.material.ThresholdConfig> dismissThresholds, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.DismissState rememberDismissState(optional androidx.compose.material.DismissValue initialValue, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.DismissValue,java.lang.Boolean> confirmStateChange);
   }
 
   public final class SwipeableDefaults {
@@ -765,38 +497,6 @@
     field public static final float StiffResistanceFactor = 20.0f;
   }
 
-  public final class SwipeableKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static <T> androidx.compose.material.SwipeableState<T> rememberSwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public static <T> androidx.compose.ui.Modifier swipeable(androidx.compose.ui.Modifier, androidx.compose.material.SwipeableState<T> state, java.util.Map<java.lang.Float,? extends T> anchors, androidx.compose.foundation.gestures.Orientation orientation, optional boolean enabled, optional boolean reverseDirection, optional androidx.compose.foundation.interaction.MutableInteractionSource? interactionSource, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends androidx.compose.material.ThresholdConfig> thresholds, optional androidx.compose.material.ResistanceConfig? resistance, optional float velocityThreshold);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public class SwipeableState<T> {
-    ctor public SwipeableState(T initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? animateTo(T targetValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public final T getCurrentValue();
-    method public final float getDirection();
-    method public final androidx.compose.runtime.State<java.lang.Float> getOffset();
-    method public final androidx.compose.runtime.State<java.lang.Float> getOverflow();
-    method public final androidx.compose.material.SwipeProgress<T> getProgress();
-    method public final T getTargetValue();
-    method public final boolean isAnimationRunning();
-    method public final float performDrag(float delta);
-    method public final suspend Object? performFling(float velocity, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.material.ExperimentalMaterialApi public final suspend Object? snapTo(T targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final T currentValue;
-    property @androidx.compose.material.ExperimentalMaterialApi public final float direction;
-    property public final boolean isAnimationRunning;
-    property public final androidx.compose.runtime.State<java.lang.Float> offset;
-    property public final androidx.compose.runtime.State<java.lang.Float> overflow;
-    property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.SwipeProgress<T> progress;
-    property @androidx.compose.material.ExperimentalMaterialApi public final T targetValue;
-    field public static final androidx.compose.material.SwipeableState.Companion Companion;
-  }
-
-  public static final class SwipeableState.Companion {
-    method public <T> androidx.compose.runtime.saveable.Saver<androidx.compose.material.SwipeableState<T>,T> Saver(androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> confirmStateChange);
-  }
-
   @androidx.compose.runtime.Stable public interface SwitchColors {
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> thumbColor(boolean enabled, boolean checked);
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trackColor(boolean enabled, boolean checked);
@@ -856,27 +556,15 @@
     method @androidx.compose.runtime.Composable public androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError);
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface TextFieldColorsWithIcons extends androidx.compose.material.TextFieldColors {
-    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> leadingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
-    method @androidx.compose.runtime.Composable public default androidx.compose.runtime.State<androidx.compose.ui.graphics.Color> trailingIconColor(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource);
-  }
-
   @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void BorderBox(boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional androidx.compose.ui.graphics.Shape shape, optional float focusedBorderThickness, optional float unfocusedBorderThickness);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void OutlinedTextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional kotlin.jvm.functions.Function0<kotlin.Unit> border);
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public void TextFieldDecorationBox(String value, kotlin.jvm.functions.Function0<kotlin.Unit> innerTextField, boolean enabled, boolean singleLine, androidx.compose.ui.text.input.VisualTransformation visualTransformation, androidx.compose.foundation.interaction.InteractionSource interactionSource, optional boolean isError, 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 androidx.compose.material.TextFieldColors colors, optional androidx.compose.foundation.layout.PaddingValues contentPadding);
     method public float getFocusedBorderThickness();
     method public float getMinHeight();
     method public float getMinWidth();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getOutlinedTextFieldShape();
     method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getTextFieldShape();
     method public float getUnfocusedBorderThickness();
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.ui.Modifier indicatorLine(androidx.compose.ui.Modifier, boolean enabled, boolean isError, androidx.compose.foundation.interaction.InteractionSource interactionSource, androidx.compose.material.TextFieldColors colors, optional float focusedIndicatorLineThickness, optional float unfocusedIndicatorLineThickness);
     method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues outlinedTextFieldPadding(optional float start, optional float top, optional float end, optional float bottom);
     method @androidx.compose.runtime.Composable public androidx.compose.material.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long leadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long trailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithLabelPadding(optional float start, optional float end, optional float top, optional float bottom);
-    method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.foundation.layout.PaddingValues textFieldWithoutLabelPadding(optional float start, optional float top, optional float end, optional float bottom);
     property public final float FocusedBorderThickness;
     property public final float MinHeight;
     property public final float MinWidth;
@@ -906,10 +594,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.TextStyle> LocalTextStyle;
   }
 
-  @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Stable public interface ThresholdConfig {
-    method public float computeThreshold(androidx.compose.ui.unit.Density, float fromValue, float toValue);
-  }
-
   @androidx.compose.runtime.Immutable public final class Typography {
     ctor public Typography(optional androidx.compose.ui.text.font.FontFamily defaultFontFamily, optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
     method public androidx.compose.material.Typography copy(optional androidx.compose.ui.text.TextStyle h1, optional androidx.compose.ui.text.TextStyle h2, optional androidx.compose.ui.text.TextStyle h3, optional androidx.compose.ui.text.TextStyle h4, optional androidx.compose.ui.text.TextStyle h5, optional androidx.compose.ui.text.TextStyle h6, optional androidx.compose.ui.text.TextStyle subtitle1, optional androidx.compose.ui.text.TextStyle subtitle2, optional androidx.compose.ui.text.TextStyle body1, optional androidx.compose.ui.text.TextStyle body2, optional androidx.compose.ui.text.TextStyle button, optional androidx.compose.ui.text.TextStyle caption, optional androidx.compose.ui.text.TextStyle overline);
@@ -943,37 +627,3 @@
 
 }
 
-package androidx.compose.material.pullrefresh {
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshDefaults {
-    method public float getRefreshThreshold();
-    method public float getRefreshingOffset();
-    property public final float RefreshThreshold;
-    property public final float RefreshingOffset;
-    field public static final androidx.compose.material.pullrefresh.PullRefreshDefaults INSTANCE;
-  }
-
-  public final class PullRefreshIndicatorKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void PullRefreshIndicator(boolean refreshing, androidx.compose.material.pullrefresh.PullRefreshState state, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional boolean scale);
-  }
-
-  public final class PullRefreshIndicatorTransformKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefreshIndicatorTransform(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean scale);
-  }
-
-  public final class PullRefreshKt {
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, androidx.compose.material.pullrefresh.PullRefreshState state, optional boolean enabled);
-    method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.ui.Modifier pullRefresh(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Float> onPull, kotlin.jvm.functions.Function2<? super java.lang.Float,? super kotlin.coroutines.Continuation<? super java.lang.Float>,?> onRelease, optional boolean enabled);
-  }
-
-  @androidx.compose.material.ExperimentalMaterialApi public final class PullRefreshState {
-    method public float getProgress();
-    property public final float progress;
-  }
-
-  public final class PullRefreshStateKt {
-    method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.pullrefresh.PullRefreshState rememberPullRefreshState(boolean refreshing, kotlin.jvm.functions.Function0<kotlin.Unit> onRefresh, optional float refreshThreshold, optional float refreshingOffset);
-  }
-
-}
-
diff --git a/compose/material/material/build.gradle b/compose/material/material/build.gradle
index 3019ae0..4fc4668 100644
--- a/compose/material/material/build.gradle
+++ b/compose/material/material/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -30,6 +31,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material/material/integration-tests/material-catalog/lint-baseline.xml b/compose/material/material/integration-tests/material-catalog/lint-baseline.xml
new file mode 100644
index 0000000..9bb779f
--- /dev/null
+++ b/compose/material/material/integration-tests/material-catalog/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ThemeShapeCornerSizeItem has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onValueChange: (themeShapeCornerSize: Int) -> Unit"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/material/catalog/library/ui/theme/ThemePicker.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/ui/theme/ThemePicker.kt b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/ui/theme/ThemePicker.kt
index 48730f5..c8a0638 100644
--- a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/ui/theme/ThemePicker.kt
+++ b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/ui/theme/ThemePicker.kt
@@ -373,7 +373,6 @@
     modifier: Modifier = Modifier,
     themeShapeCornerSize: Int,
     themeShapeCornerSizeMax: Int,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (themeShapeCornerSize: Int) -> Unit
 ) {
     Column(modifier = modifier) {
diff --git a/compose/material/material/integration-tests/material-demos/lint-baseline.xml b/compose/material/material/integration-tests/material-demos/lint-baseline.xml
new file mode 100644
index 0000000..a291fce
--- /dev/null
+++ b/compose/material/material/integration-tests/material-demos/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method MagnifierTransition has parameter &apos;content&apos; with type Function3&lt;? super Dp, ? super Dp, ? super Float, Unit>."
+        errorLine1="    content: @Composable (labelWidth: Dp, selectionDiameter: Dp, alpha: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
index 0efd044..a2e1d22 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
@@ -184,7 +184,6 @@
     visible: Boolean,
     maxWidth: Dp,
     maxDiameter: Dp,
-    @Suppress("PrimitiveInLambda")
     content: @Composable (labelWidth: Dp, selectionDiameter: Dp, alpha: Float) -> Unit
 ) {
     val transition = updateTransition(visible)
diff --git a/compose/material/material/lint-baseline.xml b/compose/material/material/lint-baseline.xml
index fd09ac4..d90ca3e 100644
--- a/compose/material/material/lint-baseline.xml
+++ b/compose/material/material/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -136,4 +136,328 @@
             file="src/androidAndroidTest/kotlin/androidx/compose/material/TabScreenshotTest.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="    internal val positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Float> of &apos;getPositionalThreshold$lint_module&apos;."
+        errorLine1="    internal val positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="    internal val velocityThreshold: () -> Float,"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function0&lt;Float> of &apos;getVelocityThreshold$lint_module&apos;."
+        errorLine1="    internal val velocityThreshold: () -> Float,"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="        positionalThreshold: (totalDistance: Float) -> Float,"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AnchoredDraggableState has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="        velocityThreshold: () -> Float,"
+        errorLine2="                           ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;positionalThreshold&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="            positionalThreshold: (distance: Float) -> Float,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;velocityThreshold&apos; with type Function0&lt;Float>."
+        errorLine1="            velocityThreshold: () -> Float,"
+        errorLine2="                               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BackdropStack has parameter &apos;frontLayer&apos; with type Function2&lt;? super Constraints, ? super Float, Unit>."
+        errorLine1="    frontLayer: @Composable @UiComposable (Constraints, Float) -> Unit"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomNavigationTransition has parameter &apos;content&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    content: @Composable (animationProgress: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomSheetScaffoldLayout has parameter &apos;bottomSheet&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    bottomSheet: @Composable (layoutHeight: Int) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomSheetScaffoldLayout has parameter &apos;sheetOffset&apos; with type Function0&lt;Float>."
+        errorLine1="    sheetOffset: () -> Float,"
+        errorLine2="                 ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitHorizontalPointerSlopOrCancellation has parameter &apos;onPointerSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/DragGestureDetectorCopy.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Scrim has parameter &apos;fraction&apos; with type Function0&lt;Float>."
+        errorLine1="    fraction: () -> Float,"
+        errorLine2="              ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Drawer.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method updateHeight has parameter &apos;onHeightUpdate&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onHeightUpdate: (Int) -> Unit"
+        errorLine2="                    ~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method NavigationRailTransition has parameter &apos;content&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    content: @Composable (animationProgress: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicWidth has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicHeight has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method pullRefresh has parameter &apos;onPull&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="    onPull: (pullDelta: Float) -> Float,"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method pullRefresh has parameter &apos;onRelease&apos; with type Function2&lt;? super Float, ? super Continuation&lt;? super Float>, ? extends Object>."
+        errorLine1="    onRelease: suspend (flingVelocity: Float) -> Float,"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PullRefreshNestedScrollConnection has parameter &apos;onPull&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="    private val onPull: (pullDelta: Float) -> Float,"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PullRefreshNestedScrollConnection has parameter &apos;onRelease&apos; with type Function2&lt;? super Float, ? super Continuation&lt;? super Float>, ? extends Object>."
+        errorLine1="    private val onRelease: suspend (flingVelocity: Float) -> Float,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Slider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;postPointerSlop&apos; with type Function2&lt;? super PointerInputChange, ? super Float, ? extends Unit>."
+        errorLine1="    val postPointerSlop = { pointerInput: PointerInputChange, offset: Float ->"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method CorrectValueSideEffect has parameter &apos;scaleToOffset&apos; with type Function1&lt;? super Float, Float>."
+        errorLine1="    scaleToOffset: (Float) -> Float,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method sliderSemantics has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type State&lt;Function2&lt;Boolean, Float, Unit>> of &apos;getOnDrag&apos;."
+        errorLine1="    val onDrag: State&lt;(Boolean, Float) -> Unit>,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SliderDraggableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    val onDelta: (Float) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Unit> of &apos;getOnDelta&apos;."
+        errorLine1="    val onDelta: (Float) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setThresholds$lint_module has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Float, Float, Float> of &apos;getThresholds$lint_module&apos;."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method computeTarget has parameter &apos;thresholds&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    thresholds: (Float, Float) -> Float,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SwitchImpl has parameter &apos;thumbValue&apos; with type Function0&lt;Float>."
+        errorLine1="    thumbValue: () -> Float,"
+        errorLine2="                ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/Switch.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicWidth has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/TextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicHeight has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/TextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Transition has parameter &apos;content&apos; with type Function4&lt;? super Float, ? super Color, ? super Color, ? super Float, Unit>."
+        errorLine1="        content: @Composable ("
+        errorLine2="                 ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
index c493a92..7cba51b 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
@@ -539,7 +539,6 @@
     view: View,
     coordinates: LayoutCoordinates?,
     verticalMarginInPx: Int,
-    @Suppress("PrimitiveInLambda")
     onHeightUpdate: (Int) -> Unit
 ) {
     coordinates ?: return
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
index 0f85c18..f888873 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
@@ -215,9 +215,7 @@
 @ExperimentalMaterialApi
 internal class AnchoredDraggableState<T>(
     initialValue: T,
-    @Suppress("PrimitiveInLambda")
     internal val positionalThreshold: (totalDistance: Float) -> Float,
-    @Suppress("PrimitiveInLambda")
     internal val velocityThreshold: () -> Float,
     val animationSpec: AnimationSpec<Float>,
     internal val confirmValueChange: (newValue: T) -> Boolean = { true }
@@ -244,9 +242,7 @@
     constructor(
         initialValue: T,
         anchors: DraggableAnchors<T>,
-        @Suppress("PrimitiveInLambda")
         positionalThreshold: (totalDistance: Float) -> Float,
-        @Suppress("PrimitiveInLambda")
         velocityThreshold: () -> Float,
         animationSpec: AnimationSpec<Float>,
         confirmValueChange: (newValue: T) -> Boolean = { true }
@@ -630,11 +626,8 @@
         @ExperimentalMaterialApi
         fun <T : Any> Saver(
             animationSpec: AnimationSpec<Float>,
-            @Suppress("PrimitiveInLambda")
             confirmValueChange: (T) -> Boolean,
-            @Suppress("PrimitiveInLambda")
             positionalThreshold: (distance: Float) -> Float,
-            @Suppress("PrimitiveInLambda")
             velocityThreshold: () -> Float,
         ) = Saver<AnchoredDraggableState<T>, T>(
             save = { it.currentValue },
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
index 5a79071..2caf16b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
@@ -455,7 +455,6 @@
     modifier: Modifier,
     backLayer: @Composable @UiComposable () -> Unit,
     calculateBackLayerConstraints: (Constraints) -> Constraints,
-    @Suppress("PrimitiveInLambda")
     frontLayer: @Composable @UiComposable (Constraints, Float) -> Unit
 ) {
     SubcomposeLayout(modifier) { constraints ->
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
index 780e22d..cad60b6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
@@ -223,7 +223,6 @@
     activeColor: Color,
     inactiveColor: Color,
     selected: Boolean,
-    @Suppress("PrimitiveInLambda")
     content: @Composable (animationProgress: Float) -> Unit
 ) {
     val animationProgress by animateFloatAsState(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index 1e173af..9d6279d 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -596,13 +596,11 @@
 private fun BottomSheetScaffoldLayout(
     topBar: @Composable (() -> Unit)?,
     body: @Composable (innerPadding: PaddingValues) -> Unit,
-    @Suppress("PrimitiveInLambda")
     bottomSheet: @Composable (layoutHeight: Int) -> Unit,
     floatingActionButton: (@Composable () -> Unit)?,
     snackbarHost: @Composable () -> Unit,
     sheetPeekHeight: Dp,
     floatingActionButtonPosition: FabPosition,
-    @Suppress("PrimitiveInLambda")
     sheetOffset: () -> Float,
     sheetState: BottomSheetState,
 ) {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/DragGestureDetectorCopy.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/DragGestureDetectorCopy.kt
index 35d2a68..973fdf1 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/DragGestureDetectorCopy.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/DragGestureDetectorCopy.kt
@@ -36,7 +36,6 @@
 internal suspend fun AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation(
     pointerId: PointerId,
     pointerType: PointerType,
-    @Suppress("PrimitiveInLambda")
     onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index 5a07ee2..39517e6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -824,7 +824,6 @@
 private fun Scrim(
     open: Boolean,
     onClose: () -> Unit,
-    @Suppress("PrimitiveInLambda")
     fraction: () -> Float,
     color: Color
 ) {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
index e008f4a..378d983 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/NavigationRail.kt
@@ -228,7 +228,6 @@
     activeColor: Color,
     inactiveColor: Color,
     selected: Boolean,
-    @Suppress("PrimitiveInLambda")
     content: @Composable (animationProgress: Float) -> Unit
 ) {
     val animationProgress by animateFloatAsState(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
index f219b8d..467a3d1 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
@@ -718,7 +718,6 @@
     private fun IntrinsicMeasureScope.intrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         val textFieldWidth =
@@ -751,7 +750,6 @@
     private fun IntrinsicMeasureScope.intrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         var remainingWidth = width
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
index dcd4670..3f01485 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
@@ -145,7 +145,6 @@
 @Composable
 fun Slider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
@@ -806,7 +805,6 @@
     type: PointerType
 ): Pair<PointerInputChange, Float>? {
     var initialDelta = 0f
-    @Suppress("PrimitiveInLambda")
     val postPointerSlop = { pointerInput: PointerInputChange, offset: Float ->
         pointerInput.consume()
         initialDelta = offset
@@ -833,7 +831,6 @@
 
 @Composable
 private fun CorrectValueSideEffect(
-    @Suppress("PrimitiveInLambda")
     scaleToOffset: (Float) -> Float,
     valueRange: ClosedFloatingPointRange<Float>,
     trackRange: ClosedFloatingPointRange<Float>,
@@ -854,7 +851,6 @@
 private fun Modifier.sliderSemantics(
     value: Float,
     enabled: Boolean,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     onValueChangeFinished: (() -> Unit)? = null,
     valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
@@ -1046,7 +1042,6 @@
     val endInteractionSource: MutableInteractionSource,
     val rawOffsetStart: State<Float>,
     val rawOffsetEnd: State<Float>,
-    @Suppress("PrimitiveInLambda")
     val onDrag: State<(Boolean, Float) -> Unit>,
 ) {
     fun activeInteraction(draggingStart: Boolean): MutableInteractionSource =
@@ -1168,7 +1163,6 @@
 private val SliderToTickAnimation = TweenSpec<Float>(durationMillis = 100)
 
 private class SliderDraggableState(
-    @Suppress("PrimitiveInLambda")
     val onDelta: (Float) -> Unit
 ) : DraggableState {
 
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
index db7fc60..23f3381 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
@@ -195,7 +195,6 @@
         }
     }
 
-    @Suppress("PrimitiveInLambda")
     internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
 
     internal var velocityThreshold by mutableFloatStateOf(0f)
@@ -773,7 +772,6 @@
     offset: Float,
     lastValue: Float,
     anchors: Set<Float>,
-    @Suppress("PrimitiveInLambda")
     thresholds: (Float, Float) -> Float,
     velocity: Float,
     velocityThreshold: Float
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
index b904b33..4afd313 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Switch.kt
@@ -214,7 +214,6 @@
     checked: Boolean,
     enabled: Boolean,
     colors: SwitchColors,
-    @Suppress("PrimitiveInLambda")
     thumbValue: () -> Float,
     interactionSource: InteractionSource
 ) {
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
index dd3a876..bce7a19 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextField.kt
@@ -700,7 +700,6 @@
     private fun intrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         val textFieldWidth =
@@ -730,7 +729,6 @@
     private fun IntrinsicMeasureScope.intrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         var remainingWidth = width
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
index 249094f..c947d0a 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/TextFieldImpl.kt
@@ -266,7 +266,6 @@
         unfocusedTextStyleColor: Color,
         contentColor: @Composable (InputPhase) -> Color,
         showLabel: Boolean,
-        @Suppress("PrimitiveInLambda")
         content: @Composable (
             labelProgress: Float,
             labelTextStyleColor: Color,
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
index be1243a..564d874 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefresh.kt
@@ -76,9 +76,7 @@
  */
 @ExperimentalMaterialApi
 fun Modifier.pullRefresh(
-    @Suppress("PrimitiveInLambda")
     onPull: (pullDelta: Float) -> Float,
-    @Suppress("PrimitiveInLambda")
     onRelease: suspend (flingVelocity: Float) -> Float,
     enabled: Boolean = true
 ) = inspectable(inspectorInfo = debugInspectorInfo {
@@ -91,9 +89,7 @@
 }
 
 private class PullRefreshNestedScrollConnection(
-    @Suppress("PrimitiveInLambda")
     private val onPull: (pullDelta: Float) -> Float,
-    @Suppress("PrimitiveInLambda")
     private val onRelease: suspend (flingVelocity: Float) -> Float,
     private val enabled: Boolean
 ) : NestedScrollConnection {
diff --git a/compose/material3/material3-adaptive/api/current.txt b/compose/material3/material3-adaptive/api/current.txt
index 8e01290..5716e1d 100644
--- a/compose/material3/material3-adaptive/api/current.txt
+++ b/compose/material3/material3-adaptive/api/current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.compose.material3.adaptive {
 
-  public final class AdaptiveLayoutDirective {
+  @androidx.compose.runtime.Immutable public final class AdaptiveLayoutDirective {
     ctor public AdaptiveLayoutDirective(int maxHorizontalPartitions, androidx.compose.material3.adaptive.GutterSizes gutterSizes, optional int maxVerticalPartitions);
     method public androidx.compose.material3.adaptive.GutterSizes getGutterSizes();
     method public int getMaxHorizontalPartitions();
@@ -29,7 +29,7 @@
   @kotlin.RequiresOptIn(message="This material3-adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
   }
 
-  public final class GutterSizes {
+  @androidx.compose.runtime.Immutable public final class GutterSizes {
     ctor public GutterSizes(float outerVertical, float innerVertical, optional float outerHorizontal, optional float innerHorizontal);
     method public float getInnerHorizontal();
     method public float getInnerVertical();
@@ -41,11 +41,11 @@
     property public final float outerVertical;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedState {
-    field public static final androidx.compose.material3.adaptive.PaneAdaptedState.Companion Companion;
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
+    field public static final androidx.compose.material3.adaptive.PaneAdaptedValue.Companion Companion;
   }
 
-  public static final class PaneAdaptedState.Companion {
+  public static final class PaneAdaptedValue.Companion {
     method public String getExpanded();
     method public String getHidden();
     property public final String Expanded;
@@ -56,7 +56,7 @@
     method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class Posture {
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
     ctor public Posture(optional boolean hasVerticalHinge, optional boolean isTabletop, optional boolean hasSeparatingHinge);
     method public boolean getHasSeparatingHinge();
     method public boolean getHasVerticalHinge();
@@ -84,17 +84,17 @@
     enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Tertiary;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldState {
-    ctor public ThreePaneScaffoldState(String primaryPaneAdaptedState, String secondaryPaneAdaptedState, String tertiaryPaneAdaptedState);
-    method public String getPrimaryPaneAdaptedState();
-    method public String getSecondaryPaneAdaptedState();
-    method public String getTertiaryPaneAdaptedState();
-    property public final String primaryPaneAdaptedState;
-    property public final String secondaryPaneAdaptedState;
-    property public final String tertiaryPaneAdaptedState;
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
+    ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
+    method public String getPrimary();
+    method public String getSecondary();
+    method public String getTertiary();
+    property public final String primary;
+    property public final String secondary;
+    property public final String tertiary;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class WindowAdaptiveInfo {
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
     ctor public WindowAdaptiveInfo(androidx.compose.material3.windowsizeclass.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture posture);
     method public androidx.compose.material3.adaptive.Posture getPosture();
     method public androidx.compose.material3.windowsizeclass.WindowSizeClass getWindowSizeClass();
diff --git a/compose/material3/material3-adaptive/api/restricted_current.txt b/compose/material3/material3-adaptive/api/restricted_current.txt
index 8e01290..5716e1d 100644
--- a/compose/material3/material3-adaptive/api/restricted_current.txt
+++ b/compose/material3/material3-adaptive/api/restricted_current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.compose.material3.adaptive {
 
-  public final class AdaptiveLayoutDirective {
+  @androidx.compose.runtime.Immutable public final class AdaptiveLayoutDirective {
     ctor public AdaptiveLayoutDirective(int maxHorizontalPartitions, androidx.compose.material3.adaptive.GutterSizes gutterSizes, optional int maxVerticalPartitions);
     method public androidx.compose.material3.adaptive.GutterSizes getGutterSizes();
     method public int getMaxHorizontalPartitions();
@@ -29,7 +29,7 @@
   @kotlin.RequiresOptIn(message="This material3-adaptive API is experimental and is likely to change or to be" + "removed in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterial3AdaptiveApi {
   }
 
-  public final class GutterSizes {
+  @androidx.compose.runtime.Immutable public final class GutterSizes {
     ctor public GutterSizes(float outerVertical, float innerVertical, optional float outerHorizontal, optional float innerHorizontal);
     method public float getInnerHorizontal();
     method public float getInnerVertical();
@@ -41,11 +41,11 @@
     property public final float outerVertical;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedState {
-    field public static final androidx.compose.material3.adaptive.PaneAdaptedState.Companion Companion;
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @kotlin.jvm.JvmInline public final value class PaneAdaptedValue {
+    field public static final androidx.compose.material3.adaptive.PaneAdaptedValue.Companion Companion;
   }
 
-  public static final class PaneAdaptedState.Companion {
+  public static final class PaneAdaptedValue.Companion {
     method public String getExpanded();
     method public String getHidden();
     property public final String Expanded;
@@ -56,7 +56,7 @@
     method public androidx.compose.ui.Modifier preferredWidth(androidx.compose.ui.Modifier, float width);
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class Posture {
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class Posture {
     ctor public Posture(optional boolean hasVerticalHinge, optional boolean isTabletop, optional boolean hasSeparatingHinge);
     method public boolean getHasSeparatingHinge();
     method public boolean getHasVerticalHinge();
@@ -84,17 +84,17 @@
     enum_constant public static final androidx.compose.material3.adaptive.ThreePaneScaffoldRole Tertiary;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class ThreePaneScaffoldState {
-    ctor public ThreePaneScaffoldState(String primaryPaneAdaptedState, String secondaryPaneAdaptedState, String tertiaryPaneAdaptedState);
-    method public String getPrimaryPaneAdaptedState();
-    method public String getSecondaryPaneAdaptedState();
-    method public String getTertiaryPaneAdaptedState();
-    property public final String primaryPaneAdaptedState;
-    property public final String secondaryPaneAdaptedState;
-    property public final String tertiaryPaneAdaptedState;
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class ThreePaneScaffoldValue {
+    ctor public ThreePaneScaffoldValue(String primary, String secondary, String tertiary);
+    method public String getPrimary();
+    method public String getSecondary();
+    method public String getTertiary();
+    property public final String primary;
+    property public final String secondary;
+    property public final String tertiary;
   }
 
-  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi public final class WindowAdaptiveInfo {
+  @androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi @androidx.compose.runtime.Immutable public final class WindowAdaptiveInfo {
     ctor public WindowAdaptiveInfo(androidx.compose.material3.windowsizeclass.WindowSizeClass windowSizeClass, androidx.compose.material3.adaptive.Posture posture);
     method public androidx.compose.material3.adaptive.Posture getPosture();
     method public androidx.compose.material3.windowsizeclass.WindowSizeClass getWindowSizeClass();
diff --git a/compose/material3/material3-adaptive/build.gradle b/compose/material3/material3-adaptive/build.gradle
index c7aaf75..52bb592 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/material3-adaptive/build.gradle
@@ -15,9 +15,10 @@
  */
 
 import androidx.build.AndroidXComposePlugin
-import androidx.build.LibraryType
-import androidx.build.Publish
 import androidx.build.KmpPlatformsKt
+import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
+import androidx.build.Publish
 
 plugins {
     id("AndroidXPlugin")
@@ -31,6 +32,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptiveLayoutDirective.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptiveLayoutDirective.kt
index 0b04975..e6d22cc 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptiveLayoutDirective.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/AdaptiveLayoutDirective.kt
@@ -17,6 +17,7 @@
 package androidx.compose.material3.adaptive
 
 import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
+import androidx.compose.runtime.Immutable
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 
@@ -140,6 +141,7 @@
  * Top-level directives about how an adaptive layout should be arranged and spaced, like how many
  * partitions the layout can be split into and what should be the gutter size.
  */
+@Immutable
 class AdaptiveLayoutDirective(
     /** How many partitions along the horizontal axis the respective layout can be split into. */
     val maxHorizontalPartitions: Int,
@@ -174,6 +176,7 @@
  * ([outerVertical] and [outerHorizontal]). Usually we will expect larger gutter sizes to be set
  * when the layout is larger and more panes are shown in the layout.
  */
+@Immutable
 class GutterSizes(
     /**
      * Size of the outer vertical gutters. It's similar to left/right paddings of a normal layout.
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedState.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedState.kt
deleted file mode 100644
index 42a35c7..0000000
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedState.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.adaptive
-
-/**
- * The adapted state of a pane. It gives clues to pane scaffolds about if a certain pane should be
- * composed and how.
- */
-@ExperimentalMaterial3AdaptiveApi
-@JvmInline
-value class PaneAdaptedState private constructor(private val description: String) {
-    companion object {
-        /**
-         * Denotes that the associated pane should be displayed in its full width and height.
-         */
-        val Expanded = PaneAdaptedState("Expanded")
-        /**
-         * Denotes that the associated pane should be hidden.
-         */
-        val Hidden = PaneAdaptedState("Hidden")
-    }
-}
\ No newline at end of file
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt
new file mode 100644
index 0000000..8254fe1
--- /dev/null
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/PaneAdaptedValue.kt
@@ -0,0 +1,36 @@
+/*
+ * 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.adaptive
+
+/**
+ * The adapted state of a pane. It gives clues to pane scaffolds about if a certain pane should be
+ * composed and how.
+ */
+@ExperimentalMaterial3AdaptiveApi
+@JvmInline
+value class PaneAdaptedValue private constructor(private val description: String) {
+    companion object {
+        /**
+         * Denotes that the associated pane should be displayed in its full width and height.
+         */
+        val Expanded = PaneAdaptedValue("Expanded")
+        /**
+         * Denotes that the associated pane should be hidden.
+         */
+        val Hidden = PaneAdaptedValue("Hidden")
+    }
+}
\ No newline at end of file
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
index da4686c..1e7c87e 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/Posture.kt
@@ -16,6 +16,8 @@
 
 package androidx.compose.material3.adaptive
 
+import androidx.compose.runtime.Immutable
+
 /**
  * Posture info that can help make layout adaptation decisions. For example when
  * [Posture.hasSeparatingHinge] is `true`, the layout may want to avoid putting any content over
@@ -24,6 +26,7 @@
  * default implementation.
  */
 @ExperimentalMaterial3AdaptiveApi
+@Immutable
 class Posture(
     /**
      * `true` if at least one vertical hinge is present in the middle of the current window. When
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldArrangement.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldArrangement.kt
index de525a5..eb42e5e 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldArrangement.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldArrangement.kt
@@ -22,15 +22,16 @@
  * Represents the pane order of [ThreePaneScaffold] from start to end. Note that the values of
  * [firstPane], [secondPane] and [thirdPane] have to be different, otherwise
  * [IllegalArgumentException] will be thrown.
+ *
+ * @param firstPane The first pane from the start of the [ThreePaneScaffold]
+ * @param secondPane The second pane from the start of the [ThreePaneScaffold]
+ * @param thirdPane The third pane from the start of the [ThreePaneScaffold]
  */
 @ExperimentalMaterial3AdaptiveApi
 @Immutable
 class ThreePaneScaffoldArrangement(
-    /** The first pane from the start of the [ThreePaneScaffold]. */
     val firstPane: ThreePaneScaffoldRole,
-    /** The second pane from the start of the [ThreePaneScaffold]. */
     val secondPane: ThreePaneScaffoldRole,
-    /** The third pane from the start of the [ThreePaneScaffold]. */
     val thirdPane: ThreePaneScaffoldRole
 ) {
     init {
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt
deleted file mode 100644
index 0d96f99..0000000
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldState.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.adaptive
-
-/**
- * The adapted state of [ThreePaneScaffold]. It contains each pane's adapted state.
- * [ThreePaneScaffold] will use the adapted states to decide which panes should be displayed
- * and how they should be displayed. With other input parameters of [ThreePaneScaffold] fixed,
- * each possible instance of this class should represent a unique state of [ThreePaneScaffold]
- * and developers can compare two [ThreePaneScaffoldState] to decide if there is a layout structure
- * change.
- *
- * For a Material-opinionated layout, it's suggested to use [calculateThreePaneScaffoldState] to
- * calculate the current scaffold state.
- */
-@ExperimentalMaterial3AdaptiveApi
-class ThreePaneScaffoldState(
-    /** [PaneAdaptedState] of the primary pane of [ThreePaneScaffold]. */
-    val primaryPaneAdaptedState: PaneAdaptedState,
-    /** [PaneAdaptedState] of the secondary pane of [ThreePaneScaffold]. */
-    val secondaryPaneAdaptedState: PaneAdaptedState,
-    /** [PaneAdaptedState] of the tertiary pane of [ThreePaneScaffold]. */
-    val tertiaryPaneAdaptedState: PaneAdaptedState
-) {
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        if (other !is ThreePaneScaffoldState) return false
-        if (primaryPaneAdaptedState != other.primaryPaneAdaptedState) return false
-        if (secondaryPaneAdaptedState != other.secondaryPaneAdaptedState) return false
-        if (tertiaryPaneAdaptedState != other.tertiaryPaneAdaptedState) return false
-        return true
-    }
-
-    override fun hashCode(): Int {
-        var result = primaryPaneAdaptedState.hashCode()
-        result = 31 * result + secondaryPaneAdaptedState.hashCode()
-        result = 31 * result + tertiaryPaneAdaptedState.hashCode()
-        return result
-    }
-}
\ No newline at end of file
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt
new file mode 100644
index 0000000..4bd9aea
--- /dev/null
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/ThreePaneScaffoldValue.kt
@@ -0,0 +1,58 @@
+/*
+ * 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.adaptive
+
+import androidx.compose.runtime.Immutable
+
+/**
+ * The adapted state of [ThreePaneScaffold]. It contains each pane's adapted state.
+ * [ThreePaneScaffold] will use the adapted states to decide which panes should be displayed
+ * and how they should be displayed. With other input parameters of [ThreePaneScaffold] fixed,
+ * each possible instance of this class should represent a unique state of [ThreePaneScaffold]
+ * and developers can compare two [ThreePaneScaffoldValue] to decide if there is a layout structure
+ * change.
+ *
+ * For a Material-opinionated layout, it's suggested to use [calculateThreePaneScaffoldState] to
+ * calculate the current scaffold state.
+ *
+ * @param primary [PaneAdaptedValue] of the primary pane of [ThreePaneScaffold]
+ * @param secondary [PaneAdaptedValue] of the secondary pane of [ThreePaneScaffold]
+ * @param tertiary [PaneAdaptedValue] of the tertiary pane of [ThreePaneScaffold]
+ */
+@ExperimentalMaterial3AdaptiveApi
+@Immutable
+class ThreePaneScaffoldValue(
+    val primary: PaneAdaptedValue,
+    val secondary: PaneAdaptedValue,
+    val tertiary: PaneAdaptedValue
+) {
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ThreePaneScaffoldValue) return false
+        if (primary != other.primary) return false
+        if (secondary != other.secondary) return false
+        if (tertiary != other.tertiary) return false
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = primary.hashCode()
+        result = 31 * result + secondary.hashCode()
+        result = 31 * result + tertiary.hashCode()
+        return result
+    }
+}
\ No newline at end of file
diff --git a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
index a5bdcf0..57f24cb 100644
--- a/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
+++ b/compose/material3/material3-adaptive/src/commonMain/kotlin/androidx/compose/material3/adaptive/WindowAdaptiveInfo.kt
@@ -17,12 +17,14 @@
 package androidx.compose.material3.adaptive
 
 import androidx.compose.material3.windowsizeclass.WindowSizeClass
+import androidx.compose.runtime.Immutable
 
 /**
  * This class collects window info that affects adaptation decisions. An adaptive layout is supposed
  * to use the info from this class to decide how the layout is supposed to be adapted.
  */
 @ExperimentalMaterial3AdaptiveApi
+@Immutable
 class WindowAdaptiveInfo(
     /** [WindowSizeClass] of the current window. */
     val windowSizeClass: WindowSizeClass,
diff --git a/compose/material3/material3-window-size-class/build.gradle b/compose/material3/material3-window-size-class/build.gradle
index 495dd73..4d4f79c 100644
--- a/compose/material3/material3-window-size-class/build.gradle
+++ b/compose/material3/material3-window-size-class/build.gradle
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-import androidx.build.KmpPlatformsKt
 import androidx.build.AndroidXComposePlugin
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -31,6 +31,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 3c5de3a..277177b 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -113,6 +113,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ButtonColors {
+    ctor public ButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class ButtonDefaults {
@@ -175,6 +184,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class CardColors {
+    ctor public CardColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class CardDefaults {
@@ -207,6 +225,29 @@
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
+    ctor public CheckboxColors(long checkedCheckmarkColor, long uncheckedCheckmarkColor, long checkedBoxColor, long uncheckedBoxColor, long disabledCheckedBoxColor, long disabledUncheckedBoxColor, long disabledIndeterminateBoxColor, long checkedBorderColor, long uncheckedBorderColor, long disabledBorderColor, long disabledIndeterminateBorderColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedBoxColor();
+    method public long getCheckedCheckmarkColor();
+    method public long getDisabledBorderColor();
+    method public long getDisabledCheckedBoxColor();
+    method public long getDisabledIndeterminateBorderColor();
+    method public long getDisabledIndeterminateBoxColor();
+    method public long getDisabledUncheckedBoxColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedBoxColor();
+    method public long getUncheckedCheckmarkColor();
+    property public final long checkedBorderColor;
+    property public final long checkedBoxColor;
+    property public final long checkedCheckmarkColor;
+    property public final long disabledBorderColor;
+    property public final long disabledCheckedBoxColor;
+    property public final long disabledIndeterminateBorderColor;
+    property public final long disabledIndeterminateBoxColor;
+    property public final long disabledUncheckedBoxColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedBoxColor;
+    property public final long uncheckedCheckmarkColor;
   }
 
   public final class CheckboxDefaults {
@@ -223,6 +264,23 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ChipColors {
+    ctor public ChipColors(long containerColor, long labelColor, long leadingIconContentColor, long trailingIconContentColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconContentColor, long disabledTrailingIconContentColor);
+    method public long getContainerColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconContentColor();
+    method public long getDisabledTrailingIconContentColor();
+    method public long getLabelColor();
+    method public long getLeadingIconContentColor();
+    method public long getTrailingIconContentColor();
+    property public final long containerColor;
+    property public final long disabledContainerColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconContentColor;
+    property public final long disabledTrailingIconContentColor;
+    property public final long labelColor;
+    property public final long leadingIconContentColor;
+    property public final long trailingIconContentColor;
   }
 
   @androidx.compose.runtime.Immutable public final class ChipElevation {
@@ -335,6 +393,57 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerColors {
+    ctor public DatePickerColors(long containerColor, long titleContentColor, long headlineContentColor, long weekdayContentColor, long subheadContentColor, long navigationContentColor, long yearContentColor, long disabledYearContentColor, long currentYearContentColor, long selectedYearContentColor, long disabledSelectedYearContentColor, long selectedYearContainerColor, long disabledSelectedYearContainerColor, long dayContentColor, long disabledDayContentColor, long selectedDayContentColor, long disabledSelectedDayContentColor, long selectedDayContainerColor, long disabledSelectedDayContainerColor, long todayContentColor, long todayDateBorderColor, long dayInSelectionRangeContainerColor, long dayInSelectionRangeContentColor, long dividerColor, androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public long getContainerColor();
+    method public long getCurrentYearContentColor();
+    method public androidx.compose.material3.TextFieldColors getDateTextFieldColors();
+    method public long getDayContentColor();
+    method public long getDayInSelectionRangeContainerColor();
+    method public long getDayInSelectionRangeContentColor();
+    method public long getDisabledDayContentColor();
+    method public long getDisabledSelectedDayContainerColor();
+    method public long getDisabledSelectedDayContentColor();
+    method public long getDisabledSelectedYearContainerColor();
+    method public long getDisabledSelectedYearContentColor();
+    method public long getDisabledYearContentColor();
+    method public long getDividerColor();
+    method public long getHeadlineContentColor();
+    method public long getNavigationContentColor();
+    method public long getSelectedDayContainerColor();
+    method public long getSelectedDayContentColor();
+    method public long getSelectedYearContainerColor();
+    method public long getSelectedYearContentColor();
+    method public long getSubheadContentColor();
+    method public long getTitleContentColor();
+    method public long getTodayContentColor();
+    method public long getTodayDateBorderColor();
+    method public long getWeekdayContentColor();
+    method public long getYearContentColor();
+    property public final long containerColor;
+    property public final long currentYearContentColor;
+    property public final androidx.compose.material3.TextFieldColors dateTextFieldColors;
+    property public final long dayContentColor;
+    property public final long dayInSelectionRangeContainerColor;
+    property public final long dayInSelectionRangeContentColor;
+    property public final long disabledDayContentColor;
+    property public final long disabledSelectedDayContainerColor;
+    property public final long disabledSelectedDayContentColor;
+    property public final long disabledSelectedYearContainerColor;
+    property public final long disabledSelectedYearContentColor;
+    property public final long disabledYearContentColor;
+    property public final long dividerColor;
+    property public final long headlineContentColor;
+    property public final long navigationContentColor;
+    property public final long selectedDayContainerColor;
+    property public final long selectedDayContentColor;
+    property public final long selectedYearContainerColor;
+    property public final long selectedYearContentColor;
+    property public final long subheadContentColor;
+    property public final long titleContentColor;
+    property public final long todayContentColor;
+    property public final long todayDateBorderColor;
+    property public final long weekdayContentColor;
+    property public final long yearContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerDefaults {
@@ -613,6 +722,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class IconButtonColors {
+    ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class IconButtonDefaults {
@@ -651,6 +769,19 @@
   }
 
   @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+    ctor public IconToggleButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor, long checkedContainerColor, long checkedContentColor);
+    method public long getCheckedContainerColor();
+    method public long getCheckedContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long checkedContainerColor;
+    property public final long checkedContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api public final class InputChipDefaults {
@@ -677,6 +808,25 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ListItemColors {
+    ctor public ListItemColors(long containerColor, long headlineColor, long leadingIconColor, long overlineColor, long supportingTextColor, long trailingIconColor, long disabledHeadlineColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getContainerColor();
+    method public long getDisabledHeadlineColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getHeadlineColor();
+    method public long getLeadingIconColor();
+    method public long getOverlineColor();
+    method public long getSupportingTextColor();
+    method public long getTrailingIconColor();
+    property public final long containerColor;
+    property public final long disabledHeadlineColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTrailingIconColor;
+    property public final long headlineColor;
+    property public final long leadingIconColor;
+    property public final long overlineColor;
+    property public final long supportingTextColor;
+    property public final long trailingIconColor;
   }
 
   public final class ListItemDefaults {
@@ -718,6 +868,19 @@
   }
 
   @androidx.compose.runtime.Immutable public final class MenuItemColors {
+    ctor public MenuItemColors(long textColor, long leadingIconColor, long trailingIconColor, long disabledTextColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getLeadingIconColor();
+    method public long getTextColor();
+    method public long getTrailingIconColor();
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long leadingIconColor;
+    property public final long textColor;
+    property public final long trailingIconColor;
   }
 
   public final class ModalBottomSheet_androidKt {
@@ -736,6 +899,21 @@
   }
 
   @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+    ctor public NavigationBarItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
   }
 
   public final class NavigationBarItemDefaults {
@@ -783,6 +961,21 @@
   }
 
   @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+    ctor public NavigationRailItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
   }
 
   public final class NavigationRailItemDefaults {
@@ -858,6 +1051,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+    ctor public RadioButtonColors(long selectedColor, long unselectedColor, long disabledSelectedColor, long disabledUnselectedColor);
+    method public long getDisabledSelectedColor();
+    method public long getDisabledUnselectedColor();
+    method public long getSelectedColor();
+    method public long getUnselectedColor();
+    property public final long disabledSelectedColor;
+    property public final long disabledUnselectedColor;
+    property public final long selectedColor;
+    property public final long unselectedColor;
   }
 
   public final class RadioButtonDefaults {
@@ -869,6 +1071,23 @@
     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);
   }
 
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
+    ctor public RangeSliderState(optional float initialActiveRangeStart, optional float initialActiveRangeEnd, optional kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit>? initialOnValueChange, optional int steps, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished);
+    method public float getActiveRangeEnd();
+    method public float getActiveRangeStart();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setActiveRangeEnd(float);
+    method public void setActiveRangeStart(float);
+    method public void setOnValueChangeFinished(kotlin.jvm.functions.Function0<kotlin.Unit>?);
+    property public final float activeRangeEnd;
+    property public final float activeRangeStart;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @androidx.compose.runtime.Stable public final class RichTooltipColors {
     ctor public RichTooltipColors(long containerColor, long contentColor, long titleContentColor, long actionContentColor);
     method public long getActionContentColor();
@@ -937,9 +1156,22 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipColors {
+    ctor public SelectableChipColors(long containerColor, long labelColor, long leadingIconColor, long trailingIconColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconColor, long disabledTrailingIconColor, long selectedContainerColor, long disabledSelectedContainerColor, long selectedLabelColor, long selectedLeadingIconColor, long selectedTrailingIconColor);
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableDates {
@@ -1009,10 +1241,32 @@
   }
 
   @androidx.compose.runtime.Immutable public final class SliderColors {
+    ctor public SliderColors(long thumbColor, long activeTrackColor, long activeTickColor, long inactiveTrackColor, long inactiveTickColor, long disabledThumbColor, long disabledActiveTrackColor, long disabledActiveTickColor, long disabledInactiveTrackColor, long disabledInactiveTickColor);
+    method public long getActiveTickColor();
+    method public long getActiveTrackColor();
+    method public long getDisabledActiveTickColor();
+    method public long getDisabledActiveTrackColor();
+    method public long getDisabledInactiveTickColor();
+    method public long getDisabledInactiveTrackColor();
+    method public long getDisabledThumbColor();
+    method public long getInactiveTickColor();
+    method public long getInactiveTrackColor();
+    method public long getThumbColor();
+    property public final long activeTickColor;
+    property public final long activeTrackColor;
+    property public final long disabledActiveTickColor;
+    property public final long disabledActiveTrackColor;
+    property public final long disabledInactiveTickColor;
+    property public final long disabledInactiveTrackColor;
+    property public final long disabledThumbColor;
+    property public final long inactiveTickColor;
+    property public final long inactiveTrackColor;
+    property public final long thumbColor;
   }
 
   @androidx.compose.runtime.Stable public final class SliderDefaults {
     method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.RangeSliderState rangeSliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderState sliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
@@ -1020,8 +1274,9 @@
   }
 
   public final class SliderKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(androidx.compose.material3.RangeSliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track);
     method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
-    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> track, optional int steps);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track, optional int steps);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(androidx.compose.material3.SliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional int steps, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
@@ -1151,6 +1406,39 @@
   }
 
   @androidx.compose.runtime.Immutable public final class SwitchColors {
+    ctor public SwitchColors(long checkedThumbColor, long checkedTrackColor, long checkedBorderColor, long checkedIconColor, long uncheckedThumbColor, long uncheckedTrackColor, long uncheckedBorderColor, long uncheckedIconColor, long disabledCheckedThumbColor, long disabledCheckedTrackColor, long disabledCheckedBorderColor, long disabledCheckedIconColor, long disabledUncheckedThumbColor, long disabledUncheckedTrackColor, long disabledUncheckedBorderColor, long disabledUncheckedIconColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedIconColor();
+    method public long getCheckedThumbColor();
+    method public long getCheckedTrackColor();
+    method public long getDisabledCheckedBorderColor();
+    method public long getDisabledCheckedIconColor();
+    method public long getDisabledCheckedThumbColor();
+    method public long getDisabledCheckedTrackColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedIconColor();
+    method public long getDisabledUncheckedThumbColor();
+    method public long getDisabledUncheckedTrackColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedIconColor();
+    method public long getUncheckedThumbColor();
+    method public long getUncheckedTrackColor();
+    property public final long checkedBorderColor;
+    property public final long checkedIconColor;
+    property public final long checkedThumbColor;
+    property public final long checkedTrackColor;
+    property public final long disabledCheckedBorderColor;
+    property public final long disabledCheckedIconColor;
+    property public final long disabledCheckedThumbColor;
+    property public final long disabledCheckedTrackColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedIconColor;
+    property public final long disabledUncheckedThumbColor;
+    property public final long disabledUncheckedTrackColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedIconColor;
+    property public final long uncheckedThumbColor;
+    property public final long uncheckedTrackColor;
   }
 
   public final class SwitchDefaults {
@@ -1199,6 +1487,93 @@
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldColors {
+    ctor public TextFieldColors(long focusedTextColor, long unfocusedTextColor, long disabledTextColor, long errorTextColor, long focusedContainerColor, long unfocusedContainerColor, long disabledContainerColor, long errorContainerColor, long cursorColor, long errorCursorColor, androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors, long focusedIndicatorColor, long unfocusedIndicatorColor, long disabledIndicatorColor, long errorIndicatorColor, long focusedLeadingIconColor, long unfocusedLeadingIconColor, long disabledLeadingIconColor, long errorLeadingIconColor, long focusedTrailingIconColor, long unfocusedTrailingIconColor, long disabledTrailingIconColor, long errorTrailingIconColor, long focusedLabelColor, long unfocusedLabelColor, long disabledLabelColor, long errorLabelColor, long focusedPlaceholderColor, long unfocusedPlaceholderColor, long disabledPlaceholderColor, long errorPlaceholderColor, long focusedSupportingTextColor, long unfocusedSupportingTextColor, long disabledSupportingTextColor, long errorSupportingTextColor, long focusedPrefixColor, long unfocusedPrefixColor, long disabledPrefixColor, long errorPrefixColor, long focusedSuffixColor, long unfocusedSuffixColor, long disabledSuffixColor, long errorSuffixColor);
+    method public long getCursorColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledIndicatorColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledPlaceholderColor();
+    method public long getDisabledPrefixColor();
+    method public long getDisabledSuffixColor();
+    method public long getDisabledSupportingTextColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getErrorContainerColor();
+    method public long getErrorCursorColor();
+    method public long getErrorIndicatorColor();
+    method public long getErrorLabelColor();
+    method public long getErrorLeadingIconColor();
+    method public long getErrorPlaceholderColor();
+    method public long getErrorPrefixColor();
+    method public long getErrorSuffixColor();
+    method public long getErrorSupportingTextColor();
+    method public long getErrorTextColor();
+    method public long getErrorTrailingIconColor();
+    method public long getFocusedContainerColor();
+    method public long getFocusedIndicatorColor();
+    method public long getFocusedLabelColor();
+    method public long getFocusedLeadingIconColor();
+    method public long getFocusedPlaceholderColor();
+    method public long getFocusedPrefixColor();
+    method public long getFocusedSuffixColor();
+    method public long getFocusedSupportingTextColor();
+    method public long getFocusedTextColor();
+    method public long getFocusedTrailingIconColor();
+    method public androidx.compose.foundation.text.selection.TextSelectionColors getTextSelectionColors();
+    method public long getUnfocusedContainerColor();
+    method public long getUnfocusedIndicatorColor();
+    method public long getUnfocusedLabelColor();
+    method public long getUnfocusedLeadingIconColor();
+    method public long getUnfocusedPlaceholderColor();
+    method public long getUnfocusedPrefixColor();
+    method public long getUnfocusedSuffixColor();
+    method public long getUnfocusedSupportingTextColor();
+    method public long getUnfocusedTextColor();
+    method public long getUnfocusedTrailingIconColor();
+    property public final long cursorColor;
+    property public final long disabledContainerColor;
+    property public final long disabledIndicatorColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledPlaceholderColor;
+    property public final long disabledPrefixColor;
+    property public final long disabledSuffixColor;
+    property public final long disabledSupportingTextColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long errorContainerColor;
+    property public final long errorCursorColor;
+    property public final long errorIndicatorColor;
+    property public final long errorLabelColor;
+    property public final long errorLeadingIconColor;
+    property public final long errorPlaceholderColor;
+    property public final long errorPrefixColor;
+    property public final long errorSuffixColor;
+    property public final long errorSupportingTextColor;
+    property public final long errorTextColor;
+    property public final long errorTrailingIconColor;
+    property public final long focusedContainerColor;
+    property public final long focusedIndicatorColor;
+    property public final long focusedLabelColor;
+    property public final long focusedLeadingIconColor;
+    property public final long focusedPlaceholderColor;
+    property public final long focusedPrefixColor;
+    property public final long focusedSuffixColor;
+    property public final long focusedSupportingTextColor;
+    property public final long focusedTextColor;
+    property public final long focusedTrailingIconColor;
+    property public final androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors;
+    property public final long unfocusedContainerColor;
+    property public final long unfocusedIndicatorColor;
+    property public final long unfocusedLabelColor;
+    property public final long unfocusedLeadingIconColor;
+    property public final long unfocusedPlaceholderColor;
+    property public final long unfocusedPrefixColor;
+    property public final long unfocusedSuffixColor;
+    property public final long unfocusedSupportingTextColor;
+    property public final long unfocusedTextColor;
+    property public final long unfocusedTrailingIconColor;
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
@@ -1260,6 +1635,35 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TimePickerColors {
+    ctor public TimePickerColors(long clockDialColor, long selectorColor, long containerColor, long periodSelectorBorderColor, long clockDialSelectedContentColor, long clockDialUnselectedContentColor, long periodSelectorSelectedContainerColor, long periodSelectorUnselectedContainerColor, long periodSelectorSelectedContentColor, long periodSelectorUnselectedContentColor, long timeSelectorSelectedContainerColor, long timeSelectorUnselectedContainerColor, long timeSelectorSelectedContentColor, long timeSelectorUnselectedContentColor);
+    method public long getClockDialColor();
+    method public long getClockDialSelectedContentColor();
+    method public long getClockDialUnselectedContentColor();
+    method public long getContainerColor();
+    method public long getPeriodSelectorBorderColor();
+    method public long getPeriodSelectorSelectedContainerColor();
+    method public long getPeriodSelectorSelectedContentColor();
+    method public long getPeriodSelectorUnselectedContainerColor();
+    method public long getPeriodSelectorUnselectedContentColor();
+    method public long getSelectorColor();
+    method public long getTimeSelectorSelectedContainerColor();
+    method public long getTimeSelectorSelectedContentColor();
+    method public long getTimeSelectorUnselectedContainerColor();
+    method public long getTimeSelectorUnselectedContentColor();
+    property public final long clockDialColor;
+    property public final long clockDialSelectedContentColor;
+    property public final long clockDialUnselectedContentColor;
+    property public final long containerColor;
+    property public final long periodSelectorBorderColor;
+    property public final long periodSelectorSelectedContainerColor;
+    property public final long periodSelectorSelectedContentColor;
+    property public final long periodSelectorUnselectedContainerColor;
+    property public final long periodSelectorUnselectedContentColor;
+    property public final long selectorColor;
+    property public final long timeSelectorSelectedContainerColor;
+    property public final long timeSelectorSelectedContentColor;
+    property public final long timeSelectorUnselectedContainerColor;
+    property public final long timeSelectorUnselectedContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerDefaults {
@@ -1336,6 +1740,17 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
+    ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
+    method public long getActionIconContentColor();
+    method public long getContainerColor();
+    method public long getNavigationIconContentColor();
+    method public long getScrolledContainerColor();
+    method public long getTitleContentColor();
+    property public final long actionIconContentColor;
+    property public final long containerColor;
+    property public final long navigationIconContentColor;
+    property public final long scrolledContainerColor;
+    property public final long titleContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api public final class TopAppBarDefaults {
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 3c5de3a..277177b 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -113,6 +113,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ButtonColors {
+    ctor public ButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class ButtonDefaults {
@@ -175,6 +184,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class CardColors {
+    ctor public CardColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class CardDefaults {
@@ -207,6 +225,29 @@
   }
 
   @androidx.compose.runtime.Immutable public final class CheckboxColors {
+    ctor public CheckboxColors(long checkedCheckmarkColor, long uncheckedCheckmarkColor, long checkedBoxColor, long uncheckedBoxColor, long disabledCheckedBoxColor, long disabledUncheckedBoxColor, long disabledIndeterminateBoxColor, long checkedBorderColor, long uncheckedBorderColor, long disabledBorderColor, long disabledIndeterminateBorderColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedBoxColor();
+    method public long getCheckedCheckmarkColor();
+    method public long getDisabledBorderColor();
+    method public long getDisabledCheckedBoxColor();
+    method public long getDisabledIndeterminateBorderColor();
+    method public long getDisabledIndeterminateBoxColor();
+    method public long getDisabledUncheckedBoxColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedBoxColor();
+    method public long getUncheckedCheckmarkColor();
+    property public final long checkedBorderColor;
+    property public final long checkedBoxColor;
+    property public final long checkedCheckmarkColor;
+    property public final long disabledBorderColor;
+    property public final long disabledCheckedBoxColor;
+    property public final long disabledIndeterminateBorderColor;
+    property public final long disabledIndeterminateBoxColor;
+    property public final long disabledUncheckedBoxColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedBoxColor;
+    property public final long uncheckedCheckmarkColor;
   }
 
   public final class CheckboxDefaults {
@@ -223,6 +264,23 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ChipColors {
+    ctor public ChipColors(long containerColor, long labelColor, long leadingIconContentColor, long trailingIconContentColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconContentColor, long disabledTrailingIconContentColor);
+    method public long getContainerColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconContentColor();
+    method public long getDisabledTrailingIconContentColor();
+    method public long getLabelColor();
+    method public long getLeadingIconContentColor();
+    method public long getTrailingIconContentColor();
+    property public final long containerColor;
+    property public final long disabledContainerColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconContentColor;
+    property public final long disabledTrailingIconContentColor;
+    property public final long labelColor;
+    property public final long leadingIconContentColor;
+    property public final long trailingIconContentColor;
   }
 
   @androidx.compose.runtime.Immutable public final class ChipElevation {
@@ -335,6 +393,57 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class DatePickerColors {
+    ctor public DatePickerColors(long containerColor, long titleContentColor, long headlineContentColor, long weekdayContentColor, long subheadContentColor, long navigationContentColor, long yearContentColor, long disabledYearContentColor, long currentYearContentColor, long selectedYearContentColor, long disabledSelectedYearContentColor, long selectedYearContainerColor, long disabledSelectedYearContainerColor, long dayContentColor, long disabledDayContentColor, long selectedDayContentColor, long disabledSelectedDayContentColor, long selectedDayContainerColor, long disabledSelectedDayContainerColor, long todayContentColor, long todayDateBorderColor, long dayInSelectionRangeContainerColor, long dayInSelectionRangeContentColor, long dividerColor, androidx.compose.material3.TextFieldColors dateTextFieldColors);
+    method public long getContainerColor();
+    method public long getCurrentYearContentColor();
+    method public androidx.compose.material3.TextFieldColors getDateTextFieldColors();
+    method public long getDayContentColor();
+    method public long getDayInSelectionRangeContainerColor();
+    method public long getDayInSelectionRangeContentColor();
+    method public long getDisabledDayContentColor();
+    method public long getDisabledSelectedDayContainerColor();
+    method public long getDisabledSelectedDayContentColor();
+    method public long getDisabledSelectedYearContainerColor();
+    method public long getDisabledSelectedYearContentColor();
+    method public long getDisabledYearContentColor();
+    method public long getDividerColor();
+    method public long getHeadlineContentColor();
+    method public long getNavigationContentColor();
+    method public long getSelectedDayContainerColor();
+    method public long getSelectedDayContentColor();
+    method public long getSelectedYearContainerColor();
+    method public long getSelectedYearContentColor();
+    method public long getSubheadContentColor();
+    method public long getTitleContentColor();
+    method public long getTodayContentColor();
+    method public long getTodayDateBorderColor();
+    method public long getWeekdayContentColor();
+    method public long getYearContentColor();
+    property public final long containerColor;
+    property public final long currentYearContentColor;
+    property public final androidx.compose.material3.TextFieldColors dateTextFieldColors;
+    property public final long dayContentColor;
+    property public final long dayInSelectionRangeContainerColor;
+    property public final long dayInSelectionRangeContentColor;
+    property public final long disabledDayContentColor;
+    property public final long disabledSelectedDayContainerColor;
+    property public final long disabledSelectedDayContentColor;
+    property public final long disabledSelectedYearContainerColor;
+    property public final long disabledSelectedYearContentColor;
+    property public final long disabledYearContentColor;
+    property public final long dividerColor;
+    property public final long headlineContentColor;
+    property public final long navigationContentColor;
+    property public final long selectedDayContainerColor;
+    property public final long selectedDayContentColor;
+    property public final long selectedYearContainerColor;
+    property public final long selectedYearContentColor;
+    property public final long subheadContentColor;
+    property public final long titleContentColor;
+    property public final long todayContentColor;
+    property public final long todayDateBorderColor;
+    property public final long weekdayContentColor;
+    property public final long yearContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class DatePickerDefaults {
@@ -613,6 +722,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class IconButtonColors {
+    ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   public final class IconButtonDefaults {
@@ -651,6 +769,19 @@
   }
 
   @androidx.compose.runtime.Immutable public final class IconToggleButtonColors {
+    ctor public IconToggleButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor, long checkedContainerColor, long checkedContentColor);
+    method public long getCheckedContainerColor();
+    method public long getCheckedContentColor();
+    method public long getContainerColor();
+    method public long getContentColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledContentColor();
+    property public final long checkedContainerColor;
+    property public final long checkedContentColor;
+    property public final long containerColor;
+    property public final long contentColor;
+    property public final long disabledContainerColor;
+    property public final long disabledContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api public final class InputChipDefaults {
@@ -677,6 +808,25 @@
   }
 
   @androidx.compose.runtime.Immutable public final class ListItemColors {
+    ctor public ListItemColors(long containerColor, long headlineColor, long leadingIconColor, long overlineColor, long supportingTextColor, long trailingIconColor, long disabledHeadlineColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getContainerColor();
+    method public long getDisabledHeadlineColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getHeadlineColor();
+    method public long getLeadingIconColor();
+    method public long getOverlineColor();
+    method public long getSupportingTextColor();
+    method public long getTrailingIconColor();
+    property public final long containerColor;
+    property public final long disabledHeadlineColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTrailingIconColor;
+    property public final long headlineColor;
+    property public final long leadingIconColor;
+    property public final long overlineColor;
+    property public final long supportingTextColor;
+    property public final long trailingIconColor;
   }
 
   public final class ListItemDefaults {
@@ -718,6 +868,19 @@
   }
 
   @androidx.compose.runtime.Immutable public final class MenuItemColors {
+    ctor public MenuItemColors(long textColor, long leadingIconColor, long trailingIconColor, long disabledTextColor, long disabledLeadingIconColor, long disabledTrailingIconColor);
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getLeadingIconColor();
+    method public long getTextColor();
+    method public long getTrailingIconColor();
+    property public final long disabledLeadingIconColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long leadingIconColor;
+    property public final long textColor;
+    property public final long trailingIconColor;
   }
 
   public final class ModalBottomSheet_androidKt {
@@ -736,6 +899,21 @@
   }
 
   @androidx.compose.runtime.Stable public final class NavigationBarItemColors {
+    ctor public NavigationBarItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
   }
 
   public final class NavigationBarItemDefaults {
@@ -783,6 +961,21 @@
   }
 
   @androidx.compose.runtime.Stable public final class NavigationRailItemColors {
+    ctor public NavigationRailItemColors(long selectedIconColor, long selectedTextColor, long selectedIndicatorColor, long unselectedIconColor, long unselectedTextColor, long disabledIconColor, long disabledTextColor);
+    method public long getDisabledIconColor();
+    method public long getDisabledTextColor();
+    method public long getSelectedIconColor();
+    method public long getSelectedIndicatorColor();
+    method public long getSelectedTextColor();
+    method public long getUnselectedIconColor();
+    method public long getUnselectedTextColor();
+    property public final long disabledIconColor;
+    property public final long disabledTextColor;
+    property public final long selectedIconColor;
+    property public final long selectedIndicatorColor;
+    property public final long selectedTextColor;
+    property public final long unselectedIconColor;
+    property public final long unselectedTextColor;
   }
 
   public final class NavigationRailItemDefaults {
@@ -858,6 +1051,15 @@
   }
 
   @androidx.compose.runtime.Immutable public final class RadioButtonColors {
+    ctor public RadioButtonColors(long selectedColor, long unselectedColor, long disabledSelectedColor, long disabledUnselectedColor);
+    method public long getDisabledSelectedColor();
+    method public long getDisabledUnselectedColor();
+    method public long getSelectedColor();
+    method public long getUnselectedColor();
+    property public final long disabledSelectedColor;
+    property public final long disabledUnselectedColor;
+    property public final long selectedColor;
+    property public final long unselectedColor;
   }
 
   public final class RadioButtonDefaults {
@@ -869,6 +1071,23 @@
     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);
   }
 
+  @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class RangeSliderState {
+    ctor public RangeSliderState(optional float initialActiveRangeStart, optional float initialActiveRangeEnd, optional kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit>? initialOnValueChange, optional int steps, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished);
+    method public float getActiveRangeEnd();
+    method public float getActiveRangeStart();
+    method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnValueChangeFinished();
+    method public int getSteps();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getValueRange();
+    method public void setActiveRangeEnd(float);
+    method public void setActiveRangeStart(float);
+    method public void setOnValueChangeFinished(kotlin.jvm.functions.Function0<kotlin.Unit>?);
+    property public final float activeRangeEnd;
+    property public final float activeRangeStart;
+    property public final kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished;
+    property public final int steps;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange;
+  }
+
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable @androidx.compose.runtime.Stable public final class RichTooltipColors {
     ctor public RichTooltipColors(long containerColor, long contentColor, long titleContentColor, long actionContentColor);
     method public long getActionContentColor();
@@ -937,9 +1156,22 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipColors {
+    ctor public SelectableChipColors(long containerColor, long labelColor, long leadingIconColor, long trailingIconColor, long disabledContainerColor, long disabledLabelColor, long disabledLeadingIconColor, long disabledTrailingIconColor, long selectedContainerColor, long disabledSelectedContainerColor, long selectedLabelColor, long selectedLeadingIconColor, long selectedTrailingIconColor);
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class SelectableChipElevation {
+    method public float getDisabledElevation();
+    method public float getDraggedElevation();
+    method public float getElevation();
+    method public float getFocusedElevation();
+    method public float getHoveredElevation();
+    method public float getPressedElevation();
+    property public final float disabledElevation;
+    property public final float draggedElevation;
+    property public final float elevation;
+    property public final float focusedElevation;
+    property public final float hoveredElevation;
+    property public final float pressedElevation;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public interface SelectableDates {
@@ -1009,10 +1241,32 @@
   }
 
   @androidx.compose.runtime.Immutable public final class SliderColors {
+    ctor public SliderColors(long thumbColor, long activeTrackColor, long activeTickColor, long inactiveTrackColor, long inactiveTickColor, long disabledThumbColor, long disabledActiveTrackColor, long disabledActiveTickColor, long disabledInactiveTrackColor, long disabledInactiveTickColor);
+    method public long getActiveTickColor();
+    method public long getActiveTrackColor();
+    method public long getDisabledActiveTickColor();
+    method public long getDisabledActiveTrackColor();
+    method public long getDisabledInactiveTickColor();
+    method public long getDisabledInactiveTrackColor();
+    method public long getDisabledThumbColor();
+    method public long getInactiveTickColor();
+    method public long getInactiveTrackColor();
+    method public long getThumbColor();
+    property public final long activeTickColor;
+    property public final long activeTrackColor;
+    property public final long disabledActiveTickColor;
+    property public final long disabledActiveTrackColor;
+    property public final long disabledInactiveTickColor;
+    property public final long disabledInactiveTrackColor;
+    property public final long disabledThumbColor;
+    property public final long inactiveTickColor;
+    property public final long inactiveTrackColor;
+    property public final long thumbColor;
   }
 
   @androidx.compose.runtime.Stable public final class SliderDefaults {
     method @androidx.compose.runtime.Composable public void Thumb(androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled, optional long thumbSize);
+    method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.RangeSliderState rangeSliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderPositions sliderPositions, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void Track(androidx.compose.material3.SliderState sliderState, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material3.SliderColors colors, optional boolean enabled);
     method @androidx.compose.runtime.Composable public androidx.compose.material3.SliderColors colors(optional long thumbColor, optional long activeTrackColor, optional long activeTickColor, optional long inactiveTrackColor, optional long inactiveTickColor, optional long disabledThumbColor, optional long disabledActiveTrackColor, optional long disabledActiveTickColor, optional long disabledInactiveTrackColor, optional long disabledInactiveTickColor);
@@ -1020,8 +1274,9 @@
   }
 
   public final class SliderKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(androidx.compose.material3.RangeSliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track);
     method @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors);
-    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderPositions,kotlin.Unit> track, optional int steps);
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RangeSlider(kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> value, kotlin.jvm.functions.Function1<? super kotlin.ranges.ClosedFloatingPointRange<java.lang.Float>,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource startInteractionSource, optional androidx.compose.foundation.interaction.MutableInteractionSource endInteractionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> startThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> endThumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.RangeSliderState,kotlin.Unit> track, optional int steps);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(androidx.compose.material3.SliderState state, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track);
     method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional int steps, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> thumb, optional kotlin.jvm.functions.Function1<? super androidx.compose.material3.SliderState,kotlin.Unit> track, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange);
     method @androidx.compose.runtime.Composable public static void Slider(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional int steps, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onValueChangeFinished, optional androidx.compose.material3.SliderColors colors, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource);
@@ -1151,6 +1406,39 @@
   }
 
   @androidx.compose.runtime.Immutable public final class SwitchColors {
+    ctor public SwitchColors(long checkedThumbColor, long checkedTrackColor, long checkedBorderColor, long checkedIconColor, long uncheckedThumbColor, long uncheckedTrackColor, long uncheckedBorderColor, long uncheckedIconColor, long disabledCheckedThumbColor, long disabledCheckedTrackColor, long disabledCheckedBorderColor, long disabledCheckedIconColor, long disabledUncheckedThumbColor, long disabledUncheckedTrackColor, long disabledUncheckedBorderColor, long disabledUncheckedIconColor);
+    method public long getCheckedBorderColor();
+    method public long getCheckedIconColor();
+    method public long getCheckedThumbColor();
+    method public long getCheckedTrackColor();
+    method public long getDisabledCheckedBorderColor();
+    method public long getDisabledCheckedIconColor();
+    method public long getDisabledCheckedThumbColor();
+    method public long getDisabledCheckedTrackColor();
+    method public long getDisabledUncheckedBorderColor();
+    method public long getDisabledUncheckedIconColor();
+    method public long getDisabledUncheckedThumbColor();
+    method public long getDisabledUncheckedTrackColor();
+    method public long getUncheckedBorderColor();
+    method public long getUncheckedIconColor();
+    method public long getUncheckedThumbColor();
+    method public long getUncheckedTrackColor();
+    property public final long checkedBorderColor;
+    property public final long checkedIconColor;
+    property public final long checkedThumbColor;
+    property public final long checkedTrackColor;
+    property public final long disabledCheckedBorderColor;
+    property public final long disabledCheckedIconColor;
+    property public final long disabledCheckedThumbColor;
+    property public final long disabledCheckedTrackColor;
+    property public final long disabledUncheckedBorderColor;
+    property public final long disabledUncheckedIconColor;
+    property public final long disabledUncheckedThumbColor;
+    property public final long disabledUncheckedTrackColor;
+    property public final long uncheckedBorderColor;
+    property public final long uncheckedIconColor;
+    property public final long uncheckedThumbColor;
+    property public final long uncheckedTrackColor;
   }
 
   public final class SwitchDefaults {
@@ -1199,6 +1487,93 @@
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldColors {
+    ctor public TextFieldColors(long focusedTextColor, long unfocusedTextColor, long disabledTextColor, long errorTextColor, long focusedContainerColor, long unfocusedContainerColor, long disabledContainerColor, long errorContainerColor, long cursorColor, long errorCursorColor, androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors, long focusedIndicatorColor, long unfocusedIndicatorColor, long disabledIndicatorColor, long errorIndicatorColor, long focusedLeadingIconColor, long unfocusedLeadingIconColor, long disabledLeadingIconColor, long errorLeadingIconColor, long focusedTrailingIconColor, long unfocusedTrailingIconColor, long disabledTrailingIconColor, long errorTrailingIconColor, long focusedLabelColor, long unfocusedLabelColor, long disabledLabelColor, long errorLabelColor, long focusedPlaceholderColor, long unfocusedPlaceholderColor, long disabledPlaceholderColor, long errorPlaceholderColor, long focusedSupportingTextColor, long unfocusedSupportingTextColor, long disabledSupportingTextColor, long errorSupportingTextColor, long focusedPrefixColor, long unfocusedPrefixColor, long disabledPrefixColor, long errorPrefixColor, long focusedSuffixColor, long unfocusedSuffixColor, long disabledSuffixColor, long errorSuffixColor);
+    method public long getCursorColor();
+    method public long getDisabledContainerColor();
+    method public long getDisabledIndicatorColor();
+    method public long getDisabledLabelColor();
+    method public long getDisabledLeadingIconColor();
+    method public long getDisabledPlaceholderColor();
+    method public long getDisabledPrefixColor();
+    method public long getDisabledSuffixColor();
+    method public long getDisabledSupportingTextColor();
+    method public long getDisabledTextColor();
+    method public long getDisabledTrailingIconColor();
+    method public long getErrorContainerColor();
+    method public long getErrorCursorColor();
+    method public long getErrorIndicatorColor();
+    method public long getErrorLabelColor();
+    method public long getErrorLeadingIconColor();
+    method public long getErrorPlaceholderColor();
+    method public long getErrorPrefixColor();
+    method public long getErrorSuffixColor();
+    method public long getErrorSupportingTextColor();
+    method public long getErrorTextColor();
+    method public long getErrorTrailingIconColor();
+    method public long getFocusedContainerColor();
+    method public long getFocusedIndicatorColor();
+    method public long getFocusedLabelColor();
+    method public long getFocusedLeadingIconColor();
+    method public long getFocusedPlaceholderColor();
+    method public long getFocusedPrefixColor();
+    method public long getFocusedSuffixColor();
+    method public long getFocusedSupportingTextColor();
+    method public long getFocusedTextColor();
+    method public long getFocusedTrailingIconColor();
+    method public androidx.compose.foundation.text.selection.TextSelectionColors getTextSelectionColors();
+    method public long getUnfocusedContainerColor();
+    method public long getUnfocusedIndicatorColor();
+    method public long getUnfocusedLabelColor();
+    method public long getUnfocusedLeadingIconColor();
+    method public long getUnfocusedPlaceholderColor();
+    method public long getUnfocusedPrefixColor();
+    method public long getUnfocusedSuffixColor();
+    method public long getUnfocusedSupportingTextColor();
+    method public long getUnfocusedTextColor();
+    method public long getUnfocusedTrailingIconColor();
+    property public final long cursorColor;
+    property public final long disabledContainerColor;
+    property public final long disabledIndicatorColor;
+    property public final long disabledLabelColor;
+    property public final long disabledLeadingIconColor;
+    property public final long disabledPlaceholderColor;
+    property public final long disabledPrefixColor;
+    property public final long disabledSuffixColor;
+    property public final long disabledSupportingTextColor;
+    property public final long disabledTextColor;
+    property public final long disabledTrailingIconColor;
+    property public final long errorContainerColor;
+    property public final long errorCursorColor;
+    property public final long errorIndicatorColor;
+    property public final long errorLabelColor;
+    property public final long errorLeadingIconColor;
+    property public final long errorPlaceholderColor;
+    property public final long errorPrefixColor;
+    property public final long errorSuffixColor;
+    property public final long errorSupportingTextColor;
+    property public final long errorTextColor;
+    property public final long errorTrailingIconColor;
+    property public final long focusedContainerColor;
+    property public final long focusedIndicatorColor;
+    property public final long focusedLabelColor;
+    property public final long focusedLeadingIconColor;
+    property public final long focusedPlaceholderColor;
+    property public final long focusedPrefixColor;
+    property public final long focusedSuffixColor;
+    property public final long focusedSupportingTextColor;
+    property public final long focusedTextColor;
+    property public final long focusedTrailingIconColor;
+    property public final androidx.compose.foundation.text.selection.TextSelectionColors textSelectionColors;
+    property public final long unfocusedContainerColor;
+    property public final long unfocusedIndicatorColor;
+    property public final long unfocusedLabelColor;
+    property public final long unfocusedLeadingIconColor;
+    property public final long unfocusedPlaceholderColor;
+    property public final long unfocusedPrefixColor;
+    property public final long unfocusedSuffixColor;
+    property public final long unfocusedSupportingTextColor;
+    property public final long unfocusedTextColor;
+    property public final long unfocusedTrailingIconColor;
   }
 
   @androidx.compose.runtime.Immutable public final class TextFieldDefaults {
@@ -1260,6 +1635,35 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Immutable public final class TimePickerColors {
+    ctor public TimePickerColors(long clockDialColor, long selectorColor, long containerColor, long periodSelectorBorderColor, long clockDialSelectedContentColor, long clockDialUnselectedContentColor, long periodSelectorSelectedContainerColor, long periodSelectorUnselectedContainerColor, long periodSelectorSelectedContentColor, long periodSelectorUnselectedContentColor, long timeSelectorSelectedContainerColor, long timeSelectorUnselectedContainerColor, long timeSelectorSelectedContentColor, long timeSelectorUnselectedContentColor);
+    method public long getClockDialColor();
+    method public long getClockDialSelectedContentColor();
+    method public long getClockDialUnselectedContentColor();
+    method public long getContainerColor();
+    method public long getPeriodSelectorBorderColor();
+    method public long getPeriodSelectorSelectedContainerColor();
+    method public long getPeriodSelectorSelectedContentColor();
+    method public long getPeriodSelectorUnselectedContainerColor();
+    method public long getPeriodSelectorUnselectedContentColor();
+    method public long getSelectorColor();
+    method public long getTimeSelectorSelectedContainerColor();
+    method public long getTimeSelectorSelectedContentColor();
+    method public long getTimeSelectorUnselectedContainerColor();
+    method public long getTimeSelectorUnselectedContentColor();
+    property public final long clockDialColor;
+    property public final long clockDialSelectedContentColor;
+    property public final long clockDialUnselectedContentColor;
+    property public final long containerColor;
+    property public final long periodSelectorBorderColor;
+    property public final long periodSelectorSelectedContainerColor;
+    property public final long periodSelectorSelectedContentColor;
+    property public final long periodSelectorUnselectedContainerColor;
+    property public final long periodSelectorUnselectedContentColor;
+    property public final long selectorColor;
+    property public final long timeSelectorSelectedContainerColor;
+    property public final long timeSelectorSelectedContentColor;
+    property public final long timeSelectorUnselectedContainerColor;
+    property public final long timeSelectorUnselectedContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TimePickerDefaults {
@@ -1336,6 +1740,17 @@
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
+    ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
+    method public long getActionIconContentColor();
+    method public long getContainerColor();
+    method public long getNavigationIconContentColor();
+    method public long getScrolledContainerColor();
+    method public long getTitleContentColor();
+    property public final long actionIconContentColor;
+    property public final long containerColor;
+    property public final long navigationIconContentColor;
+    property public final long scrolledContainerColor;
+    property public final long titleContentColor;
   }
 
   @androidx.compose.material3.ExperimentalMaterial3Api public final class TopAppBarDefaults {
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 9583afe..e9f6e1c 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -15,8 +15,9 @@
  */
 
 import androidx.build.AndroidXComposePlugin
-import androidx.build.LibraryType
 import androidx.build.KmpPlatformsKt
+import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
@@ -32,6 +33,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/material3/material3/integration-tests/material3-catalog/lint-baseline.xml b/compose/material3/material3/integration-tests/material3-catalog/lint-baseline.xml
new file mode 100644
index 0000000..8c7461b
--- /dev/null
+++ b/compose/material3/material3/integration-tests/material3-catalog/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method FontScaleItem has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (textScale: Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
index 65a4227..95cc9b1 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
@@ -146,7 +146,8 @@
 import androidx.compose.material3.samples.TextFieldWithPrefixAndSuffix
 import androidx.compose.material3.samples.TextFieldWithSupportingText
 import androidx.compose.material3.samples.TextTabs
-import androidx.compose.material3.samples.ThreeLineListItem
+import androidx.compose.material3.samples.ThreeLineListItemWithExtendedSupporting
+import androidx.compose.material3.samples.ThreeLineListItemWithOverlineAndSupporting
 import androidx.compose.material3.samples.TimeInputSample
 import androidx.compose.material3.samples.TimePickerSample
 import androidx.compose.material3.samples.TimePickerSwitchableSample
@@ -559,11 +560,18 @@
         TwoLineListItem()
     },
     Example(
-        name = ::ThreeLineListItem.name,
+        name = ::ThreeLineListItemWithOverlineAndSupporting.name,
         description = ListsExampleDescription,
         sourceUrl = ListsExampleSourceUrl
     ) {
-        ThreeLineListItem()
+        ThreeLineListItemWithOverlineAndSupporting()
+    },
+    Example(
+        name = ::ThreeLineListItemWithExtendedSupporting.name,
+        description = ListsExampleDescription,
+        sourceUrl = ListsExampleSourceUrl
+    ) {
+        ThreeLineListItemWithExtendedSupporting()
     },
 )
 
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
index 553be07..a198901 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
@@ -315,7 +315,6 @@
     fontScale: Float,
     fontScaleMin: Float = MinFontScale,
     fontScaleMax: Float = MaxFontScale,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (textScale: Float) -> Unit,
     onValueChangeFinished: () -> Unit
 ) {
diff --git a/compose/material3/material3/lint-baseline.xml b/compose/material3/material3/lint-baseline.xml
index 482eaef..8f77094 100644
--- a/compose/material3/material3/lint-baseline.xml
+++ b/compose/material3/material3/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -199,4 +199,562 @@
             file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomSheetScaffoldLayout has parameter &apos;bottomSheet&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    bottomSheet: @Composable (layoutHeight: Int) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomSheetScaffoldLayout has parameter &apos;sheetOffset&apos; with type Function0&lt;Float>."
+        errorLine1="    sheetOffset: () -> Float,"
+        errorLine2="                 ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method BottomSheetScaffoldAnchorChangeHandler has parameter &apos;animateTo&apos; with type Function2&lt;? super SheetValue, ? super Float, Unit>."
+        errorLine1="    animateTo: (target: SheetValue, velocity: Float) -> Unit,"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DateInputContent has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (dateInMillis: Long?) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateInput.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DateInputTextField has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (Long?) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateInput.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DisplayModeToggleButton has parameter &apos;onDisplayModeChange&apos; with type Function1&lt;? super DisplayMode, Unit>."
+        errorLine1="    onDisplayModeChange: (DisplayMode) -> Unit"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SwitchableDateEntryContent has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (dateInMillis: Long?) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SwitchableDateEntryContent has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DatePickerContent has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (dateInMillis: Long) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DatePickerContent has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalMonthsList has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (dateInMillis: Long) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method HorizontalMonthsList has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method updateDisplayedMonth has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Month has parameter &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDateSelectionChange: (dateInMillis: Long) -> Unit,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method YearPicker has parameter &apos;onYearSelected&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onYearSelected: (year: Int) -> Unit,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DateRangeInputContent has parameter &apos;onDatesSelectionChange&apos; with type Function2&lt;? super Long, ? super Long, Unit>."
+        errorLine1="    onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SwitchableDateEntryContent has parameter &apos;onDatesSelectionChange&apos; with type Function2&lt;? super Long, ? super Long, Unit>."
+        errorLine1="    onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method SwitchableDateEntryContent has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DateRangePickerContent has parameter &apos;onDatesSelectionChange&apos; with type Function2&lt;? super Long, ? super Long, Unit>."
+        errorLine1="    onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DateRangePickerContent has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalMonthsList has parameter &apos;onDatesSelectionChange&apos; with type Function2&lt;? super Long, ? super Long, Unit>."
+        errorLine1="    onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method VerticalMonthsList has parameter &apos;onDisplayedMonthChange&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    onDisplayedMonthChange: (monthInMillis: Long) -> Unit,"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;onDateSelectionChange&apos; with type Function1&lt;? super Long, ? extends Unit>."
+        errorLine1="                    val onDateSelectionChange = { dateInMillis: Long ->"
+        errorLine2="                    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method updateDateSelection has parameter &apos;onDatesSelectionChange&apos; with type Function2&lt;? super Long, ? super Long, Unit>."
+        errorLine1="    onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method awaitHorizontalPointerSlopOrCancellation has parameter &apos;onPointerSlopReached&apos; with type Function2&lt;? super PointerInputChange, ? super Float, Unit>."
+        errorLine1="    onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/DragGestureDetectorCopy.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method updateHeight has parameter &apos;onHeightUpdate&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onHeightUpdate: (Int) -> Unit"
+        errorLine2="                    ~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;settleToDismiss&apos; with type Function1&lt;? super Float, ? extends Unit>."
+        errorLine1="    val settleToDismiss: (velocity: Float) -> Unit = {"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method modalBottomSheetSwipeable has parameter &apos;onDragStopped&apos; with type Function2&lt;? super CoroutineScope, ? super Float, Unit>."
+        errorLine1="    onDragStopped: CoroutineScope.(velocity: Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ModalBottomSheetAnchorChangeHandler has parameter &apos;animateTo&apos; with type Function2&lt;? super SheetValue, ? super Float, Unit>."
+        errorLine1="    animateTo: (target: SheetValue, velocity: Float) -> Unit,"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Scrim has parameter &apos;fraction&apos; with type Function0&lt;Float>."
+        errorLine1="    fraction: () -> Float,"
+        errorLine2="              ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicWidth has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicHeight has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection has parameter &apos;onFling&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onFling: (velocity: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Slider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Slider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;postPointerSlop&apos; with type Function2&lt;? super PointerInputChange, ? super Float, ? extends Unit>."
+        errorLine1="    val postPointerSlop = { pointerInput: PointerInputChange, offset: Float ->"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method sliderSemantics has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type State&lt;Function2&lt;Boolean, Float, Unit>> of &apos;getOnDrag&apos;."
+        errorLine1="    val onDrag: State&lt;(Boolean, Float) -> Unit>,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SliderDraggableState has parameter &apos;onDelta&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    val onDelta: (Float) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Unit> of &apos;getOnDelta&apos;."
+        errorLine1="    val onDelta: (Float) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SliderState has parameter &apos;initialOnValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    initialOnValueChange: ((Float) -> Unit)? = null,"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setOnValueChange$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Float, Unit> of &apos;getOnValueChange$lint_module&apos;."
+        errorLine1="    internal var onValueChange: (Float) -> Unit = {"
+        errorLine2="                                ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DismissState has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="            positionalThreshold: Density.(totalDistance: Float) -> Float,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberDismissState has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;getFixedPositionalThreshold&apos;."
+        errorLine1="    val FixedPositionalThreshold: Density.(totalDistance: Float) -> Float = { _ -> 56.dp.toPx() }"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setThresholds$lint_module has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Float, Float, Float> of &apos;getThresholds$lint_module&apos;."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method computeTarget has parameter &apos;thresholds&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    thresholds: (Float, Float) -> Float,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method swipeAnchors has parameter &apos;calculateAnchor&apos; with type Function2&lt;? super T, ? super IntSize, Float>."
+        errorLine1="    calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SwipeableV2State has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    internal val positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;getPositionalThreshold$lint_module&apos;."
+        errorLine1="    internal val positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="            positionalThreshold: Density.(distance: Float) -> Float,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;fixedPositionalThreshold&apos;."
+        errorLine1="internal fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;fractionalPositionalThreshold&apos;."
+        errorLine1="): Density.(distance: Float) -> Float = { distance -> distance * fraction }"
+        errorLine2="   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;getPositionalThreshold&apos;."
+        errorLine1="    val PositionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ReconcileAnimationOnAnchorChangeHandler$lint_module has parameter &apos;animate&apos; with type Function2&lt;? super T, ? super Float, Unit>."
+        errorLine1="        animate: (target: T, velocity: Float) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;valueToOffset&apos; with type Function1&lt;? super Boolean, ? extends Float>."
+        errorLine1="    val valueToOffset = remember&lt;(Boolean) -> Float>(minBound, maxBound) {"
+        errorLine2="    ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/Switch.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicWidth has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/TextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method intrinsicHeight has parameter &apos;intrinsicMeasurer&apos; with type Function2&lt;? super IntrinsicMeasurable, ? super Integer, Integer>."
+        errorLine1="        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/TextField.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Transition has parameter &apos;content&apos; with type Function5&lt;? super Float, ? super Color, ? super Color, ? super Float, ? super Float, Unit>."
+        errorLine1="        content: @Composable ("
+        errorLine2="                 ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ListSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ListSamples.kt
index 5355796..66bd980 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ListSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ListSamples.kt
@@ -21,7 +21,6 @@
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.material3.Divider
-import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Icon
 import androidx.compose.material3.ListItem
 import androidx.compose.material3.Text
@@ -31,7 +30,6 @@
 @Preview
 @Sampled
 @Composable
-@OptIn(ExperimentalMaterial3Api::class)
 fun OneLineListItem() {
     Column {
         ListItem(
@@ -50,7 +48,6 @@
 @Preview
 @Sampled
 @Composable
-@OptIn(ExperimentalMaterial3Api::class)
 fun TwoLineListItem() {
     Column {
         ListItem(
@@ -71,8 +68,7 @@
 @Preview
 @Sampled
 @Composable
-@OptIn(ExperimentalMaterial3Api::class)
-fun ThreeLineListItem() {
+fun ThreeLineListItemWithOverlineAndSupporting() {
     Column {
         ListItem(
             headlineContent = { Text("Three line list item") },
@@ -88,4 +84,26 @@
         )
         Divider()
     }
-}
\ No newline at end of file
+}
+
+@Preview
+@Sampled
+@Composable
+fun ThreeLineListItemWithExtendedSupporting() {
+    Column {
+        ListItem(
+            headlineContent = { Text("Three line list item") },
+            supportingContent = {
+                Text("Secondary text that is long and perhaps goes onto another line")
+            },
+            leadingContent = {
+                Icon(
+                    Icons.Filled.Favorite,
+                    contentDescription = "Localized description",
+                )
+            },
+            trailingContent = { Text("meta") }
+        )
+        Divider()
+    }
+}
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SliderSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SliderSamples.kt
index 56e258c..4b4c84f 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SliderSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SliderSamples.kt
@@ -26,6 +26,7 @@
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.Icon
 import androidx.compose.material3.RangeSlider
+import androidx.compose.material3.RangeSliderState
 import androidx.compose.material3.Slider
 import androidx.compose.material3.SliderDefaults
 import androidx.compose.material3.SliderState
@@ -154,7 +155,7 @@
         RangeSlider(
             modifier = Modifier.semantics { contentDescription = "Localized Description" },
             value = sliderPosition,
-            onValueChange = { sliderPosition = it },
+            onValueChange = { range -> sliderPosition = range },
             valueRange = 0f..100f,
             onValueChangeFinished = {
                 // launch some business logic update with the state you hold
@@ -175,8 +176,8 @@
             modifier = Modifier.semantics { contentDescription = "Localized Description" },
             steps = 5,
             value = sliderPosition,
-            onValueChange = { sliderPosition = it },
-            valueRange = 0f..100f,
+            onValueChange = { range -> sliderPosition = range },
+            valueRange = 0f..1f,
             onValueChangeFinished = {
                 // launch some business logic update with the state you hold
                 // viewModel.updateSelectedSliderValue(sliderPosition)
@@ -190,7 +191,17 @@
 @Sampled
 @Composable
 fun RangeSliderWithCustomComponents() {
-    var sliderPosition by remember { mutableStateOf(0f..100f) }
+    val rangeSliderState = remember {
+        RangeSliderState(
+            0f,
+            100f,
+            valueRange = 0f..100f,
+            onValueChangeFinished = {
+                // launch some business logic update with the state you hold
+                // viewModel.updateSelectedSliderValue(sliderPosition)
+            }
+        )
+    }
     val startInteractionSource = remember { MutableInteractionSource() }
     val endInteractionSource = remember { MutableInteractionSource() }
     val startThumbAndTrackColors = SliderDefaults.colors(
@@ -199,16 +210,10 @@
     )
     val endThumbColors = SliderDefaults.colors(thumbColor = Color.Green)
     Column {
-        Text(text = sliderPosition.toString())
+        Text(text = (rangeSliderState.activeRangeStart..rangeSliderState.activeRangeEnd).toString())
         RangeSlider(
+            state = rangeSliderState,
             modifier = Modifier.semantics { contentDescription = "Localized Description" },
-            value = sliderPosition,
-            onValueChange = { sliderPosition = it },
-            valueRange = 0f..100f,
-            onValueChangeFinished = {
-                // launch some business logic update with the state you hold
-                // viewModel.updateSelectedSliderValue(sliderPosition)
-            },
             startInteractionSource = startInteractionSource,
             endInteractionSource = endInteractionSource,
             startThumb = {
@@ -223,10 +228,10 @@
                     colors = endThumbColors
                 )
             },
-            track = { sliderPositions ->
+            track = { rangeSliderState ->
                 SliderDefaults.Track(
                     colors = startThumbAndTrackColors,
-                    sliderPositions = sliderPositions
+                    rangeSliderState = rangeSliderState
                 )
             }
         )
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
index 1b21463..b5e14eb 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
@@ -18,12 +18,14 @@
 
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
 import androidx.compose.material3.tokens.ListTokens
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.node.Ref
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
@@ -125,8 +127,8 @@
     @Test
     fun listItem_oneLine_positioning_noIcon() {
         val listItemHeight = ListTokens.ListItemOneLineContainerHeight
-        val expectedStartPadding = 16.dp
-        val expectedEndPadding = 24.dp
+        val expectedStartPadding = LeadingContentEndPadding
+        val expectedEndPadding = ListItemEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -151,17 +153,17 @@
 
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - textSize.value!!.height) / 2f
             )
 
-            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
                 ds.width.toPx() - trailingSize.value!!.width - expectedEndPadding.toPx()
             )
-            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
             )
         }
@@ -170,8 +172,8 @@
     @Test
     fun listItem_oneLine_positioning_withIcon() {
         val listItemHeight = ListTokens.ListItemOneLineContainerHeight
-        val expectedStartPadding = 16.dp
-        val expectedTextStartPadding = 16.dp
+        val expectedStartPadding = ListItemStartPadding
+        val expectedTextStartPadding = LeadingContentEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -193,29 +195,90 @@
             }
         }
         rule.runOnIdleWithDensity {
-            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - iconSize.value!!.height) / 2f
             )
 
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() +
                     iconSize.value!!.width +
                     expectedTextStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - textSize.value!!.height) / 2f
             )
         }
     }
 
     @Test
+    fun listItem_oneLine_positioning_customSize() {
+        val listItemHeight = 100.dp
+        val listItemWidth = 300.dp
+        val expectedStartPadding = ListItemStartPadding
+        val expectedEndPadding = ListItemEndPadding
+        val expectedTextStartPadding = LeadingContentEndPadding
+
+        val textPosition = Ref<Offset>()
+        val textSize = Ref<IntSize>()
+        val leadingIconPosition = Ref<Offset>()
+        val leadingIconSize = Ref<IntSize>()
+        val trailingPosition = Ref<Offset>()
+        val trailingSize = Ref<IntSize>()
+        rule.setMaterialContent(lightColorScheme()) {
+            ListItem(
+                modifier = Modifier.size(width = listItemWidth, height = listItemHeight),
+                headlineContent = {
+                    Text("Primary text", Modifier.saveLayout(textPosition, textSize))
+                },
+                leadingContent = {
+                    Image(
+                        icon24x24,
+                        null,
+                        Modifier.saveLayout(leadingIconPosition, leadingIconSize))
+                },
+                trailingContent = {
+                    Text(
+                        "meta",
+                        Modifier.saveLayout(trailingPosition, trailingSize)
+                    )
+                }
+            )
+        }
+        rule.runOnIdleWithDensity {
+            assertThat(leadingIconPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx()
+            )
+            assertThat(leadingIconPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - leadingIconSize.value!!.height) / 2f
+            )
+
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - textSize.value!!.height) / 2f
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
+                listItemWidth.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
+            )
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
+            )
+        }
+    }
+
+    @Test
     fun listItem_twoLine_positioning_noIcon() {
         val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
-        val expectedStartPadding = 16.dp
-        val expectedEndPadding = 24.dp
+        val expectedStartPadding = ListItemStartPadding
+        val expectedEndPadding = ListItemEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -251,25 +314,25 @@
         rule.runOnIdleWithDensity {
             val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
 
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - totalTextHeight) / 2f
             )
 
-            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
             )
 
-            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
                 ds.width.toPx() - trailingSize.value!!.width -
                     expectedEndPadding.toPx()
             )
-            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
             )
         }
@@ -278,8 +341,8 @@
     @Test
     fun listItem_twoLine_positioning_withIcon() {
         val listItemHeight = ListTokens.ListItemTwoLineContainerHeight
-        val expectedStartPadding = 16.dp
-        val expectedContentStartPadding = 16.dp
+        val expectedStartPadding = ListItemStartPadding
+        val expectedContentStartPadding = LeadingContentEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -311,36 +374,117 @@
         rule.runOnIdleWithDensity {
             val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
 
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - totalTextHeight) / 2f
             )
 
-            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
             )
 
-            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.y).isWithin(1f).of(
                 (listItemHeight.toPx() - iconSize.value!!.height) / 2f
             )
         }
     }
 
     @Test
+    fun listItem_twoLine_positioning_customSize() {
+        val listItemHeight = 100.dp
+        val listItemWidth = 300.dp
+        val expectedStartPadding = ListItemStartPadding
+        val expectedEndPadding = ListItemEndPadding
+        val expectedTextStartPadding = LeadingContentEndPadding
+
+        val textPosition = Ref<Offset>()
+        val textSize = Ref<IntSize>()
+        val secondaryTextPosition = Ref<Offset>()
+        val secondaryTextSize = Ref<IntSize>()
+        val leadingIconPosition = Ref<Offset>()
+        val leadingIconSize = Ref<IntSize>()
+        val trailingPosition = Ref<Offset>()
+        val trailingSize = Ref<IntSize>()
+        rule.setMaterialContent(lightColorScheme()) {
+            ListItem(
+                modifier = Modifier.size(width = listItemWidth, height = listItemHeight),
+                headlineContent = {
+                    Text("Primary text", Modifier.saveLayout(textPosition, textSize))
+                },
+                supportingContent = {
+                    Text(
+                        "Secondary text",
+                        Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
+                    )
+                },
+                leadingContent = {
+                    Image(
+                        icon24x24,
+                        null,
+                        Modifier.saveLayout(leadingIconPosition, leadingIconSize))
+                },
+                trailingContent = {
+                    Text(
+                        "meta",
+                        Modifier.saveLayout(trailingPosition, trailingSize)
+                    )
+                }
+            )
+        }
+        rule.runOnIdleWithDensity {
+            val totalTextHeight = textSize.value!!.height + secondaryTextSize.value!!.height
+
+            assertThat(leadingIconPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx()
+            )
+            assertThat(leadingIconPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - leadingIconSize.value!!.height) / 2f
+            )
+
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f
+            )
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - totalTextHeight) / 2f + textSize.value!!.height
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
+                listItemWidth.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
+            )
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
+                (listItemHeight.toPx() - trailingSize.value!!.height) / 2f
+            )
+        }
+    }
+
+    @Test
     fun listItem_threeLine_positioning_noOverline_metaText() {
-        val expectedStartPadding = 16.dp
-        val expectedContentStartPadding = 16.dp
-        val expectedEndPadding = 24.dp
+        val expectedTopPadding = ListItemThreeLineVerticalPadding
+        val expectedStartPadding = ListItemStartPadding
+        val expectedContentStartPadding = LeadingContentEndPadding
+        val expectedEndPadding = ListItemEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -376,34 +520,45 @@
         }
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            // TODO(b/233782301): Test y positions when this is implemented as a 3-line ListItem
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
 
-            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx() + textSize.value!!.height
+            )
 
-            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
+            assertThat(iconPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
 
-            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
                 ds.width.toPx() - trailingSize.value!!.width -
                     expectedEndPadding.toPx()
             )
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
         }
     }
 
     @Test
     fun listItem_threeLine_positioning_overline_trailingIcon() {
-        val expectedTopPadding = 12.dp
-        val expectedStartPadding = 16.dp
-        val expectedContentStartPadding = 16.dp
-        val expectedEndPadding = 24.dp
+        val expectedTopPadding = ListItemThreeLineVerticalPadding
+        val expectedStartPadding = ListItemStartPadding
+        val expectedContentStartPadding = LeadingContentEndPadding
+        val expectedEndPadding = ListItemEndPadding
 
         val textPosition = Ref<Offset>()
         val textSize = Ref<IntSize>()
@@ -455,43 +610,140 @@
 
         val ds = rule.onRoot().getUnclippedBoundsInRoot()
         rule.runOnIdleWithDensity {
-            assertThat(textPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
-            assertThat(textPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
                 expectedTopPadding.toPx() + overlineTextSize.value!!.height
             )
 
-            assertThat(secondaryTextPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
-            assertThat(secondaryTextPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
                 expectedTopPadding.toPx() + overlineTextSize.value!!.height +
                 textSize.value!!.height
             )
 
-            assertThat(iconPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx()
             )
-            assertThat(iconPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(iconPosition.value!!.y).isWithin(1f).of(
                 expectedTopPadding.toPx()
             )
 
-            assertThat(trailingPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
                 ds.width.toPx() - trailingSize.value!!.width -
                     expectedEndPadding.toPx()
             )
-            assertThat(trailingPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
                 expectedTopPadding.toPx()
             )
 
-            assertThat(overlineTextPosition.value!!.x).isWithin(0.5f).of(
+            assertThat(overlineTextPosition.value!!.x).isWithin(1f).of(
                 expectedStartPadding.toPx() + iconSize.value!!.width +
                     expectedContentStartPadding.toPx()
             )
-            assertThat(overlineTextPosition.value!!.y).isWithin(0.5f).of(
+            assertThat(overlineTextPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
+        }
+    }
+
+    @Test
+    fun listItem_threeLine_overline_positioning_customSize() {
+        val listItemHeight = 100.dp
+        val listItemWidth = 300.dp
+        val expectedTopPadding = ListItemThreeLineVerticalPadding
+        val expectedStartPadding = ListItemStartPadding
+        val expectedEndPadding = ListItemEndPadding
+        val expectedTextStartPadding = LeadingContentEndPadding
+
+        val textPosition = Ref<Offset>()
+        val textSize = Ref<IntSize>()
+        val overlineTextPosition = Ref<Offset>()
+        val overlineTextSize = Ref<IntSize>()
+        val secondaryTextPosition = Ref<Offset>()
+        val secondaryTextSize = Ref<IntSize>()
+        val leadingIconPosition = Ref<Offset>()
+        val leadingIconSize = Ref<IntSize>()
+        val trailingPosition = Ref<Offset>()
+        val trailingSize = Ref<IntSize>()
+        rule.setMaterialContent(lightColorScheme()) {
+            ListItem(
+                modifier = Modifier.size(width = listItemWidth, height = listItemHeight),
+                overlineContent = {
+                    Text(
+                        "OVERLINE",
+                        Modifier.saveLayout(overlineTextPosition, overlineTextSize)
+                    )
+                },
+                headlineContent = {
+                    Text("Primary text", Modifier.saveLayout(textPosition, textSize))
+                },
+                supportingContent = {
+                    Text(
+                        "Secondary text",
+                        Modifier.saveLayout(secondaryTextPosition, secondaryTextSize)
+                    )
+                },
+                leadingContent = {
+                    Image(
+                        icon24x24,
+                        null,
+                        Modifier.saveLayout(leadingIconPosition, leadingIconSize))
+                },
+                trailingContent = {
+                    Text(
+                        "meta",
+                        Modifier.saveLayout(trailingPosition, trailingSize)
+                    )
+                }
+            )
+        }
+        rule.runOnIdleWithDensity {
+            assertThat(leadingIconPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx()
+            )
+            assertThat(leadingIconPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
+
+            assertThat(overlineTextPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(overlineTextPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx()
+            )
+
+            assertThat(textPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(textPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx() + overlineTextSize.value!!.height
+            )
+
+            assertThat(secondaryTextPosition.value!!.x).isWithin(1f).of(
+                expectedStartPadding.toPx() +
+                    leadingIconSize.value!!.width +
+                    expectedTextStartPadding.toPx()
+            )
+            assertThat(secondaryTextPosition.value!!.y).isWithin(1f).of(
+                expectedTopPadding.toPx() + overlineTextSize.value!!.height +
+                textSize.value!!.height
+            )
+
+            assertThat(trailingPosition.value!!.x).isWithin(1f).of(
+                listItemWidth.toPx() - trailingSize.value!!.width -
+                    expectedEndPadding.toPx()
+            )
+            assertThat(trailingPosition.value!!.y).isWithin(1f).of(
                 expectedTopPadding.toPx()
             )
         }
@@ -503,7 +755,7 @@
         coords: Ref<Offset>,
         size: Ref<IntSize>,
     ): Modifier = onGloballyPositioned { coordinates: LayoutCoordinates ->
-        coords.value = coordinates.localToRoot(Offset.Zero)
+        coords.value = coordinates.positionInRoot()
         size.value = coordinates.size
     }
 }
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ScaffoldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ScaffoldTest.kt
index 605e1fb..9d76b98 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ScaffoldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ScaffoldTest.kt
@@ -25,6 +25,7 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.windowInsetsPadding
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.geometry.Offset
@@ -43,6 +44,7 @@
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.toSize
@@ -271,7 +273,7 @@
     @Test
     fun scaffold_providesInsets_respectTopAppBar() {
         rule.setContent {
-            Box(Modifier.requiredSize(10.dp, 20.dp)) {
+            Box(Modifier.requiredSize(10.dp, 40.dp)) {
                 Scaffold(
                     contentWindowInsets = WindowInsets(top = 5.dp, bottom = 3.dp),
                     topBar = {
@@ -279,11 +281,80 @@
                     }
                 ) { paddingValues ->
                     // top is like top app bar + rounding error
-                    assertThat(paddingValues.calculateTopPadding() - 10.dp)
-                        .isLessThan(roundingError)
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateTopPadding(),
+                        expected = 10.dp,
+                        threshold = roundingError
+                    )
                     // bottom is like the insets
-                    assertThat(paddingValues.calculateBottomPadding() - 30.dp).isLessThan(
-                        roundingError
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateBottomPadding(),
+                        expected = 3.dp,
+                        threshold = roundingError
+                    )
+                    Box(
+                        Modifier
+                            .requiredSize(10.dp)
+                            .background(color = Color.White)
+                    )
+                }
+            }
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun scaffold_respectsProvidedInsets() {
+        rule.setContent {
+            Box(Modifier.requiredSize(10.dp, 40.dp)) {
+                Scaffold(
+                    contentWindowInsets = WindowInsets(top = 15.dp, bottom = 10.dp),
+                ) { paddingValues ->
+                    // topPadding is equal to provided top window inset
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateTopPadding(),
+                        expected = 15.dp,
+                        threshold = roundingError
+                    )
+                    // bottomPadding is equal to provided bottom window inset
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateBottomPadding(),
+                        expected = 10.dp,
+                        threshold = roundingError
+                    )
+                    Box(
+                        Modifier
+                            .requiredSize(10.dp)
+                            .background(color = Color.White)
+                    )
+                }
+            }
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+    @Test
+    fun scaffold_respectsConsumedWindowInsets() {
+        rule.setContent {
+            Box(
+                Modifier
+                    .requiredSize(10.dp, 40.dp)
+                    .windowInsetsPadding(WindowInsets(top = 10.dp, bottom = 10.dp))
+            ) {
+                Scaffold(
+                    contentWindowInsets = WindowInsets(top = 15.dp, bottom = 15.dp)
+                ) { paddingValues ->
+                    // Consumed windowInsetsPadding is omitted. This replicates behavior from
+                    // Modifier.windowInsetsPadding. (15.dp contentPadding - 10.dp consumedPadding)
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateTopPadding(),
+                        expected = 5.dp,
+                        threshold = roundingError
+                    )
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateBottomPadding(),
+                        expected = 5.dp,
+                        threshold = roundingError
                     )
                     Box(
                         Modifier
@@ -299,7 +370,7 @@
     @Test
     fun scaffold_providesInsets_respectCollapsedTopAppBar() {
         rule.setContent {
-            Box(Modifier.requiredSize(10.dp, 20.dp)) {
+            Box(Modifier.requiredSize(10.dp, 40.dp)) {
                 Scaffold(
                     contentWindowInsets = WindowInsets(top = 5.dp, bottom = 3.dp),
                     topBar = {
@@ -307,10 +378,16 @@
                     }
                 ) { paddingValues ->
                     // top is like the collapsed top app bar (i.e. 0dp) + rounding error
-                    assertThat(paddingValues.calculateTopPadding()).isLessThan(roundingError)
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateTopPadding(),
+                        expected = 0.dp,
+                        threshold = roundingError
+                    )
                     // bottom is like the insets
-                    assertThat(paddingValues.calculateBottomPadding() - 30.dp).isLessThan(
-                        roundingError
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateBottomPadding(),
+                        expected = 3.dp,
+                        threshold = roundingError
                     )
                     Box(
                         Modifier
@@ -326,7 +403,7 @@
     @Test
     fun scaffold_providesInsets_respectsBottomAppBar() {
         rule.setContent {
-            Box(Modifier.requiredSize(10.dp, 20.dp)) {
+            Box(Modifier.requiredSize(10.dp, 40.dp)) {
                 Scaffold(
                     contentWindowInsets = WindowInsets(top = 5.dp, bottom = 3.dp),
                     bottomBar = {
@@ -334,11 +411,17 @@
                     }
                 ) { paddingValues ->
                     // bottom is like bottom app bar + rounding error
-                    assertThat(paddingValues.calculateBottomPadding() - 10.dp).isLessThan(
-                        roundingError
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateBottomPadding(),
+                        expected = 10.dp,
+                        threshold = roundingError
                     )
                     // top is like the insets
-                    assertThat(paddingValues.calculateTopPadding() - 5.dp).isLessThan(roundingError)
+                    assertDpIsWithinThreshold(
+                        actual = paddingValues.calculateTopPadding(),
+                        expected = 5.dp,
+                        threshold = roundingError
+                    )
                     Box(
                         Modifier
                             .requiredSize(10.dp)
@@ -357,7 +440,7 @@
         var snackbarPosition: Offset? = null
         var density: Density? = null
         rule.setContent {
-            Box(Modifier.requiredSize(10.dp, 20.dp)) {
+            Box(Modifier.requiredSize(10.dp, 40.dp)) {
                 density = LocalDensity.current
                 Scaffold(
                     contentWindowInsets = WindowInsets(top = 5.dp, bottom = 3.dp),
@@ -417,4 +500,8 @@
             with(density!!) { (fabPosition!!.y.roundToInt() + fabSize!!.height).toDp() }
         assertThat(rule.rootHeight() - fabBottomOffsetDp - 3.dp).isLessThan(1.dp)
     }
+
+    private fun assertDpIsWithinThreshold(actual: Dp, expected: Dp, threshold: Dp) {
+        assertThat(actual.value).isWithin(threshold.value).of(expected.value)
+    }
 }
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderScreenshotTest.kt
index 18428a7..07f43c4 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderScreenshotTest.kt
@@ -208,7 +208,12 @@
         rule.setMaterialContent(lightColorScheme()) {
             Box(wrap.testTag(wrapperTestTag)) {
                 var position by remember { mutableStateOf(0.5f..1f) }
-                RangeSlider(position, { position = it }, steps = 5, enabled = false)
+                RangeSlider(
+                    position,
+                    { position = it },
+                    steps = 5,
+                    enabled = false
+                )
             }
         }
         assertSliderAgainstGolden("rangeSlider_middle_steps_disabled")
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderTest.kt
index 0576f34..00f95e0 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SliderTest.kt
@@ -747,7 +747,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_dragThumb() {
         val state = mutableStateOf(0f..1f)
@@ -758,7 +757,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -781,7 +780,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_drag_out_of_bounds() {
         val state = mutableStateOf(0f..1f)
@@ -792,7 +790,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -819,7 +817,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_drag_overlap_thumbs() {
         val state = mutableStateOf(0.5f..1f)
@@ -830,7 +827,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -857,7 +854,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_tap() {
         val state = mutableStateOf(0f..1f)
@@ -866,7 +862,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -888,7 +884,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_tap_rangeChange() {
         val state = mutableStateOf(0f..25f)
@@ -898,7 +893,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it },
+                onValueChange = { range -> state.value = range },
                 valueRange = 0f..rangeEnd.value
             )
         }
@@ -921,7 +916,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_drag_rtl() {
         val state = mutableStateOf(0f..1f)
@@ -933,7 +927,7 @@
                 RangeSlider(
                     modifier = Modifier.testTag(tag),
                     value = state.value,
-                    onValueChange = { state.value = it }
+                    onValueChange = { range -> state.value = range }
                 )
             }
         }
@@ -970,7 +964,7 @@
                 RangeSlider(
                     modifier = Modifier.testTag(tag),
                     value = state.value,
-                    onValueChange = { state.value = it }
+                    onValueChange = { range -> state.value = range }
                 )
             }
         }
@@ -999,7 +993,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_closeThumbs_dragRight() {
         val state = mutableStateOf(0.5f..0.5f)
@@ -1010,7 +1003,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -1035,7 +1028,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_closeThumbs_dragLeft() {
         val state = mutableStateOf(0.5f..0.5f)
@@ -1046,7 +1038,7 @@
             RangeSlider(
                 modifier = Modifier.testTag(tag),
                 value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -1074,7 +1066,6 @@
     /**
      * Regression test for bug: 210289161 where RangeSlider was ignoring some modifiers like weight.
      */
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_weightModifier() {
         var sliderBounds = Rect(0f, 0f, 0f, 0f)
@@ -1084,7 +1075,7 @@
                     Spacer(Modifier.requiredSize(100.toDp()))
                     RangeSlider(
                         value = 0f..0.5f,
-                        onValueChange = {},
+                        onValueChange = { _ -> },
                         modifier = Modifier
                             .testTag(tag)
                             .weight(1f)
@@ -1103,7 +1094,6 @@
         }
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_semantics_continuous() {
         val state = mutableStateOf(0f..1f)
@@ -1111,7 +1101,7 @@
         rule.setMaterialContent(lightColorScheme()) {
             RangeSlider(
                 modifier = Modifier.testTag(tag), value = state.value,
-                onValueChange = { state.value = it }
+                onValueChange = { range -> state.value = range }
             )
         }
 
@@ -1156,7 +1146,6 @@
             .assertRangeInfoEquals(ProgressBarRangeInfo(0.8f, 0.6f..1f, 0))
     }
 
-    @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun rangeSlider_semantics_stepped() {
         val state = mutableStateOf(0f..20f)
@@ -1166,7 +1155,7 @@
                 modifier = Modifier.testTag(tag), value = state.value,
                 steps = 3,
                 valueRange = 0f..20f,
-                onValueChange = { state.value = it },
+                onValueChange = { range -> state.value = range },
             )
         }
 
@@ -1216,11 +1205,11 @@
                 value = state.value,
                 onValueChange = { state.value = it },
                 valueRange = 0f..100f,
-                startThumb = { sliderPositions ->
-                    startRecompositionCounter.OuterContent(sliderPositions)
+                startThumb = { rangeSliderState ->
+                    startRecompositionCounter.OuterContent(rangeSliderState)
                 },
-                endThumb = { sliderPositions ->
-                    endRecompositionCounter.OuterContent(sliderPositions)
+                endThumb = { rangeSliderState ->
+                    endRecompositionCounter.OuterContent(rangeSliderState)
                 }
             )
         }
@@ -1235,9 +1224,9 @@
 
         rule.runOnIdle {
             Truth.assertThat(startRecompositionCounter.outerRecomposition).isEqualTo(1)
-            Truth.assertThat(startRecompositionCounter.innerRecomposition).isEqualTo(3)
+            Truth.assertThat(startRecompositionCounter.innerRecomposition).isEqualTo(2)
             Truth.assertThat(endRecompositionCounter.outerRecomposition).isEqualTo(1)
-            Truth.assertThat(endRecompositionCounter.innerRecomposition).isEqualTo(3)
+            Truth.assertThat(endRecompositionCounter.innerRecomposition).isEqualTo(2)
         }
     }
 
@@ -1253,8 +1242,8 @@
                 value = state.value,
                 onValueChange = { state.value = it },
                 valueRange = 0f..100f,
-                track = { sliderPositions ->
-                    recompositionCounter.OuterContent(sliderPositions)
+                track = { rangeSliderState ->
+                    recompositionCounter.OuterContent(rangeSliderState)
                 }
             )
         }
@@ -1269,7 +1258,7 @@
 
         rule.runOnIdle {
             Truth.assertThat(recompositionCounter.outerRecomposition).isEqualTo(1)
-            Truth.assertThat(recompositionCounter.innerRecomposition).isEqualTo(4)
+            Truth.assertThat(recompositionCounter.innerRecomposition).isEqualTo(3)
         }
     }
 
@@ -1278,7 +1267,10 @@
         val state = mutableStateOf(0f..1f)
         rule.setMaterialContentForSizeAssertions {
             Box(modifier = Modifier.requiredWidth(Int.MAX_VALUE.dp)) {
-                RangeSlider(value = state.value, onValueChange = { state.value = it })
+                RangeSlider(
+                    value = state.value,
+                    onValueChange = { range -> state.value = range }
+                )
             }
         }.assertWidthIsEqualTo(48.dp)
     }
@@ -1292,7 +1284,7 @@
                     RangeSlider(
                         modifier = Modifier.weight(1f),
                         value = state.value,
-                        onValueChange = { state.value = it }
+                        onValueChange = { range -> state.value = range }
                     )
                 }
             }
@@ -1300,29 +1292,6 @@
     }
 }
 
-@Stable
-class RangeSliderRecompositionCounter {
-    var innerRecomposition = 0
-    var outerRecomposition = 0
-
-    @OptIn(ExperimentalMaterial3Api::class)
-    @Composable
-    fun OuterContent(sliderPositions: SliderPositions) {
-        SideEffect { ++outerRecomposition }
-        Column {
-            Text("OuterContent")
-            InnerContent(sliderPositions)
-        }
-    }
-
-    @OptIn(ExperimentalMaterial3Api::class)
-    @Composable
-    private fun InnerContent(sliderPositions: SliderPositions) {
-        SideEffect { ++innerRecomposition }
-        Text("InnerContent: ${sliderPositions.activeRange}")
-    }
-}
-
 @OptIn(ExperimentalMaterial3Api::class)
 @Stable
 class SliderRecompositionCounter {
@@ -1344,3 +1313,27 @@
         Text("InnerContent: ${state.value}")
     }
 }
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Stable
+class RangeSliderRecompositionCounter {
+    var innerRecomposition = 0
+    var outerRecomposition = 0
+
+    @Composable
+    fun OuterContent(state: RangeSliderState) {
+        SideEffect {
+            ++outerRecomposition
+        }
+        Column {
+            Text("OuterContent")
+            InnerContent(state)
+        }
+    }
+
+    @Composable
+    private fun InnerContent(state: RangeSliderState) {
+        SideEffect { ++innerRecomposition }
+        Text("InnerContent: ${state.activeRangeStart..state.activeRangeEnd}")
+    }
+}
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TimePickerTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TimePickerTest.kt
index c514c93..8d116ff5 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TimePickerTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TimePickerTest.kt
@@ -22,7 +22,6 @@
 import android.os.Build
 import android.text.format.DateFormat
 import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.input.key.Key
 import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalContext
@@ -384,7 +383,7 @@
             .assertContentDescriptionContains("for minutes")
     }
 
-    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @OptIn(ExperimentalTestApi::class)
     @Test
     fun timeInput_keyboardInput_valid() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = false)
@@ -412,7 +411,7 @@
         assertThat(state.hour).isEqualTo(4)
     }
 
-    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @OptIn(ExperimentalTestApi::class)
     @Test
     fun timeInput_keyboardInput_outOfRange() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = false)
@@ -431,7 +430,7 @@
         assertThat(state.hour).isEqualTo(4)
     }
 
-    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @OptIn(ExperimentalTestApi::class)
     @Test
     fun timeInput_keyboardInput_Nan() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = false)
@@ -483,7 +482,7 @@
     }
 
     @Test
-    @OptIn(ExperimentalComposeUiApi::class, ExperimentalTestApi::class)
+    @OptIn(ExperimentalTestApi::class)
     fun timeInput_24Hour_writeAfternoonHour() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = true)
 
@@ -501,6 +500,42 @@
     }
 
     @Test
+    @OptIn(ExperimentalTestApi::class)
+    fun timeInput_24Hour_writeNoon() {
+        val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = true)
+
+        rule.setMaterialContent(lightColorScheme()) {
+            TimeInput(state)
+        }
+
+        rule.onNodeWithText("10")
+            .performKeyInput {
+                pressKey(Key.One)
+                pressKey(Key.Two)
+            }
+
+        assertThat(state.hour).isEqualTo(12)
+    }
+
+    @Test
+    @OptIn(ExperimentalTestApi::class)
+    fun timeInput_24Hour_writeMidnight() {
+        val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = true)
+
+        rule.setMaterialContent(lightColorScheme()) {
+            TimeInput(state)
+        }
+
+        rule.onNodeWithText("10")
+            .performKeyInput {
+                pressKey(Key.Zero)
+                pressKey(Key.Zero)
+            }
+
+        assertThat(state.hour).isEqualTo(0)
+    }
+
+    @Test
     fun state_restoresTimePickerState() {
         val restorationTester = StateRestorationTester(rule)
         var state: TimePickerState?
@@ -520,6 +555,24 @@
     }
 
     @Test
+    fun state_12h_hourInitializationMatches() {
+        repeat(24) {
+            val state = TimePickerState(initialHour = it, initialMinute = 0, is24Hour = false)
+
+            assertThat(state.hour).isEqualTo(it)
+        }
+    }
+
+    @Test
+    fun state_24h_hourInitializationMatches() {
+        repeat(24) {
+            val state = TimePickerState(initialHour = it, initialMinute = 0, is24Hour = true)
+
+            assertThat(state.hour).isEqualTo(it)
+        }
+    }
+
+    @Test
     fun clockFace_24Hour_everyValue() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = true)
 
@@ -564,6 +617,15 @@
     }
 
     @Test
+    fun clockFace_12Hour_initAtNoon() {
+        val state = TimePickerState(initialHour = 12, initialMinute = 0, is24Hour = false)
+
+        assertThat(state.isAfternoonToggle).isTrue()
+
+        assertThat(state.hour).isEqualTo(12)
+    }
+
+    @Test
     fun clockFace_24HourMinutes_everyValue() {
         val state = TimePickerState(initialHour = 10, initialMinute = 23, is24Hour = true)
         state.selection = Selection.Minute
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
index 88a2417..cd1d852 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
@@ -1043,7 +1043,6 @@
     view: View,
     anchorCoordinates: LayoutCoordinates?,
     verticalMarginInPx: Int,
-    @Suppress("PrimitiveInLambda")
     onHeightUpdate: (Int) -> Unit
 ) {
     anchorCoordinates ?: return
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
index f5661fc..42b9c63 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
@@ -143,7 +143,6 @@
             }
         }
     }
-    @Suppress("PrimitiveInLambda")
     val settleToDismiss: (velocity: Float) -> Unit = {
         scope.launch { sheetState.settle(it) }.invokeOnCompletion {
             if (!sheetState.isVisible) onDismissRequest()
@@ -326,7 +325,6 @@
     sheetState: SheetState,
     anchorChangeHandler: AnchorChangeHandler<SheetValue>,
     screenHeight: Float,
-    @Suppress("PrimitiveInLambda")
     onDragStopped: CoroutineScope.(velocity: Float) -> Unit,
 ) = draggable(
         state = sheetState.swipeableState.swipeDraggableState,
@@ -356,7 +354,6 @@
 @ExperimentalMaterial3Api
 private fun ModalBottomSheetAnchorChangeHandler(
     state: SheetState,
-    @Suppress("PrimitiveInLambda")
     animateTo: (target: SheetValue, velocity: Float) -> Unit,
     snapTo: (target: SheetValue) -> Unit,
 ) = AnchorChangeHandler<SheetValue> { previousTarget, previousAnchors, newAnchors ->
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.kt
index 8b84f83..92c0bae 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/SearchBar.kt
@@ -65,9 +65,7 @@
 import androidx.compose.runtime.State
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
 import androidx.compose.runtime.structuralEqualityPolicy
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
@@ -93,7 +91,6 @@
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
@@ -695,30 +692,6 @@
     override fun calculateRightPadding(layoutDirection: LayoutDirection): Dp = 0.dp
 }
 
-/**
- * A [WindowInsets] whose values can change without changing the instance. This is useful
- * to avoid recomposition when [WindowInsets] can change.
- *
- * Copied from [androidx.compose.foundation.layout.MutableWindowInsets], which is marked as
- * experimental and thus cannot be used cross-module.
- */
-private class MutableWindowInsets(
-    initialInsets: WindowInsets = WindowInsets(0, 0, 0, 0)
-) : WindowInsets {
-    /**
-     * The [WindowInsets] that are used for [left][getLeft], [top][getTop], [right][getRight],
-     * and [bottom][getBottom] values.
-     */
-    var insets by mutableStateOf(initialInsets)
-
-    override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int =
-        insets.getLeft(density, layoutDirection)
-    override fun getTop(density: Density): Int = insets.getTop(density)
-    override fun getRight(density: Density, layoutDirection: LayoutDirection): Int =
-        insets.getRight(density, layoutDirection)
-    override fun getBottom(density: Density): Int = insets.getBottom(density)
-}
-
 // Measurement specs
 @OptIn(ExperimentalMaterial3Api::class)
 private val SearchBarCornerRadius: Dp = InputFieldHeight / 2
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
index e1799f9..8e30c16 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
@@ -915,15 +915,24 @@
  * Represents the colors used by a top app bar in different states.
  * This implementation animates the container color according to the top app bar scroll state. It
  * does not animate the leading, headline, or trailing colors.
+ *
+ * @constructor create an instance with arbitrary colors, see [TopAppBarColors] for a
+ * factory method using the default material3 spec
+ * @param containerColor the color used for the background of this BottomAppBar. Use
+ * [Color.Transparent] to have no color.
+ * @param scrolledContainerColor the container color when content is scrolled behind it
+ * @param navigationIconContentColor the content color used for the navigation icon
+ * @param titleContentColor the content color used for the title
+ * @param actionIconContentColor the content color used for actions
  */
 @ExperimentalMaterial3Api
 @Stable
-class TopAppBarColors internal constructor(
-    private val containerColor: Color,
-    private val scrolledContainerColor: Color,
-    internal val navigationIconContentColor: Color,
-    internal val titleContentColor: Color,
-    internal val actionIconContentColor: Color,
+class TopAppBarColors constructor(
+    val containerColor: Color,
+    val scrolledContainerColor: Color,
+    val navigationIconContentColor: Color,
+    val titleContentColor: Color,
+    val actionIconContentColor: Color,
 ) {
 
     /**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
index a3c5d6b..20adb98 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
@@ -318,11 +318,9 @@
     modifier: Modifier,
     topBar: @Composable (() -> Unit)?,
     body: @Composable (innerPadding: PaddingValues) -> Unit,
-    @Suppress("PrimitiveInLambda")
     bottomSheet: @Composable (layoutHeight: Int) -> Unit,
     snackbarHost: @Composable () -> Unit,
     sheetPeekHeight: Dp,
-    @Suppress("PrimitiveInLambda")
     sheetOffset: () -> Float,
     sheetState: SheetState,
     containerColor: Color,
@@ -375,7 +373,6 @@
 @ExperimentalMaterial3Api
 private fun BottomSheetScaffoldAnchorChangeHandler(
     state: SheetState,
-    @Suppress("PrimitiveInLambda")
     animateTo: (target: SheetValue, velocity: Float) -> Unit,
     snapTo: (target: SheetValue) -> Unit,
 ) = AnchorChangeHandler<SheetValue> { previousTarget, previousAnchors, newAnchors ->
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 6580872..47cbc44 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
@@ -905,16 +905,21 @@
 /**
  * Represents the container and content colors used in a button in different states.
  *
+ *  @constructor create an instance with arbitrary colors.
  * - See [ButtonDefaults.buttonColors] for the default colors used in a [Button].
  * - See [ButtonDefaults.elevatedButtonColors] for the default colors used in a [ElevatedButton].
  * - See [ButtonDefaults.textButtonColors] for the default colors used in a [TextButton].
+ * @param containerColor the container color of this [Button] when enabled.
+ * @param contentColor the content color of this [Button] when enabled.
+ * @param disabledContainerColor the container color of this [Button] when not enabled.
+ * @param disabledContentColor the content color of this [Button] when not enabled.
  */
 @Immutable
-class ButtonColors internal constructor(
-    private val containerColor: Color,
-    private val contentColor: Color,
-    private val disabledContainerColor: Color,
-    private val disabledContentColor: Color,
+class ButtonColors constructor(
+    val containerColor: Color,
+    val contentColor: Color,
+    val disabledContainerColor: Color,
+    val disabledContentColor: Color,
 ) {
     /**
      * Represents the container color for this button, depending on [enabled].
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 e952287..cf4ce4c 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
@@ -720,16 +720,22 @@
 /**
  * Represents the container and content colors used in a card in different states.
  *
+ * @constructor create an instance with arbitrary colors.
  * - See [CardDefaults.cardColors] for the default colors used in a [Card].
  * - See [CardDefaults.elevatedCardColors] for the default colors used in a [ElevatedCard].
  * - See [CardDefaults.outlinedCardColors] for the default colors used in a [OutlinedCard].
+ *
+ * @param containerColor the container color of this [Card] when enabled.
+ * @param contentColor the content color of this [Card] when enabled.
+ * @param disabledContainerColor the container color of this [Card] when not enabled.
+ * @param disabledContentColor the content color of this [Card] when not enabled.
  */
 @Immutable
-class CardColors internal constructor(
-    private val containerColor: Color,
-    private val contentColor: Color,
-    private val disabledContainerColor: Color,
-    private val disabledContentColor: Color,
+class CardColors constructor(
+    val containerColor: Color,
+    val contentColor: Color,
+    val disabledContainerColor: Color,
+    val disabledContentColor: Color,
 ) {
     /**
      * Represents the container color for this card, depending on [enabled].
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 010b841..55571a3 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
@@ -373,22 +373,38 @@
  * Represents the colors used by the three different sections (checkmark, box, and border) of a
  * [Checkbox] or [TriStateCheckbox] in different states.
  *
- * See [CheckboxDefaults.colors] for the default implementation that follows Material
- * specifications.
+ * @constructor create an instance with arbitrary colors, see [CheckboxDefaults.colors] for the
+ * default implementation that follows Material specifications.
+ *
+ * @param checkedCheckmarkColor color that will be used for the checkmark when checked
+ * @param uncheckedCheckmarkColor color that will be used for the checkmark when unchecked
+ * @param checkedBoxColor the color that will be used for the box when checked
+ * @param uncheckedBoxColor color that will be used for the box when unchecked
+ * @param disabledCheckedBoxColor color that will be used for the box when disabled and
+ * checked
+ * @param disabledUncheckedBoxColor color that will be used for the box and border when disabled
+ * and not checked
+ * @param disabledIndeterminateBoxColor color that will be used for the box and
+ * border in a [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state.
+ * @param checkedBorderColor color that will be used for the border when checked
+ * @param uncheckedBorderColor color that will be used for the border when unchecked
+ * @param disabledBorderColor color that will be used for the border when disabled
+ * @param disabledIndeterminateBorderColor color that will be used for the border when in an
+ * [ToggleableState.Indeterminate] state.
  */
 @Immutable
-class CheckboxColors internal constructor(
-    private val checkedCheckmarkColor: Color,
-    private val uncheckedCheckmarkColor: Color,
-    private val checkedBoxColor: Color,
-    private val uncheckedBoxColor: Color,
-    private val disabledCheckedBoxColor: Color,
-    private val disabledUncheckedBoxColor: Color,
-    private val disabledIndeterminateBoxColor: Color,
-    private val checkedBorderColor: Color,
-    private val uncheckedBorderColor: Color,
-    private val disabledBorderColor: Color,
-    private val disabledIndeterminateBorderColor: Color
+class CheckboxColors constructor(
+    val checkedCheckmarkColor: Color,
+    val uncheckedCheckmarkColor: Color,
+    val checkedBoxColor: Color,
+    val uncheckedBoxColor: Color,
+    val disabledCheckedBoxColor: Color,
+    val disabledUncheckedBoxColor: Color,
+    val disabledIndeterminateBoxColor: Color,
+    val checkedBorderColor: Color,
+    val uncheckedBorderColor: Color,
+    val disabledBorderColor: Color,
+    val disabledIndeterminateBorderColor: Color
 ) {
     /**
      * Represents the color used for the checkmark inside the checkbox, depending on [state].
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 6f2b7ac..897d1d4 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
@@ -1599,16 +1599,22 @@
  * Note that this default implementation does not take into consideration the `selectable` state
  * passed into its [tonalElevation] and [shadowElevation]. If you wish to apply that state, use a
  * different [SelectableChipElevation].
+ *
+ * @param pressedElevation the elevation used when the chip is pressed.
+ * @param focusedElevation the elevation used when the chip is focused
+ * @param hoveredElevation the elevation used when the chip is hovered
+ * @param draggedElevation the elevation used when the chip is dragged
+ * @param disabledElevation the elevation used when the chip is not enabled
  */
 @ExperimentalMaterial3Api
 @Immutable
 class SelectableChipElevation internal constructor(
-    private val elevation: Dp,
-    private val pressedElevation: Dp,
-    private val focusedElevation: Dp,
-    private val hoveredElevation: Dp,
-    private val draggedElevation: Dp,
-    private val disabledElevation: Dp
+    val elevation: Dp,
+    val pressedElevation: Dp,
+    val focusedElevation: Dp,
+    val hoveredElevation: Dp,
+    val draggedElevation: Dp,
+    val disabledElevation: Dp
 ) {
     /**
      * Represents the tonal elevation used in a chip, depending on [enabled] and
@@ -1753,19 +1759,29 @@
 /**
  * Represents the container and content colors used in a clickable chip in different states.
  *
- * See [AssistChipDefaults], [InputChipDefaults], and [SuggestionChipDefaults] for the default
- * colors used in the various Chip configurations.
+ * @constructor create an instance with arbitrary colors, see [AssistChipDefaults],
+ * [InputChipDefaults], and [SuggestionChipDefaults] for the default colors used in the various Chip
+ * configurations.
+ *
+ * @param containerColor the container color of this chip when enabled
+ * @param labelColor the label color of this chip when enabled
+ * @param leadingIconContentColor the color of this chip's start icon when enabled
+ * @param trailingIconContentColor the color of this chip's end icon when enabled
+ * @param disabledContainerColor the container color of this chip when not enabled
+ * @param disabledLabelColor the label color of this chip when not enabled
+ * @param disabledLeadingIconContentColor the color of this chip's start icon when not enabled
+ * @param disabledTrailingIconContentColor the color of this chip's end icon when not enabled
  */
 @Immutable
-class ChipColors internal constructor(
-    private val containerColor: Color,
-    private val labelColor: Color,
-    private val leadingIconContentColor: Color,
-    private val trailingIconContentColor: Color,
-    private val disabledContainerColor: Color,
-    private val disabledLabelColor: Color,
-    private val disabledLeadingIconContentColor: Color,
-    private val disabledTrailingIconContentColor: Color
+class ChipColors constructor(
+    val containerColor: Color,
+    val labelColor: Color,
+    val leadingIconContentColor: Color,
+    val trailingIconContentColor: Color,
+    val disabledContainerColor: Color,
+    val disabledLabelColor: Color,
+    val disabledLeadingIconContentColor: Color,
+    val disabledTrailingIconContentColor: Color
     // TODO(b/113855296): Support other states: hover, focus, drag
 ) {
     /**
@@ -1850,7 +1866,7 @@
  */
 @ExperimentalMaterial3Api
 @Immutable
-class SelectableChipColors internal constructor(
+class SelectableChipColors constructor(
     private val containerColor: Color,
     private val labelColor: Color,
     private val leadingIconColor: Color,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
index d3341f6..6e05d30 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateInput.kt
@@ -47,7 +47,6 @@
 @Composable
 internal fun DateInputContent(
     selectedDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (dateInMillis: Long?) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -106,7 +105,6 @@
 internal fun DateInputTextField(
     modifier: Modifier,
     initialDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (Long?) -> Unit,
     calendarModel: CalendarModel,
     label: @Composable (() -> Unit)?,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
index 8ff82a1..e6581d6 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DatePicker.kt
@@ -640,37 +640,72 @@
 /**
  * Represents the colors used by the date picker.
  *
- * See [DatePickerDefaults.colors] for the default implementation that follows Material
- * specifications.
+ * @constructor create an instance with arbitrary colors, see [DatePickerDefaults.colors] for the
+ * default implementation that follows Material specifications.
+ *
+ * @param containerColor the color used for the date picker's background
+ * @param titleContentColor the color used for the date picker's title
+ * @param headlineContentColor the color used for the date picker's headline
+ * @param weekdayContentColor the color used for the weekday letters
+ * @param subheadContentColor the color used for the month and year subhead labels that appear
+ * when months are displayed at a `DateRangePicker`.
+ * @param navigationContentColor the content color used for the year selection menu button and
+ * the months arrow navigation when displayed at a `DatePicker`.
+ * @param yearContentColor the color used for a year item content
+ * @param disabledYearContentColor the color used for a disabled year item content
+ * @param currentYearContentColor the color used for the current year content when selecting a
+ * year
+ * @param selectedYearContentColor the color used for a selected year item content
+ * @param disabledSelectedYearContentColor the color used for a disabled selected year item
+ * content
+ * @param selectedYearContainerColor the color used for a selected year item container
+ * @param disabledSelectedYearContainerColor the color used for a disabled selected year item
+ * container
+ * @param dayContentColor the color used for days content
+ * @param disabledDayContentColor the color used for disabled days content
+ * @param selectedDayContentColor the color used for selected days content
+ * @param disabledSelectedDayContentColor the color used for disabled selected days content
+ * @param selectedDayContainerColor the color used for a selected day container
+ * @param disabledSelectedDayContainerColor the color used for a disabled selected day container
+ * @param todayContentColor the color used for the day that marks the current date
+ * @param todayDateBorderColor the color used for the border of the day that marks the current
+ * date
+ * @param dayInSelectionRangeContentColor the content color used for days that are within a date
+ * range selection
+ * @param dayInSelectionRangeContainerColor the container color used for days that are within a
+ * date range selection
+ * @param dividerColor the color used for the dividers used at the date pickers
+ * @param dateTextFieldColors the [TextFieldColors] defaults for the date text field when in
+ * [DisplayMode.Input]. See [OutlinedTextFieldDefaults.colors].
  */
 @ExperimentalMaterial3Api
 @Immutable
-class DatePickerColors internal constructor(
-    internal val containerColor: Color,
-    internal val titleContentColor: Color,
-    internal val headlineContentColor: Color,
-    internal val weekdayContentColor: Color,
-    internal val subheadContentColor: Color,
-    internal val navigationContentColor: Color,
-    private val yearContentColor: Color,
-    private val disabledYearContentColor: Color,
-    private val currentYearContentColor: Color,
-    private val selectedYearContentColor: Color,
-    private val disabledSelectedYearContentColor: Color,
-    private val selectedYearContainerColor: Color,
-    private val disabledSelectedYearContainerColor: Color,
-    private val dayContentColor: Color,
-    private val disabledDayContentColor: Color,
-    private val selectedDayContentColor: Color,
-    private val disabledSelectedDayContentColor: Color,
-    private val selectedDayContainerColor: Color,
-    private val disabledSelectedDayContainerColor: Color,
-    private val todayContentColor: Color,
-    internal val todayDateBorderColor: Color,
-    internal val dayInSelectionRangeContainerColor: Color,
-    private val dayInSelectionRangeContentColor: Color,
-    internal val dividerColor: Color,
-    internal val dateTextFieldColors: TextFieldColors
+class DatePickerColors constructor(
+    val containerColor: Color,
+    val titleContentColor: Color,
+    val headlineContentColor: Color,
+    val weekdayContentColor: Color,
+    val subheadContentColor: Color,
+    val navigationContentColor: Color,
+    val yearContentColor: Color,
+    val disabledYearContentColor: Color,
+    val currentYearContentColor: Color,
+    val selectedYearContentColor: Color,
+    val disabledSelectedYearContentColor: Color,
+    val selectedYearContainerColor: Color,
+    val disabledSelectedYearContainerColor: Color,
+    val dayContentColor: Color,
+    val disabledDayContentColor: Color,
+    val selectedDayContentColor: Color,
+    val disabledSelectedDayContentColor: Color,
+    val selectedDayContainerColor: Color,
+    val disabledSelectedDayContainerColor: Color,
+    val todayContentColor: Color,
+    val todayDateBorderColor: Color,
+    val dayInSelectionRangeContainerColor: Color,
+    val dayInSelectionRangeContentColor: Color,
+    val dividerColor: Color,
+    val dateTextFieldColors: TextFieldColors
 ) {
     /**
      * Represents the content color for a calendar day.
@@ -1136,7 +1171,6 @@
 internal fun DisplayModeToggleButton(
     modifier: Modifier,
     displayMode: DisplayMode,
-    @Suppress("PrimitiveInLambda")
     onDisplayModeChange: (DisplayMode) -> Unit
 ) {
     if (displayMode == DisplayMode.Picker) {
@@ -1166,9 +1200,7 @@
     selectedDateMillis: Long?,
     displayedMonthMillis: Long,
     displayMode: DisplayMode,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (dateInMillis: Long?) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -1256,9 +1288,7 @@
 private fun DatePickerContent(
     selectedDateMillis: Long?,
     displayedMonthMillis: Long,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (dateInMillis: Long) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -1411,9 +1441,7 @@
 private fun HorizontalMonthsList(
     lazyListState: LazyListState,
     selectedDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (dateInMillis: Long) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -1476,7 +1504,6 @@
 @OptIn(ExperimentalMaterial3Api::class)
 internal suspend fun updateDisplayedMonth(
     lazyListState: LazyListState,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange
@@ -1550,7 +1577,6 @@
 @Composable
 internal fun Month(
     month: CalendarMonth,
-    @Suppress("PrimitiveInLambda")
     onDateSelectionChange: (dateInMillis: Long) -> Unit,
     todayMillis: Long,
     startDateMillis: Long?,
@@ -1767,7 +1793,6 @@
 private fun YearPicker(
     modifier: Modifier,
     displayedMonthMillis: Long,
-    @Suppress("PrimitiveInLambda")
     onYearSelected: (year: Int) -> Unit,
     selectableDates: SelectableDates,
     calendarModel: CalendarModel,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt
index 6f72678..5ffb509 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangeInput.kt
@@ -32,7 +32,6 @@
 internal fun DateRangeInputContent(
     selectedStartDateMillis: Long?,
     selectedEndDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
index a26272b..5e1e430 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DateRangePicker.kt
@@ -611,9 +611,7 @@
     selectedEndDateMillis: Long?,
     displayedMonthMillis: Long,
     displayMode: DisplayMode,
-    @Suppress("PrimitiveInLambda")
     onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -664,9 +662,7 @@
     selectedStartDateMillis: Long?,
     selectedEndDateMillis: Long?,
     displayedMonthMillis: Long,
-    @Suppress("PrimitiveInLambda")
     onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -704,9 +700,7 @@
     lazyListState: LazyListState,
     selectedStartDateMillis: Long?,
     selectedEndDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit,
-    @Suppress("PrimitiveInLambda")
     onDisplayedMonthChange: (monthInMillis: Long) -> Unit,
     calendarModel: CalendarModel,
     yearRange: IntRange,
@@ -784,7 +778,6 @@
                         }
                     // The updateDateSelection will invoke the onDatesSelectionChange with the proper
                     // selection according to the current state.
-                    @Suppress("PrimitiveInLambda")
                     val onDateSelectionChange = { dateInMillis: Long ->
                         updateDateSelection(
                             dateInMillis = dateInMillis,
@@ -823,7 +816,6 @@
     dateInMillis: Long,
     currentStartDateMillis: Long?,
     currentEndDateMillis: Long?,
-    @Suppress("PrimitiveInLambda")
     onDatesSelectionChange: (startDateMillis: Long?, endDateMillis: Long?) -> Unit
 ) {
     if ((currentStartDateMillis == null && currentEndDateMillis == null) ||
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DragGestureDetectorCopy.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DragGestureDetectorCopy.kt
index b6eb31d..410bc38 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DragGestureDetectorCopy.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/DragGestureDetectorCopy.kt
@@ -37,7 +37,6 @@
 internal suspend fun AwaitPointerEventScope.awaitHorizontalPointerSlopOrCancellation(
     pointerId: PointerId,
     pointerType: PointerType,
-    @Suppress("PrimitiveInLambda")
     onPointerSlopReached: (change: PointerInputChange, overSlop: Float) -> Unit
 ) = awaitPointerSlopOrCancellation(
     pointerId = pointerId,
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 abacad1..51ae14d 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
@@ -801,18 +801,24 @@
 /**
  * Represents the container and content colors used in an icon button in different states.
  *
+ * @constructor create an instance with arbitrary colors.
  * - See [IconButtonDefaults.filledIconButtonColors] and
  * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a
  * [FilledIconButton].
  * - See [IconButtonDefaults.outlinedIconButtonColors] for the default colors used in an
  * [OutlinedIconButton].
+ *
+ * @param containerColor the container color of this icon button when enabled.
+ * @param contentColor the content color of this icon button when enabled.
+ * @param disabledContainerColor the container color of this icon button when not enabled.
+ * @param disabledContentColor the content color of this icon button when not enabled.
  */
 @Immutable
-class IconButtonColors internal constructor(
-    private val containerColor: Color,
-    private val contentColor: Color,
-    private val disabledContainerColor: Color,
-    private val disabledContentColor: Color,
+class IconButtonColors constructor(
+    val containerColor: Color,
+    val contentColor: Color,
+    val disabledContainerColor: Color,
+    val disabledContentColor: Color,
 ) {
     /**
      * Represents the container color for this icon button, depending on [enabled].
@@ -860,20 +866,28 @@
  * Represents the container and content colors used in a toggleable icon button in
  * different states.
  *
+ * @constructor create an instance with arbitrary colors.
  * - See [IconButtonDefaults.filledIconToggleButtonColors] and
  * [IconButtonDefaults.filledTonalIconToggleButtonColors] for the default colors used in a
  * [FilledIconButton].
  * - See [IconButtonDefaults.outlinedIconToggleButtonColors] for the default colors used in a
  *  toggleable [OutlinedIconButton].
+ *
+ * @param containerColor the container color of this icon button when enabled.
+ * @param contentColor the content color of this icon button when enabled.
+ * @param disabledContainerColor the container color of this icon button when not enabled.
+ * @param disabledContentColor the content color of this icon button when not enabled.
+ * @param checkedContainerColor the container color of this icon button when checked.
+ * @param checkedContentColor the content color of this icon button when checked.
  */
 @Immutable
-class IconToggleButtonColors internal constructor(
-    private val containerColor: Color,
-    private val contentColor: Color,
-    private val disabledContainerColor: Color,
-    private val disabledContentColor: Color,
-    private val checkedContainerColor: Color,
-    private val checkedContentColor: Color,
+class IconToggleButtonColors constructor(
+    val containerColor: Color,
+    val contentColor: Color,
+    val disabledContainerColor: Color,
+    val disabledContentColor: Color,
+    val checkedContainerColor: Color,
+    val checkedContentColor: Color,
 ) {
     /**
      * Represents the container color for this icon button, depending on [enabled] and [checked].
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
index ae11486..7f82383 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ListItem.kt
@@ -16,13 +16,11 @@
 
 package androidx.compose.material3
 
-import androidx.compose.foundation.layout.Arrangement
+import androidx.annotation.VisibleForTesting
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.calculateEndPadding
+import androidx.compose.foundation.layout.calculateStartPadding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.material3.tokens.ListTokens
 import androidx.compose.material3.tokens.TypographyKeyTokens
@@ -32,14 +30,24 @@
 import androidx.compose.runtime.ReadOnlyComposable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Alignment.Companion.CenterVertically
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.FirstBaseline
+import androidx.compose.ui.layout.LastBaseline
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.layout.Placeable
+import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.offset
+import kotlin.math.max
 
 /**
  * <a href="https://m3.material.io/components/lists/overview" class="external" target="_blank">Material Design list item.</a>
@@ -56,8 +64,10 @@
  * @sample androidx.compose.material3.samples.OneLineListItem
  * - two-line item
  * @sample androidx.compose.material3.samples.TwoLineListItem
- * - three-line item
- * @sample androidx.compose.material3.samples.ThreeLineListItem
+ * - three-line item with both overline and supporting content
+ * @sample androidx.compose.material3.samples.ThreeLineListItemWithOverlineAndSupporting
+ * - three-line item with extended supporting content
+ * @sample androidx.compose.material3.samples.ThreeLineListItemWithExtendedSupporting
  *
  * @param headlineContent the headline content of the list item
  * @param modifier [Modifier] to be applied to the list item
@@ -90,7 +100,7 @@
         )
     }
     val decoratedSupportingContent: @Composable (() -> Unit)? = supportingContent?.let {
-        @Composable {
+        {
             ProvideTextStyleFromToken(
                 colors.supportingColor().value,
                 ListTokens.ListItemSupportingTextFont,
@@ -99,7 +109,7 @@
         }
     }
     val decoratedOverlineContent: @Composable (() -> Unit)? = overlineContent?.let {
-        @Composable {
+        {
             ProvideTextStyleFromToken(
                 colors.overlineColor().value,
                 ListTokens.ListItemOverlineFont,
@@ -107,153 +117,264 @@
             )
         }
     }
-
-    val listItemType = ListItemType.getListItemType(
-        hasOverline = decoratedOverlineContent != null,
-        hasSupporting = decoratedSupportingContent != null
-    )
-    val isThreeLine = listItemType == ListItemType.ThreeLine
-
-    val decoratedLeadingContent: @Composable (RowScope.() -> Unit)? = leadingContent?.let {
+    val decoratedLeadingContent: @Composable (() -> Unit)? = leadingContent?.let {
         {
-            LeadingContent(
-                contentColor = colors.leadingIconColor(enabled = true).value,
-                topAlign = isThreeLine,
-                content = it
-            )
+            Box(Modifier.padding(end = LeadingContentEndPadding)) {
+                CompositionLocalProvider(
+                    LocalContentColor provides colors.leadingIconColor(enabled = true).value,
+                    content = it
+                )
+            }
+        }
+    }
+    val decoratedTrailingContent: @Composable (() -> Unit)? = trailingContent?.let {
+        {
+            Box(Modifier.padding(start = TrailingContentStartPadding)) {
+                ProvideTextStyleFromToken(
+                    colors.trailingIconColor(enabled = true).value,
+                    ListTokens.ListItemTrailingSupportingTextFont,
+                    content = it
+                )
+            }
         }
     }
 
-    val decoratedTrailingContent: @Composable (RowScope.() -> Unit)? = trailingContent?.let {
-        {
-            TrailingContent(
-                contentColor = colors.trailingIconColor(enabled = true).value,
-                topAlign = isThreeLine,
-                content = it
-            )
-        }
-    }
-    val minHeight: Dp = when (listItemType) {
-        ListItemType.OneLine -> ListTokens.ListItemOneLineContainerHeight
-        ListItemType.TwoLine -> ListTokens.ListItemTwoLineContainerHeight
-        else -> ListTokens.ListItemThreeLineContainerHeight // 3
-    }
-    val verticalPadding = if (isThreeLine) ListItemThreeLineVerticalPadding else
-        ListItemVerticalPadding
-    val outerPaddingValues =
-        PaddingValues(
-            start = ListItemStartPadding,
-            top = verticalPadding,
-            end = ListItemEndPadding,
-            bottom = verticalPadding,
-        )
-
-    ListItem(
-        modifier = modifier,
-        containerColor = colors.containerColor().value,
+    Surface(
+        modifier = Modifier.semantics(mergeDescendants = true) {}.then(modifier),
+        shape = ListItemDefaults.shape,
+        color = colors.containerColor().value,
         contentColor = colors.headlineColor(enabled = true).value,
         tonalElevation = tonalElevation,
         shadowElevation = shadowElevation,
-        minHeight = minHeight,
-        paddingValues = outerPaddingValues
     ) {
-        if (decoratedLeadingContent != null) {
-            decoratedLeadingContent()
-        }
-        Column(
-            modifier = Modifier
-                .weight(1f)
-                .align(if (isThreeLine) Alignment.Top else CenterVertically),
-            verticalArrangement = if (isThreeLine) Arrangement.Top else Arrangement.Center
-        ) {
-            if (decoratedOverlineContent != null) {
-                decoratedOverlineContent()
-            }
-            decoratedHeadlineContent()
-            if (decoratedSupportingContent != null) {
-                decoratedSupportingContent()
-            }
-        }
-        if (decoratedTrailingContent != null) {
-            decoratedTrailingContent()
-        }
+        ListItemLayout(
+            headline = decoratedHeadlineContent,
+            overline = decoratedOverlineContent,
+            supporting = decoratedSupportingContent,
+            leading = decoratedLeadingContent,
+            trailing = decoratedTrailingContent,
+        )
     }
 }
 
-// TODO(b/233782301): Complete 3-line list item
-/**
- * <a href="https://m3.material.io/components/lists/overview" class="external" target="_blank">Material Design list item.</a>
- *
- * Lists are continuous, vertical indexes of text or images. For more opinionated List Items,
- * consider using another overload
- *
- * @param modifier [Modifier] to be applied to the list item
- * @param shape defines the list item's shape
- * @param containerColor the container color of this list item
- * @param contentColor the content color of this list item
- * @param tonalElevation the tonal elevation of this list item
- * @param shadowElevation the shadow elevation of this list item
- * @param content the content to be displayed in the middle section of this list item
- */
 @Composable
-private fun ListItem(
-    modifier: Modifier = Modifier,
-    shape: Shape = ListItemDefaults.shape,
-    containerColor: Color = ListItemDefaults.containerColor,
-    contentColor: Color = ListItemDefaults.contentColor,
-    tonalElevation: Dp = ListItemDefaults.Elevation,
-    shadowElevation: Dp = ListItemDefaults.Elevation,
-    minHeight: Dp,
-    paddingValues: PaddingValues,
-    content: @Composable RowScope.() -> Unit,
+private fun ListItemLayout(
+    leading: @Composable (() -> Unit)?,
+    trailing: @Composable (() -> Unit)?,
+    headline: @Composable () -> Unit,
+    overline: @Composable (() -> Unit)?,
+    supporting: @Composable (() -> Unit)?,
 ) {
-    val semanticModifier = Modifier.semantics(mergeDescendants = true) { }.then(modifier)
-    Surface(
-        modifier = semanticModifier,
-        shape = shape,
-        color = containerColor,
-        contentColor = contentColor,
-        tonalElevation = tonalElevation,
-        shadowElevation = shadowElevation,
-    ) {
-        Row(
-            modifier = Modifier
-                .heightIn(min = minHeight)
-                .padding(paddingValues),
-            content = content
+    val layoutDirection = LocalLayoutDirection.current
+    Layout(
+        contents = listOf(
+            headline,
+            overline ?: {},
+            supporting ?: {},
+            leading ?: {},
+            trailing ?: {},
+        )
+    ) { measurables, constraints ->
+        val (headlineMeasurable, overlineMeasurable, supportingMeasurable, leadingMeasurable,
+            trailingMeasurable) = measurables
+        var currentTotalWidth = 0
+
+        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)
+            .offset(
+                horizontal = -(ListItemStartPadding + ListItemEndPadding).roundToPx(),
+                vertical = -(ListItemVerticalPadding * 2).roundToPx()
+            )
+
+        val leadingPlaceable = leadingMeasurable.firstOrNull()?.measure(looseConstraints)
+        currentTotalWidth += widthOrZero(leadingPlaceable)
+
+        val trailingPlaceable = trailingMeasurable.firstOrNull()?.measure(
+            looseConstraints.offset(
+                horizontal = -currentTotalWidth
+            ))
+        currentTotalWidth += widthOrZero(trailingPlaceable)
+
+        var currentTotalHeight = 0
+
+        val headlinePlaceable = headlineMeasurable.first().measure(
+            looseConstraints.offset(
+                horizontal = -currentTotalWidth
+            ))
+        currentTotalHeight += headlinePlaceable.height
+
+        val supportingPlaceable = supportingMeasurable.firstOrNull()?.measure(
+            looseConstraints.offset(
+                horizontal = -currentTotalWidth,
+                vertical = -currentTotalHeight
+            ))
+        currentTotalHeight += heightOrZero(supportingPlaceable)
+        val isSupportingMultiline = supportingPlaceable != null &&
+            (supportingPlaceable[FirstBaseline] != supportingPlaceable[LastBaseline])
+
+        val overlinePlaceable = overlineMeasurable.firstOrNull()?.measure(
+            looseConstraints.offset(
+                horizontal = -currentTotalWidth,
+                vertical = -currentTotalHeight
+            ))
+
+        val listItemType = ListItemType.getListItemType(
+            hasOverline = overlinePlaceable != null,
+            hasSupporting = supportingPlaceable != null,
+            isSupportingMultiline = isSupportingMultiline
+        )
+        val isThreeLine = listItemType == ListItemType.ThreeLine
+
+        val paddingValues = PaddingValues(
+            start = ListItemStartPadding,
+            end = ListItemEndPadding,
+            top = if (isThreeLine) ListItemThreeLineVerticalPadding else ListItemVerticalPadding,
+            bottom = if (isThreeLine) ListItemThreeLineVerticalPadding else ListItemVerticalPadding,
+        )
+
+        val width = calculateWidth(
+            leadingPlaceable = leadingPlaceable,
+            trailingPlaceable = trailingPlaceable,
+            headlinePlaceable = headlinePlaceable,
+            overlinePlaceable = overlinePlaceable,
+            supportingPlaceable = supportingPlaceable,
+            paddingValues = paddingValues,
+            layoutDirection = layoutDirection,
+            constraints = constraints,
+        )
+        val height = calculateHeight(
+            leadingPlaceable = leadingPlaceable,
+            trailingPlaceable = trailingPlaceable,
+            headlinePlaceable = headlinePlaceable,
+            overlinePlaceable = overlinePlaceable,
+            supportingPlaceable = supportingPlaceable,
+            listItemType = listItemType,
+            paddingValues = paddingValues,
+            constraints = constraints,
+        )
+
+        place(
+            width = width,
+            height = height,
+            leadingPlaceable = leadingPlaceable,
+            trailingPlaceable = trailingPlaceable,
+            headlinePlaceable = headlinePlaceable,
+            overlinePlaceable = overlinePlaceable,
+            supportingPlaceable = supportingPlaceable,
+            isThreeLine = isThreeLine,
+            layoutDirection = layoutDirection,
+            paddingValues = paddingValues,
         )
     }
 }
 
-@Composable
-private fun RowScope.LeadingContent(
-    contentColor: Color,
-    topAlign: Boolean,
-    content: @Composable () -> Unit,
-) = CompositionLocalProvider(LocalContentColor provides contentColor) {
-        Box(
-            Modifier
-                .padding(end = LeadingContentEndPadding)
-                .then(if (!topAlign) Modifier.align(CenterVertically) else Modifier),
-        ) { content() }
+private fun MeasureScope.calculateWidth(
+    leadingPlaceable: Placeable?,
+    trailingPlaceable: Placeable?,
+    headlinePlaceable: Placeable,
+    overlinePlaceable: Placeable?,
+    supportingPlaceable: Placeable?,
+    layoutDirection: LayoutDirection,
+    paddingValues: PaddingValues,
+    constraints: Constraints,
+): Int {
+    if (constraints.hasBoundedWidth) {
+        return constraints.maxWidth
     }
+    // Fallback behavior if width constraints are infinite
+    val horizontalPadding = (paddingValues.calculateLeftPadding(layoutDirection) +
+        paddingValues.calculateRightPadding(layoutDirection)).roundToPx()
+    val mainContentWidth = maxOf(
+        headlinePlaceable.width,
+        widthOrZero(overlinePlaceable),
+        widthOrZero(supportingPlaceable),
+    )
+    return horizontalPadding +
+        widthOrZero(leadingPlaceable) +
+        mainContentWidth +
+        widthOrZero(trailingPlaceable)
+}
 
-@Composable
-private fun RowScope.TrailingContent(
-    contentColor: Color,
-    topAlign: Boolean,
-    content: @Composable () -> Unit,
-) = Box(
-    Modifier
-        .padding(start = TrailingContentStartPadding)
-        .then(if (!topAlign) Modifier.align(CenterVertically) else Modifier),
-    ) {
-        ProvideTextStyleFromToken(
-            contentColor,
-            ListTokens.ListItemTrailingSupportingTextFont,
-            content
-        )
+private fun MeasureScope.calculateHeight(
+    leadingPlaceable: Placeable?,
+    trailingPlaceable: Placeable?,
+    headlinePlaceable: Placeable,
+    overlinePlaceable: Placeable?,
+    supportingPlaceable: Placeable?,
+    listItemType: ListItemType,
+    paddingValues: PaddingValues,
+    constraints: Constraints,
+): Int {
+    val defaultMinHeight = when (listItemType) {
+        ListItemType.OneLine -> ListTokens.ListItemOneLineContainerHeight
+        ListItemType.TwoLine -> ListTokens.ListItemTwoLineContainerHeight
+        else /* ListItemType.ThreeLine */ -> ListTokens.ListItemThreeLineContainerHeight
     }
+    val minHeight = max(constraints.minHeight, defaultMinHeight.roundToPx())
+
+    val verticalPadding =
+        paddingValues.calculateTopPadding() + paddingValues.calculateBottomPadding()
+
+    val mainContentHeight = headlinePlaceable.height +
+        heightOrZero(overlinePlaceable) +
+        heightOrZero(supportingPlaceable)
+
+    return max(
+        minHeight,
+        verticalPadding.roundToPx() + maxOf(
+            heightOrZero(leadingPlaceable),
+            mainContentHeight,
+            heightOrZero(trailingPlaceable),
+        )
+    ).coerceAtMost(constraints.maxHeight)
+}
+
+private fun MeasureScope.place(
+    width: Int,
+    height: Int,
+    leadingPlaceable: Placeable?,
+    trailingPlaceable: Placeable?,
+    headlinePlaceable: Placeable,
+    overlinePlaceable: Placeable?,
+    supportingPlaceable: Placeable?,
+    isThreeLine: Boolean,
+    layoutDirection: LayoutDirection,
+    paddingValues: PaddingValues,
+): MeasureResult {
+    return layout(width, height) {
+        val startPadding = paddingValues.calculateStartPadding(layoutDirection).roundToPx()
+        val endPadding = paddingValues.calculateEndPadding(layoutDirection).roundToPx()
+        val topPadding = paddingValues.calculateTopPadding().roundToPx()
+
+        leadingPlaceable?.let {
+            it.placeRelative(
+                x = startPadding,
+                y = if (isThreeLine) topPadding else CenterVertically.align(it.height, height)
+            )
+        }
+        trailingPlaceable?.let {
+            it.placeRelative(
+                x = width - endPadding - it.width,
+                y = if (isThreeLine) topPadding else CenterVertically.align(it.height, height)
+            )
+        }
+
+        val mainContentX = startPadding + widthOrZero(leadingPlaceable)
+        val mainContentY = if (isThreeLine) { topPadding } else {
+            val totalHeight = headlinePlaceable.height + heightOrZero(overlinePlaceable) +
+                heightOrZero(supportingPlaceable)
+            CenterVertically.align(totalHeight, height)
+        }
+        var currentY = mainContentY
+
+        overlinePlaceable?.placeRelative(mainContentX, currentY)
+        currentY += heightOrZero(overlinePlaceable)
+
+        headlinePlaceable.placeRelative(mainContentX, currentY)
+        currentY += headlinePlaceable.height
+
+        supportingPlaceable?.placeRelative(mainContentX, currentY)
+    }
+}
 
 /**
  * Contains the default values used by list items.
@@ -325,19 +446,33 @@
 /**
  * Represents the container and content colors used in a list item in different states.
  *
- * - See [ListItemDefaults.colors] for the default colors used in a [ListItem].
+ * @constructor create an instance with arbitrary colors.
+ * See [ListItemDefaults.colors] for the default colors used in a [ListItem].
+ *
+ * @param containerColor the container color of this list item when enabled.
+ * @param headlineColor the headline text content color of this list item when
+ * enabled.
+ * @param leadingIconColor the color of this list item's leading content when enabled.
+ * @param overlineColor the overline text color of this list item
+ * @param supportingTextColor the supporting text color of this list item
+ * @param trailingIconColor the color of this list item's trailing content when enabled.
+ * @param disabledHeadlineColor the content color of this list item when not enabled.
+ * @param disabledLeadingIconColor the color of this list item's leading content when not
+ * enabled.
+ * @param disabledTrailingIconColor the color of this list item's trailing content when not
+ * enabled.
  */
 @Immutable
-class ListItemColors internal constructor(
-    private val containerColor: Color,
-    private val headlineColor: Color,
-    private val leadingIconColor: Color,
-    private val overlineColor: Color,
-    private val supportingTextColor: Color,
-    private val trailingIconColor: Color,
-    private val disabledHeadlineColor: Color,
-    private val disabledLeadingIconColor: Color,
-    private val disabledTrailingIconColor: Color,
+class ListItemColors constructor(
+    val containerColor: Color,
+    val headlineColor: Color,
+    val leadingIconColor: Color,
+    val overlineColor: Color,
+    val supportingTextColor: Color,
+    val trailingIconColor: Color,
+    val disabledHeadlineColor: Color,
+    val disabledLeadingIconColor: Color,
+    val disabledTrailingIconColor: Color,
 ) {
     /** The container color of this [ListItem] based on enabled state */
     @Composable
@@ -413,9 +548,13 @@
         /** Three line list item */
         val ThreeLine = ListItemType(3)
 
-        internal fun getListItemType(hasOverline: Boolean, hasSupporting: Boolean): ListItemType {
+        internal fun getListItemType(
+            hasOverline: Boolean,
+            hasSupporting: Boolean,
+            isSupportingMultiline: Boolean
+        ): ListItemType {
             return when {
-                hasOverline && hasSupporting -> ThreeLine
+                (hasOverline && hasSupporting) || isSupportingMultiline -> ThreeLine
                 hasOverline || hasSupporting -> TwoLine
                 else -> OneLine
             }
@@ -425,15 +564,21 @@
 
 // Container related defaults
 // TODO: Make sure these values stay up to date until replaced with tokens.
-private val ListItemVerticalPadding = 8.dp
-private val ListItemThreeLineVerticalPadding = 12.dp
-private val ListItemStartPadding = 16.dp
-private val ListItemEndPadding = 24.dp
+@VisibleForTesting
+internal val ListItemVerticalPadding = 8.dp
+@VisibleForTesting
+internal val ListItemThreeLineVerticalPadding = 12.dp
+@VisibleForTesting
+internal val ListItemStartPadding = 16.dp
+@VisibleForTesting
+internal val ListItemEndPadding = 24.dp
 
 // Icon related defaults.
 // TODO: Make sure these values stay up to date until replaced with tokens.
-private val LeadingContentEndPadding = 16.dp
+@VisibleForTesting
+internal val LeadingContentEndPadding = 16.dp
 
 // Trailing related defaults.
 // TODO: Make sure these values stay up to date until replaced with tokens.
-private val TrailingContentStartPadding = 16.dp
+@VisibleForTesting
+internal val TrailingContentStartPadding = 16.dp
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 6356636..3788a3b 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
@@ -369,16 +369,27 @@
 /**
  * Represents the text and icon colors used in a menu item at different states.
  *
- * - See [MenuDefaults.itemColors] for the default colors used in a [DropdownMenuItemContent].
+ * @constructor create an instance with arbitrary colors.
+ * See [MenuDefaults.itemColors] for the default colors used in a [DropdownMenuItemContent].
+ *
+ * @param textColor the text color of this [DropdownMenuItemContent] when enabled
+ * @param leadingIconColor the leading icon color of this [DropdownMenuItemContent] when enabled
+ * @param trailingIconColor the trailing icon color of this [DropdownMenuItemContent] when
+ * enabled
+ * @param disabledTextColor the text color of this [DropdownMenuItemContent] when not enabled
+ * @param disabledLeadingIconColor the leading icon color of this [DropdownMenuItemContent] when
+ * not enabled
+ * @param disabledTrailingIconColor the trailing icon color of this [DropdownMenuItemContent]
+ * when not enabled
  */
 @Immutable
-class MenuItemColors internal constructor(
-    private val textColor: Color,
-    private val leadingIconColor: Color,
-    private val trailingIconColor: Color,
-    private val disabledTextColor: Color,
-    private val disabledLeadingIconColor: Color,
-    private val disabledTrailingIconColor: Color,
+class MenuItemColors constructor(
+    val textColor: Color,
+    val leadingIconColor: Color,
+    val trailingIconColor: Color,
+    val disabledTextColor: Color,
+    val disabledLeadingIconColor: Color,
+    val disabledTrailingIconColor: Color,
 ) {
     /**
      * Represents the text color for a menu item, depending on its [enabled] state.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MutableWindowInsets.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MutableWindowInsets.kt
new file mode 100644
index 0000000..95ac756d
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MutableWindowInsets.kt
@@ -0,0 +1,48 @@
+/*
+ * 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
+
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.LayoutDirection
+
+/**
+ * A [WindowInsets] whose values can change without changing the instance. This is useful
+ * to avoid recomposition when [WindowInsets] can change.
+ *
+ * Copied from [androidx.compose.foundation.layout.MutableWindowInsets], which is marked as
+ * experimental and thus cannot be used cross-module.
+ */
+internal class MutableWindowInsets(
+    initialInsets: WindowInsets = WindowInsets(0, 0, 0, 0)
+) : WindowInsets {
+    /**
+     * The [WindowInsets] that are used for [left][getLeft], [top][getTop], [right][getRight],
+     * and [bottom][getBottom] values.
+     */
+    var insets by mutableStateOf(initialInsets)
+
+    override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int =
+        insets.getLeft(density, layoutDirection)
+    override fun getTop(density: Density): Int = insets.getTop(density)
+    override fun getRight(density: Density, layoutDirection: LayoutDirection): Int =
+        insets.getRight(density, layoutDirection)
+    override fun getBottom(density: Density): Int = insets.getBottom(density)
+}
\ No newline at end of file
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 989ceba..bb9e6a2 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
@@ -331,15 +331,28 @@
     )
 }
 
+/**
+ * Represents the colors of the various elements of a navigation item.
+ *
+ * @constructor create an instance with arbitrary colors.
+ *
+ * @param selectedIconColor the color to use for the icon when the item is selected.
+ * @param selectedTextColor the color to use for the text label when the item is selected.
+ * @param selectedIndicatorColor the color to use for the indicator when the item is selected.
+ * @param unselectedIconColor the color to use for the icon when the item is unselected.
+ * @param unselectedTextColor the color to use for the text label when the item is unselected.
+ * @param disabledIconColor the color to use for the icon when the item is disabled.
+ * @param disabledTextColor the color to use for the text label when the item is disabled.
+*/
 @Stable
-class NavigationBarItemColors internal constructor(
-    private val selectedIconColor: Color,
-    private val selectedTextColor: Color,
-    private val selectedIndicatorColor: Color,
-    private val unselectedIconColor: Color,
-    private val unselectedTextColor: Color,
-    private val disabledIconColor: Color,
-    private val disabledTextColor: Color,
+class NavigationBarItemColors constructor(
+    val selectedIconColor: Color,
+    val selectedTextColor: Color,
+    val selectedIndicatorColor: Color,
+    val unselectedIconColor: Color,
+    val unselectedTextColor: Color,
+    val disabledIconColor: Color,
+    val disabledTextColor: Color,
 ) {
     /**
      * Represents the icon color for this item, depending on whether it is [selected].
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 a79e45a..067b2d8 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
@@ -843,7 +843,6 @@
 private fun Scrim(
     open: Boolean,
     onClose: () -> Unit,
-    @Suppress("PrimitiveInLambda")
     fraction: () -> Float,
     color: Color
 ) {
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 3647d4b..fcee888 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
@@ -328,16 +328,28 @@
     )
 }
 
-/** Represents the colors of the various elements of a navigation item. */
+/**
+ * Represents the colors of the various elements of a navigation item.
+ *
+ * @constructor create an instance with arbitrary colors.
+ *
+ * @param selectedIconColor the color to use for the icon when the item is selected.
+ * @param selectedTextColor the color to use for the text label when the item is selected.
+ * @param selectedIndicatorColor the color to use for the indicator when the item is selected.
+ * @param unselectedIconColor the color to use for the icon when the item is unselected.
+ * @param unselectedTextColor the color to use for the text label when the item is unselected.
+ * @param disabledIconColor the color to use for the icon when the item is disabled.
+ * @param disabledTextColor the color to use for the text label when the item is disabled.
+ */
 @Stable
-class NavigationRailItemColors internal constructor(
-    private val selectedIconColor: Color,
-    private val selectedTextColor: Color,
-    private val selectedIndicatorColor: Color,
-    private val unselectedIconColor: Color,
-    private val unselectedTextColor: Color,
-    private val disabledIconColor: Color,
-    private val disabledTextColor: Color,
+class NavigationRailItemColors constructor(
+    val selectedIconColor: Color,
+    val selectedTextColor: Color,
+    val selectedIndicatorColor: Color,
+    val unselectedIconColor: Color,
+    val unselectedTextColor: Color,
+    val disabledIconColor: Color,
+    val disabledTextColor: Color,
 ) {
     /**
      * Represents the icon color for this item, depending on whether it is [selected].
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 4067ffb..a148a0f 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
@@ -827,7 +827,6 @@
     private fun IntrinsicMeasureScope.intrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         val textFieldWidth =
@@ -868,7 +867,6 @@
     private fun IntrinsicMeasureScope.intrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         var remainingWidth = width
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 ca727e5..101aed1 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
@@ -162,15 +162,22 @@
 /**
  * Represents the color used by a [RadioButton] in different states.
  *
+ * @constructor create an instance with arbitrary colors.
  * See [RadioButtonDefaults.colors] for the default implementation that follows Material
  * specifications.
+ *
+ * @param selectedColor the color to use for the RadioButton when selected and enabled.
+ * @param unselectedColor the color to use for the RadioButton when unselected and enabled.
+ * @param disabledSelectedColor the color to use for the RadioButton when disabled and selected.
+ * @param disabledUnselectedColor the color to use for the RadioButton when disabled and not
+ * selected.
  */
 @Immutable
-class RadioButtonColors internal constructor(
-    private val selectedColor: Color,
-    private val unselectedColor: Color,
-    private val disabledSelectedColor: Color,
-    private val disabledUnselectedColor: Color
+class RadioButtonColors constructor(
+    val selectedColor: Color,
+    val unselectedColor: Color,
+    val disabledSelectedColor: Color,
+    val disabledUnselectedColor: Color
 ) {
     /**
      * Represents the main color used to draw the outer and inner circles, depending on whether
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Scaffold.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Scaffold.kt
index 122937e..1946195 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Scaffold.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Scaffold.kt
@@ -21,9 +21,13 @@
 import androidx.compose.foundation.layout.asPaddingValues
 import androidx.compose.foundation.layout.calculateEndPadding
 import androidx.compose.foundation.layout.calculateStartPadding
+import androidx.compose.foundation.layout.consumeWindowInsets
+import androidx.compose.foundation.layout.exclude
+import androidx.compose.foundation.layout.onConsumedWindowInsetsChanged
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.remember
 import androidx.compose.runtime.staticCompositionLocalOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -64,7 +68,8 @@
  * @param contentWindowInsets window insets to be passed to [content] slot via [PaddingValues]
  * params. Scaffold will take the insets into account from the top/bottom only if the [topBar]/
  * [bottomBar] are not present, as the scaffold expect [topBar]/[bottomBar] to handle insets
- * instead
+ * instead. Any insets consumed by other insets padding modifiers or [consumeWindowInsets] on a
+ * parent layout will be excluded from [contentWindowInsets].
  * @param content content of the screen. The lambda receives a [PaddingValues] that should be
  * applied to the content root via [Modifier.padding] and [Modifier.consumeWindowInsets] to
  * properly offset top and bottom bars. If using [Modifier.verticalScroll], apply this modifier to
@@ -83,14 +88,23 @@
     contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,
     content: @Composable (PaddingValues) -> Unit
 ) {
-    Surface(modifier = modifier, color = containerColor, contentColor = contentColor) {
+    val safeInsets = remember(contentWindowInsets) {
+        MutableWindowInsets(contentWindowInsets)
+    }
+    Surface(
+        modifier = modifier.onConsumedWindowInsetsChanged { consumedWindowInsets ->
+            // Exclude currently consumed window insets from user provided contentWindowInsets
+            safeInsets.insets = contentWindowInsets.exclude(consumedWindowInsets)
+        },
+        color = containerColor,
+        contentColor = contentColor) {
         ScaffoldLayout(
             fabPosition = floatingActionButtonPosition,
             topBar = topBar,
             bottomBar = bottomBar,
             content = content,
             snackbar = snackbarHost,
-            contentWindowInsets = contentWindowInsets,
+            contentWindowInsets = safeInsets,
             fab = floatingActionButton
         )
     }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
index 4013d8a..141ffbf 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
@@ -354,7 +354,6 @@
 internal fun ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(
     sheetState: SheetState,
     orientation: Orientation,
-    @Suppress("PrimitiveInLambda")
     onFling: (velocity: Float) -> Unit
 ): NestedScrollConnection = object : NestedScrollConnection {
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
index 7e21534..a4e0331 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
@@ -16,7 +16,6 @@
 
 package androidx.compose.material3
 
-import androidx.compose.animation.core.TweenSpec
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.MutatePriority
 import androidx.compose.foundation.MutatorMutex
@@ -42,10 +41,8 @@
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.requiredSizeIn
 import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.progressSemantics
 import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.material3.tokens.SliderTokens
@@ -149,7 +146,6 @@
 @Composable
 fun Slider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
@@ -244,7 +240,6 @@
 @ExperimentalMaterial3Api
 fun Slider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
@@ -406,6 +401,7 @@
  * @param colors [SliderColors] that will be used to determine the color of the Range Slider
  * parts in different state. See [SliderDefaults.colors] to customize.
  */
+@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun RangeSlider(
     value: ClosedFloatingPointRange<Float>,
@@ -421,12 +417,10 @@
     val startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }
     val endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() }
 
-    require(steps >= 0) { "steps should be >= 0" }
-
-    RangeSliderImpl(
-        modifier = modifier,
+    RangeSlider(
         value = value,
         onValueChange = onValueChange,
+        modifier = modifier,
         enabled = enabled,
         valueRange = valueRange,
         steps = steps,
@@ -447,11 +441,11 @@
                 enabled = enabled
             )
         },
-        track = { sliderPositions ->
+        track = { rangeSliderState ->
             SliderDefaults.Track(
                 colors = colors,
                 enabled = enabled,
-                sliderPositions = sliderPositions
+                rangeSliderState = rangeSliderState
             )
         }
     )
@@ -488,11 +482,6 @@
  * @param onValueChange lambda in which values should be updated
  * @param modifier modifiers for the Range Slider layout
  * @param enabled whether or not component is enabled and can we interacted with or not
- * @param valueRange range of values that Range Slider values can take. Passed [value] will be
- * coerced to this range
- * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed
- * between across the whole value range. If 0, range slider will behave as a continuous slider and
- * allow to choose any value from the range specified. Must not be negative.
  * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback
  * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather to
  * know when the user has completed selecting a new value by ending a drag or a click.
@@ -504,15 +493,17 @@
  * @param endInteractionSource the [MutableInteractionSource] representing the stream of
  * [Interaction]s for the end thumb. You can create and pass in your own
  * `remember`ed instance to observe.
+ * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed
+ * between across the whole value range. If 0, range slider will behave as a continuous slider and
+ * allow to choose any value from the range specified. Must not be negative.
  * @param startThumb the start thumb to be displayed on the Range Slider. The lambda receives a
- * [SliderPositions] which is used to obtain the current active track and the tick
- * positions if the range slider is discrete.
+ * [RangeSliderState] which is used to obtain the current active track.
  * @param endThumb the end thumb to be displayed on the Range Slider. The lambda receives a
- * [SliderPositions] which is used to obtain the current active track and the tick
- * positions if the range slider is discrete.
+ * [RangeSliderState] which is used to obtain the current active track.
  * @param track the track to be displayed on the range slider, it is placed underneath the thumb.
- * The lambda receives a [SliderPositions] which is used to obtain the current active track and the
- * tick positions if the range slider is discrete.
+ * The lambda receives a [RangeSliderState] which is used to obtain the current active track.
+ * @param valueRange range of values that Range Slider values can take. Passed [value] will be
+ * coerced to this range.
  */
 @Composable
 @ExperimentalMaterial3Api
@@ -526,40 +517,142 @@
     colors: SliderColors = SliderDefaults.colors(),
     startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
     endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
-    startThumb: @Composable (SliderPositions) -> Unit = {
+    startThumb: @Composable (RangeSliderState) -> Unit = {
         SliderDefaults.Thumb(
             interactionSource = startInteractionSource,
             colors = colors,
             enabled = enabled
         )
     },
-    endThumb: @Composable (SliderPositions) -> Unit = {
+    endThumb: @Composable (RangeSliderState) -> Unit = {
         SliderDefaults.Thumb(
             interactionSource = endInteractionSource,
             colors = colors,
             enabled = enabled
         )
     },
-    track: @Composable (SliderPositions) -> Unit = { sliderPositions ->
-            SliderDefaults.Track(
-                colors = colors,
-                enabled = enabled,
-                sliderPositions = sliderPositions
-            )
+    track: @Composable (RangeSliderState) -> Unit = { rangeSliderState ->
+        SliderDefaults.Track(
+            colors = colors,
+            enabled = enabled,
+            rangeSliderState = rangeSliderState
+        )
     },
     /*@IntRange(from = 0)*/
-    steps: Int = 0,
+    steps: Int = 0
 ) {
-    require(steps >= 0) { "steps should be >= 0" }
+    val state = remember(
+        steps,
+        valueRange
+    ) {
+        RangeSliderState(
+            value.start,
+            value.endInclusive,
+            onValueChange,
+            steps,
+            valueRange,
+            onValueChangeFinished,
+        )
+    }
+    state.activeRangeStart = value.start
+    state.activeRangeEnd = value.endInclusive
+    state.onValueChange = onValueChange
+    state.onValueChangeFinished = onValueChangeFinished
+
+    RangeSlider(
+        modifier = modifier,
+        state = state,
+        enabled = enabled,
+        startInteractionSource = startInteractionSource,
+        endInteractionSource = endInteractionSource,
+        startThumb = startThumb,
+        endThumb = endThumb,
+        track = track
+    )
+}
+
+/**
+ * <a href="https://m3.material.io/components/sliders/overview" class="external" target="_blank">Material Design Range slider</a>.
+ *
+ * Range Sliders expand upon [Slider] using the same concepts but allow the user to select 2 values.
+ *
+ * The two values are still bounded by the value range but they also cannot cross each other.
+ *
+ * It uses the provided startThumb for the slider's start thumb and endThumb for the
+ * slider's end thumb. It also uses the provided track for the slider's track. If nothing is
+ * passed for these parameters, it will use [SliderDefaults.Thumb] and [SliderDefaults.Track]
+ * for the thumbs and track.
+ *
+ * Use continuous Range Sliders to allow users to make meaningful selections that don’t
+ * require a specific values:
+ *
+ * @sample androidx.compose.material3.samples.RangeSliderSample
+ *
+ * You can allow the user to choose only between predefined set of values by specifying the amount
+ * of steps between min and max values:
+ *
+ * @sample androidx.compose.material3.samples.StepRangeSliderSample
+ *
+ * A custom start/end thumb and track can be provided:
+ *
+ * @sample androidx.compose.material3.samples.RangeSliderWithCustomComponents
+ *
+ * @param state [RangeSliderState] which contains the current values of the RangeSlider.
+ * @param modifier modifiers for the Range Slider layout
+ * @param enabled whether or not component is enabled and can we interacted with or not
+ * @param colors [SliderColors] that will be used to determine the color of the Range Slider
+ * parts in different state. See [SliderDefaults.colors] to customize.
+ * @param startInteractionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for the start thumb. You can create and pass in your own
+ * `remember`ed instance to observe.
+ * @param endInteractionSource the [MutableInteractionSource] representing the stream of
+ * [Interaction]s for the end thumb. You can create and pass in your own
+ * `remember`ed instance to observe.
+ * @param startThumb the start thumb to be displayed on the Range Slider. The lambda receives a
+ * [RangeSliderState] which is used to obtain the current active track.
+ * @param endThumb the end thumb to be displayed on the Range Slider. The lambda receives a
+ * [RangeSliderState] which is used to obtain the current active track.
+ * @param track the track to be displayed on the range slider, it is placed underneath the thumb.
+ * The lambda receives a [RangeSliderState] which is used to obtain the current active track.
+ */
+@Composable
+@ExperimentalMaterial3Api
+fun RangeSlider(
+    state: RangeSliderState,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true,
+    colors: SliderColors = SliderDefaults.colors(),
+    startInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    endInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+    startThumb: @Composable (RangeSliderState) -> Unit = {
+        state.activeRangeStart
+        SliderDefaults.Thumb(
+            interactionSource = startInteractionSource,
+            colors = colors,
+            enabled = enabled
+        )
+    },
+    endThumb: @Composable (RangeSliderState) -> Unit = {
+        SliderDefaults.Thumb(
+            interactionSource = endInteractionSource,
+            colors = colors,
+            enabled = enabled
+        )
+    },
+    track: @Composable (RangeSliderState) -> Unit = { rangeSliderState ->
+        SliderDefaults.Track(
+            colors = colors,
+            enabled = enabled,
+            rangeSliderState = rangeSliderState
+        )
+    }
+) {
+    require(state.steps >= 0) { "steps should be >= 0" }
 
     RangeSliderImpl(
         modifier = modifier,
-        value = value,
-        onValueChange = onValueChange,
+        state = state,
         enabled = enabled,
-        valueRange = valueRange,
-        steps = steps,
-        onValueChangeFinished = onValueChangeFinished,
         startInteractionSource = startInteractionSource,
         endInteractionSource = endInteractionSource,
         startThumb = startThumb,
@@ -659,125 +752,34 @@
     }
 }
 
+@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 private fun RangeSliderImpl(
     modifier: Modifier,
-    value: ClosedFloatingPointRange<Float>,
-    onValueChange: (ClosedFloatingPointRange<Float>) -> Unit,
+    state: RangeSliderState,
     enabled: Boolean,
-    valueRange: ClosedFloatingPointRange<Float>,
-    steps: Int = 0,
-    onValueChangeFinished: (() -> Unit)?,
     startInteractionSource: MutableInteractionSource,
     endInteractionSource: MutableInteractionSource,
-    startThumb: @Composable ((SliderPositions) -> Unit),
-    endThumb: @Composable ((SliderPositions) -> Unit),
-    track: @Composable ((SliderPositions) -> Unit)
+    startThumb: @Composable ((RangeSliderState) -> Unit),
+    endThumb: @Composable ((RangeSliderState) -> Unit),
+    track: @Composable ((RangeSliderState) -> Unit)
 ) {
-    val onValueChangeState = rememberUpdatedState<(ClosedFloatingPointRange<Float>) -> Unit> {
-        if (it != value) {
-            onValueChange(it)
-        }
-    }
-
-    val tickFractions = remember(steps) {
-        stepsToTickFractions(steps)
-    }
-
-    var startThumbWidth by remember { mutableFloatStateOf(ThumbWidth.value) }
-    var endThumbWidth by remember { mutableFloatStateOf(ThumbWidth.value) }
-    var totalWidth by remember { mutableIntStateOf(0) }
-
-    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
-
-    // scales range offset from within minPx..maxPx to within valueRange.start..valueRange.end
-    fun scaleToUserValue(minPx: Float, maxPx: Float, offset: ClosedFloatingPointRange<Float>) =
-        scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)
-
-    // scales float userValue within valueRange.start..valueRange.end to within minPx..maxPx
-    fun scaleToOffset(minPx: Float, maxPx: Float, userValue: Float) =
-        scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
-
-    var obtainedMeasurements = remember { mutableStateOf(false) }
-    val rawOffsetStart = remember { mutableFloatStateOf(0f) }
-    val rawOffsetEnd = remember { mutableFloatStateOf(0f) }
-
-    val gestureEndAction = rememberUpdatedState<(Boolean) -> Unit> {
-        onValueChangeFinished?.invoke()
-    }
-
-    val onDrag = rememberUpdatedState<(Boolean, Float) -> Unit> { isStart, offset ->
-        val maxPx = max(totalWidth - endThumbWidth / 2, 0f)
-        val minPx = min(startThumbWidth / 2, maxPx)
-        val offsetRange = if (isStart) {
-            rawOffsetStart.floatValue = (rawOffsetStart.floatValue + offset)
-            rawOffsetEnd.floatValue = scaleToOffset(minPx, maxPx, value.endInclusive)
-            val offsetEnd = rawOffsetEnd.floatValue
-            var offsetStart = rawOffsetStart.floatValue.coerceIn(minPx, offsetEnd)
-            offsetStart = snapValueToTick(offsetStart, tickFractions, minPx, maxPx)
-            offsetStart..offsetEnd
-        } else {
-            rawOffsetEnd.floatValue = (rawOffsetEnd.floatValue + offset)
-            rawOffsetStart.floatValue = scaleToOffset(minPx, maxPx, value.start)
-            val offsetStart = rawOffsetStart.floatValue
-            var offsetEnd = rawOffsetEnd.floatValue.coerceIn(offsetStart, maxPx)
-            offsetEnd = snapValueToTick(offsetEnd, tickFractions, minPx, maxPx)
-            offsetStart..offsetEnd
-        }
-
-        onValueChangeState.value.invoke(scaleToUserValue(minPx, maxPx, offsetRange))
-    }
+    state.isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
 
     val pressDrag = Modifier.rangeSliderPressDragModifier(
+        state,
         startInteractionSource,
         endInteractionSource,
-        rawOffsetStart,
-        rawOffsetEnd,
-        enabled,
-        isRtl,
-        totalWidth,
-        valueRange,
-        gestureEndAction,
-        onDrag,
+        enabled
     )
 
-    // The positions of the thumbs are dependant on each other.
-    val coercedStart = value.start.coerceIn(valueRange.start, value.endInclusive)
-    val coercedEnd = value.endInclusive.coerceIn(value.start, valueRange.endInclusive)
-    val positionFractionStart = calcFraction(
-        valueRange.start,
-        valueRange.endInclusive,
-        coercedStart
+    val startThumbSemantics = Modifier.rangeSliderStartThumbSemantics(
+        state,
+        enabled
     )
-    val positionFractionEnd = calcFraction(valueRange.start, valueRange.endInclusive, coercedEnd)
-
-    val sliderPositions = remember {
-        SliderPositions(
-            positionFractionStart..positionFractionEnd,
-            tickFractions
-        )
-    }
-    sliderPositions.activeRange = positionFractionStart..positionFractionEnd
-    sliderPositions.tickFractions = tickFractions
-
-    val startSteps = floor(steps * positionFractionEnd).toInt()
-    val endSteps = floor(steps * (1f - positionFractionStart)).toInt()
-
-    val startThumbSemantics = Modifier.sliderSemantics(
-        coercedStart,
-        enabled,
-        { changedVal -> onValueChangeState.value.invoke(changedVal..coercedEnd) },
-        onValueChangeFinished,
-        valueRange.start..coercedEnd,
-        startSteps
-    )
-    val endThumbSemantics = Modifier.sliderSemantics(
-        coercedEnd,
-        enabled,
-        { changedVal -> onValueChangeState.value.invoke(coercedStart..changedVal) },
-        onValueChangeFinished,
-        coercedStart..valueRange.endInclusive,
-        endSteps
+    val endThumbSemantics = Modifier.rangeSliderEndThumbSemantics(
+        state,
+        enabled
     )
 
     val startContentDescription = getString(Strings.SliderRangeStart)
@@ -792,7 +794,7 @@
                 }
                 .focusable(enabled, startInteractionSource)
                 .then(startThumbSemantics)
-            ) { startThumb(sliderPositions) }
+            ) { startThumb(state) }
             Box(modifier = Modifier
                 .layoutId(RangeSliderComponents.ENDTHUMB)
                 .semantics(mergeDescendants = true) {
@@ -800,9 +802,9 @@
                 }
                 .focusable(enabled, endInteractionSource)
                 .then(endThumbSemantics)
-            ) { endThumb(sliderPositions) }
+            ) { endThumb(state) }
             Box(modifier = Modifier.layoutId(RangeSliderComponents.TRACK)) {
-                track(sliderPositions)
+                track(state)
             }
         },
         modifier = modifier
@@ -841,36 +843,21 @@
             endThumbPlaceable.height
         )
 
-        startThumbWidth = startThumbPlaceable.width.toFloat()
-        endThumbWidth = endThumbPlaceable.width.toFloat()
-        totalWidth = sliderWidth
+        state.startThumbWidth = startThumbPlaceable.width.toFloat()
+        state.endThumbWidth = endThumbPlaceable.width.toFloat()
+        state.totalWidth = sliderWidth
 
-        // Updates rawOffsetStart and rawOffsetEnd with the correct min and max pixel.
-        // We use this `obtainedMeasurements` boolean so that we only do this update once.
-        // Is there a cleaner way to do this?
-        if (!obtainedMeasurements.value) {
-            val finalizedMaxPx = max(totalWidth - endThumbWidth / 2, 0f)
-            val finalizedMinPx = min(startThumbWidth / 2, finalizedMaxPx)
-            rawOffsetStart.floatValue = scaleToOffset(
-                finalizedMinPx,
-                finalizedMaxPx,
-                value.start
-            )
-            rawOffsetEnd.floatValue = scaleToOffset(
-                finalizedMinPx,
-                finalizedMaxPx,
-                value.endInclusive
-            )
-            obtainedMeasurements.value = true
-        }
+        state.updateMinMaxPx()
 
         val trackOffsetX = startThumbPlaceable.width / 2
-        val startThumbOffsetX = (trackPlaceable.width * positionFractionStart).roundToInt()
+        val startThumbOffsetX = (trackPlaceable.width * state.coercedActiveRangeStartAsFraction)
+            .roundToInt()
         // When start thumb and end thumb have different widths,
         // we need to add a correction for the centering of the slider.
-        val endCorrection = (startThumbWidth - endThumbWidth) / 2
+        val endCorrection = (state.startThumbWidth - state.endThumbWidth) / 2
         val endThumbOffsetX =
-            (trackPlaceable.width * positionFractionEnd + endCorrection).roundToInt()
+            (trackPlaceable.width * state.coercedActiveRangeEndAsFraction + endCorrection)
+                .roundToInt()
         val trackOffsetY = (sliderHeight - trackPlaceable.height) / 2
         val startThumbOffsetY = (sliderHeight - startThumbPlaceable.height) / 2
         val endThumbOffsetY = (sliderHeight - endThumbPlaceable.height) / 2
@@ -1050,10 +1037,9 @@
         val activeTrackColor = colors.trackColor(enabled, active = true)
         val inactiveTickColor = colors.tickColor(enabled, active = false)
         val activeTickColor = colors.tickColor(enabled, active = true)
-        Canvas(
-            modifier
-                .fillMaxWidth()
-                .height(TrackHeight)
+        Canvas(modifier
+            .fillMaxWidth()
+            .height(TrackHeight)
         ) {
             val isRtl = layoutDirection == LayoutDirection.Rtl
             val sliderLeft = Offset(0f, center.y)
@@ -1124,7 +1110,6 @@
         colors: SliderColors = colors(),
         enabled: Boolean = true
     ) {
-
         val inactiveTrackColor by colors.trackColor(enabled, active = false)
         val activeTrackColor by colors.trackColor(enabled, active = true)
         val inactiveTickColor by colors.tickColor(enabled, active = false)
@@ -1146,6 +1131,46 @@
         }
     }
 
+    /**
+     * The Default track for [RangeSlider]
+     *
+     * @param rangeSliderState [RangeSliderState] which is used to obtain the current active track.
+     * @param modifier the [Modifier] to be applied to the track.
+     * @param colors [SliderColors] that will be used to resolve the colors used for this track in
+     * different states. See [SliderDefaults.colors].
+     * @param enabled controls the enabled state of this slider. When `false`, this component will
+     * not respond to user input, and it will appear visually disabled and disabled to
+     * accessibility services.
+     */
+    @OptIn(ExperimentalMaterial3Api::class)
+    @Composable
+    fun Track(
+        rangeSliderState: RangeSliderState,
+        modifier: Modifier = Modifier,
+        colors: SliderColors = colors(),
+        enabled: Boolean = true
+    ) {
+        val inactiveTrackColor by colors.trackColor(enabled, active = false)
+        val activeTrackColor by colors.trackColor(enabled, active = true)
+        val inactiveTickColor by colors.tickColor(enabled, active = false)
+        val activeTickColor by colors.tickColor(enabled, active = true)
+        Canvas(
+            modifier
+                .fillMaxWidth()
+                .height(TrackHeight)
+        ) {
+            drawTrack(
+                rangeSliderState.tickFractions,
+                rangeSliderState.coercedActiveRangeStartAsFraction,
+                rangeSliderState.coercedActiveRangeEndAsFraction,
+                inactiveTrackColor,
+                activeTrackColor,
+                inactiveTickColor,
+                activeTickColor
+            )
+        }
+    }
+
     private fun DrawScope.drawTrack(
         tickFractions: FloatArray,
         activeRangeStart: Float,
@@ -1223,7 +1248,6 @@
     type: PointerType
 ): Pair<PointerInputChange, Float>? {
     var initialDelta = 0f
-    @Suppress("PrimitiveInLambda")
     val postPointerSlop = { pointerInput: PointerInputChange, offset: Float ->
         pointerInput.consume()
         initialDelta = offset
@@ -1248,54 +1272,6 @@
 private fun calcFraction(a: Float, b: Float, pos: Float) =
     (if (b - a == 0f) 0f else (pos - a) / (b - a)).coerceIn(0f, 1f)
 
-private fun Modifier.sliderSemantics(
-    value: Float,
-    enabled: Boolean,
-    @Suppress("PrimitiveInLambda")
-    onValueChange: (Float) -> Unit,
-    onValueChangeFinished: (() -> Unit)? = null,
-    valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
-    steps: Int = 0
-): Modifier {
-    val coerced = value.coerceIn(valueRange.start, valueRange.endInclusive)
-    return semantics {
-        if (!enabled) disabled()
-        setProgress(
-            action = { targetValue ->
-                var newValue = targetValue.coerceIn(valueRange.start, valueRange.endInclusive)
-                val originalVal = newValue
-                val resolvedValue = if (steps > 0) {
-                    var distance: Float = newValue
-                    for (i in 0..steps + 1) {
-                        val stepValue = lerp(
-                            valueRange.start,
-                            valueRange.endInclusive,
-                            i.toFloat() / (steps + 1)
-                        )
-                        if (abs(stepValue - originalVal) <= distance) {
-                            distance = abs(stepValue - originalVal)
-                            newValue = stepValue
-                        }
-                    }
-                    newValue
-                } else {
-                    newValue
-                }
-
-                // This is to keep it consistent with AbsSeekbar.java: return false if no
-                // change from current.
-                if (resolvedValue == coerced) {
-                    false
-                } else {
-                    onValueChange(resolvedValue)
-                    onValueChangeFinished?.invoke()
-                    true
-                }
-            }
-        )
-    }.progressSemantics(value, valueRange, steps)
-}
-
 @OptIn(ExperimentalMaterial3Api::class)
 private fun Modifier.sliderSemantics(
     state: SliderState,
@@ -1344,6 +1320,105 @@
 }
 
 @OptIn(ExperimentalMaterial3Api::class)
+private fun Modifier.rangeSliderStartThumbSemantics(
+    state: RangeSliderState,
+    enabled: Boolean
+): Modifier {
+    val valueRange = state.valueRange.start..state.coercedEnd
+    val coerced = state.coercedStart.coerceIn(
+        valueRange.start,
+        valueRange.endInclusive
+    )
+    return semantics {
+        if (!enabled) disabled()
+        setProgress(
+            action = { targetValue ->
+                var newValue = targetValue.coerceIn(
+                    valueRange.start,
+                    valueRange.endInclusive
+                )
+                val originalVal = newValue
+                val resolvedValue = if (state.startSteps > 0) {
+                    var distance: Float = newValue
+                    for (i in 0..state.startSteps + 1) {
+                        val stepValue = lerp(
+                            valueRange.start,
+                            valueRange.endInclusive,
+                            i.toFloat() / (state.startSteps + 1)
+                        )
+                        if (abs(stepValue - originalVal) <= distance) {
+                            distance = abs(stepValue - originalVal)
+                            newValue = stepValue
+                        }
+                    }
+                    newValue
+                } else {
+                    newValue
+                }
+
+                // This is to keep it consistent with AbsSeekbar.java: return false if no
+                // change from current.
+                if (resolvedValue == coerced) {
+                    false
+                } else {
+                    state.onValueChange(resolvedValue..state.coercedEnd)
+                    state.onValueChangeFinished?.invoke()
+                    true
+                }
+            }
+        )
+    }.progressSemantics(state.coercedStart, valueRange, state.startSteps)
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+private fun Modifier.rangeSliderEndThumbSemantics(
+    state: RangeSliderState,
+    enabled: Boolean
+): Modifier {
+    val valueRange = state.coercedStart..state.valueRange.endInclusive
+    val coerced = state.coercedEnd.coerceIn(
+        valueRange.start,
+        valueRange.endInclusive
+    )
+    return semantics {
+        if (!enabled) disabled()
+        setProgress(
+            action = { targetValue ->
+                var newValue = targetValue.coerceIn(valueRange.start, valueRange.endInclusive)
+                val originalVal = newValue
+                val resolvedValue = if (state.endSteps > 0) {
+                    var distance: Float = newValue
+                    for (i in 0..state.endSteps + 1) {
+                        val stepValue = lerp(
+                            valueRange.start,
+                            valueRange.endInclusive,
+                            i.toFloat() / (state.endSteps + 1)
+                        )
+                        if (abs(stepValue - originalVal) <= distance) {
+                            distance = abs(stepValue - originalVal)
+                            newValue = stepValue
+                        }
+                    }
+                    newValue
+                } else {
+                    newValue
+                }
+
+                // This is to keep it consistent with AbsSeekbar.java: return false if no
+                // change from current.
+                if (resolvedValue == coerced) {
+                    false
+                } else {
+                    state.onValueChange(state.coercedStart..resolvedValue)
+                    state.onValueChangeFinished?.invoke()
+                    true
+                }
+            }
+        )
+    }.progressSemantics(state.coercedEnd, valueRange, state.endSteps)
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
 private fun Modifier.sliderTapModifier(
     state: SliderState,
     interactionSource: MutableInteractionSource,
@@ -1377,46 +1452,46 @@
         properties["enabled"] = enabled
     })
 
+@OptIn(ExperimentalMaterial3Api::class)
 private fun Modifier.rangeSliderPressDragModifier(
+    state: RangeSliderState,
     startInteractionSource: MutableInteractionSource,
     endInteractionSource: MutableInteractionSource,
-    rawOffsetStart: State<Float>,
-    rawOffsetEnd: State<Float>,
-    enabled: Boolean,
-    isRtl: Boolean,
-    maxPx: Int,
-    valueRange: ClosedFloatingPointRange<Float>,
-    gestureEndAction: State<(Boolean) -> Unit>,
-    onDrag: State<(Boolean, Float) -> Unit>,
+    enabled: Boolean
 ): Modifier =
     if (enabled) {
-        pointerInput(startInteractionSource, endInteractionSource, maxPx, isRtl, valueRange) {
+        pointerInput(
+            startInteractionSource,
+            endInteractionSource,
+            state.totalWidth,
+            state.isRtl,
+            state.valueRange
+        ) {
             val rangeSliderLogic = RangeSliderLogic(
+                state,
                 startInteractionSource,
-                endInteractionSource,
-                rawOffsetStart,
-                rawOffsetEnd,
-                onDrag
+                endInteractionSource
             )
             coroutineScope {
                 awaitEachGesture {
                     val event = awaitFirstDown(requireUnconsumed = false)
                     val interaction = DragInteraction.Start()
-                    var posX = if (isRtl) maxPx - event.position.x else event.position.x
+                    var posX = if (state.isRtl)
+                        state.totalWidth - event.position.x else event.position.x
                     val compare = rangeSliderLogic.compareOffsets(posX)
                     var draggingStart = if (compare != 0) {
                         compare < 0
                     } else {
-                        rawOffsetStart.value > posX
+                        state.rawOffsetStart > posX
                     }
 
                     awaitSlop(event.id, event.type)?.let {
                         val slop = viewConfiguration.pointerSlop(event.type)
-                        val shouldUpdateCapturedThumb = abs(rawOffsetEnd.value - posX) < slop &&
-                            abs(rawOffsetStart.value - posX) < slop
+                        val shouldUpdateCapturedThumb = abs(state.rawOffsetEnd - posX) < slop &&
+                            abs(state.rawOffsetStart - posX) < slop
                         if (shouldUpdateCapturedThumb) {
                             val dir = it.second
-                            draggingStart = if (isRtl) dir >= 0f else dir < 0f
+                            draggingStart = if (state.isRtl) dir >= 0f else dir < 0f
                             posX += it.first.positionChange().x
                         }
                     }
@@ -1431,7 +1506,7 @@
                     val finishInteraction = try {
                         val success = horizontalDrag(pointerId = event.id) {
                             val deltaX = it.positionChange().x
-                            onDrag.value.invoke(draggingStart, if (isRtl) -deltaX else deltaX)
+                            state.onDrag.invoke(draggingStart, if (state.isRtl) -deltaX else deltaX)
                         }
                         if (success) {
                             DragInteraction.Stop(interaction)
@@ -1442,7 +1517,7 @@
                         DragInteraction.Cancel(interaction)
                     }
 
-                    gestureEndAction.value.invoke(draggingStart)
+                    state.gestureEndAction(draggingStart)
                     launch {
                         rangeSliderLogic
                             .activeInteraction(draggingStart)
@@ -1455,20 +1530,18 @@
         this
     }
 
-private class RangeSliderLogic(
+@OptIn(ExperimentalMaterial3Api::class)
+private class RangeSliderLogic constructor(
+    val state: RangeSliderState,
     val startInteractionSource: MutableInteractionSource,
-    val endInteractionSource: MutableInteractionSource,
-    val rawOffsetStart: State<Float>,
-    val rawOffsetEnd: State<Float>,
-    @Suppress("PrimitiveInLambda")
-    val onDrag: State<(Boolean, Float) -> Unit>,
+    val endInteractionSource: MutableInteractionSource
 ) {
     fun activeInteraction(draggingStart: Boolean): MutableInteractionSource =
         if (draggingStart) startInteractionSource else endInteractionSource
 
     fun compareOffsets(eventX: Float): Int {
-        val diffStart = abs(rawOffsetStart.value - eventX)
-        val diffEnd = abs(rawOffsetEnd.value - eventX)
+        val diffStart = abs(state.rawOffsetStart - eventX)
+        val diffEnd = abs(state.rawOffsetEnd - eventX)
         return diffStart.compareTo(diffEnd)
     }
 
@@ -1478,9 +1551,9 @@
         interaction: Interaction,
         scope: CoroutineScope
     ) {
-        onDrag.value.invoke(
+        state.onDrag.invoke(
             draggingStart,
-            posX - if (draggingStart) rawOffsetStart.value else rawOffsetEnd.value
+            posX - if (draggingStart) state.rawOffsetStart else state.rawOffsetEnd
         )
         scope.launch {
             activeInteraction(draggingStart).emit(interaction)
@@ -1488,18 +1561,44 @@
     }
 }
 
+/**
+ * Represents the color used by a [Slider] in different states.
+ *
+ * @constructor create an instance with arbitrary colors.
+ * See [SliderDefaults.colors] for the default implementation that follows Material
+ * specifications.
+ *
+ * @param thumbColor thumb color when enabled
+ * @param activeTrackColor color of the track in the part that is "active", meaning that the
+ * thumb is ahead of it
+ * @param activeTickColor colors to be used to draw tick marks on the active track, if `steps`
+ * is specified
+ * @param inactiveTrackColor color of the track in the part that is "inactive", meaning that the
+ * thumb is before it
+ * @param inactiveTickColor colors to be used to draw tick marks on the inactive track, if
+ * `steps` are specified on the Slider is specified
+ * @param disabledThumbColor thumb colors when disabled
+ * @param disabledActiveTrackColor color of the track in the "active" part when the Slider is
+ * disabled
+ * @param disabledActiveTickColor colors to be used to draw tick marks on the active track
+ * when Slider is disabled and when `steps` are specified on it
+ * @param disabledInactiveTrackColor color of the track in the "inactive" part when the
+ * Slider is disabled
+ * @param disabledInactiveTickColor colors to be used to draw tick marks on the inactive part
+ * of the track when Slider is disabled and when `steps` are specified on it
+ */
 @Immutable
-class SliderColors internal constructor(
-    private val thumbColor: Color,
-    private val activeTrackColor: Color,
-    private val activeTickColor: Color,
-    private val inactiveTrackColor: Color,
-    private val inactiveTickColor: Color,
-    private val disabledThumbColor: Color,
-    private val disabledActiveTrackColor: Color,
-    private val disabledActiveTickColor: Color,
-    private val disabledInactiveTrackColor: Color,
-    private val disabledInactiveTickColor: Color
+class SliderColors constructor(
+    val thumbColor: Color,
+    val activeTrackColor: Color,
+    val activeTickColor: Color,
+    val inactiveTrackColor: Color,
+    val inactiveTickColor: Color,
+    val disabledThumbColor: Color,
+    val disabledActiveTrackColor: Color,
+    val disabledActiveTickColor: Color,
+    val disabledInactiveTrackColor: Color,
+    val disabledInactiveTickColor: Color
 ) {
 
     @Composable
@@ -1574,15 +1673,8 @@
 internal val TrackHeight = SliderTokens.InactiveTrackHeight
 private val SliderHeight = 48.dp
 private val SliderMinWidth = 144.dp // TODO: clarify min width
-private val DefaultSliderConstraints =
-    Modifier
-        .widthIn(min = SliderMinWidth)
-        .heightIn(max = SliderHeight)
-
-private val SliderToTickAnimation = TweenSpec<Float>(durationMillis = 100)
 
 internal class SliderDraggableState(
-    @Suppress("PrimitiveInLambda")
     val onDelta: (Float) -> Unit
 ) : DraggableState {
 
@@ -1681,7 +1773,6 @@
 @ExperimentalMaterial3Api
 class SliderState(
     initialValue: Float = 0f,
-    @Suppress("PrimitiveInLambda")
     initialOnValueChange: ((Float) -> Unit)? = null,
     /*@IntRange(from = 0)*/
     val steps: Int = 0,
@@ -1710,7 +1801,6 @@
     /**
      * callback in which value should be updated
      */
-    @Suppress("PrimitiveInLambda")
     internal var onValueChange: (Float) -> Unit = {
         if (it != value) {
             initialOnValueChange?.invoke(it) ?: defaultOnValueChange(it)
@@ -1722,8 +1812,8 @@
     private var thumbWidth by mutableFloatStateOf(ThumbWidth.value)
     internal var totalWidth by mutableIntStateOf(0)
 
-    internal var rawOffset by mutableFloatStateOf(scaleToOffset(0f, 0f, value))
-    internal var pressOffset by mutableFloatStateOf(0f)
+    private var rawOffset by mutableFloatStateOf(scaleToOffset(0f, 0f, value))
+    private var pressOffset by mutableFloatStateOf(0f)
 
     internal var isRtl = false
 
@@ -1777,3 +1867,173 @@
     private fun scaleToOffset(minPx: Float, maxPx: Float, userValue: Float) =
         scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
 }
+
+/**
+ * Class that holds information about [RangeSlider]'s active range.
+ *
+ * @param initialActiveRangeStart [Float] that indicates the initial
+ * start of the active range of the slider. If outside of [valueRange]
+ * provided, value will be coerced to this range.
+ * @param initialActiveRangeEnd [Float] that indicates the initial
+ * end of the active range of the slider. If outside of [valueRange]
+ * provided, value will be coerced to this range.
+ * @param initialOnValueChange callback in which [activeRangeStart] and
+ * [activeRangeEnd] should be updated.
+ * @param steps if greater than 0, specifies the amounts of discrete values, evenly distributed
+ * between across the whole value range. If 0, range slider will behave as a continuous slider and
+ * allow to choose any value from the range specified. Must not be negative.
+ * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback
+ * shouldn't be used to update the range slider values (use [onValueChange] for that), but rather
+ * to know when the user has completed selecting a new value by ending a drag or a click.
+ * @param valueRange range of values that Range Slider values can take. [activeRangeStart]
+ * and [activeRangeEnd] will be coerced to this range.
+ */
+@Stable
+@ExperimentalMaterial3Api
+class RangeSliderState(
+    initialActiveRangeStart: Float = 0f,
+    initialActiveRangeEnd: Float = 1f,
+    initialOnValueChange: ((ClosedFloatingPointRange<Float>) -> Unit)? = null,
+    /*@IntRange(from = 0)*/
+    val steps: Int = 0,
+    val valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
+    var onValueChangeFinished: (() -> Unit)? = null,
+) {
+    private var activeRangeStartState by mutableFloatStateOf(initialActiveRangeStart)
+    private var activeRangeEndState by mutableFloatStateOf(initialActiveRangeEnd)
+
+    /**
+     * [Float]s that indicates the current active range for the
+     * start thumb and end thumb for a [RangeSlider].
+     */
+    var activeRangeStart: Float
+        set(newVal) {
+            val coercedValue = newVal.coerceIn(valueRange.start, activeRangeEnd)
+            val snappedValue = snapValueToTick(
+                coercedValue,
+                tickFractions,
+                valueRange.start,
+                valueRange.endInclusive
+            )
+            activeRangeStartState = snappedValue
+        }
+        get() = activeRangeStartState
+    var activeRangeEnd: Float
+        set(newVal) {
+            val coercedValue = newVal.coerceIn(activeRangeStart, valueRange.endInclusive)
+            val snappedValue = snapValueToTick(
+                coercedValue,
+                tickFractions,
+                valueRange.start,
+                valueRange.endInclusive
+            )
+            activeRangeEndState = snappedValue
+        }
+        get() = activeRangeEndState
+
+    internal var onValueChange: (ClosedFloatingPointRange<Float>) -> Unit = {
+        if (it != activeRangeStart..activeRangeEnd) {
+            initialOnValueChange?.invoke(it) ?: defaultOnValueChange(it)
+        }
+    }
+
+    internal val tickFractions = stepsToTickFractions(steps)
+
+    internal var startThumbWidth by mutableFloatStateOf(ThumbWidth.value)
+    internal var endThumbWidth by mutableFloatStateOf(ThumbWidth.value)
+    internal var totalWidth by mutableIntStateOf(0)
+
+    internal var rawOffsetStart by mutableFloatStateOf(0f)
+    internal var rawOffsetEnd by mutableFloatStateOf(0f)
+
+    internal var isRtl = false
+
+    internal val gestureEndAction: (Boolean) -> Unit = {
+        onValueChangeFinished?.invoke()
+    }
+
+    private var maxPx by mutableFloatStateOf(max(totalWidth - endThumbWidth / 2, 0f))
+    private var minPx by mutableFloatStateOf(min(startThumbWidth / 2, maxPx))
+
+    @Suppress("PrimitiveInLambda")
+    internal val onDrag: (Boolean, Float) -> Unit = { isStart, offset ->
+        val offsetRange = if (isStart) {
+            rawOffsetStart = (rawOffsetStart + offset)
+            rawOffsetEnd = scaleToOffset(minPx, maxPx, activeRangeEnd)
+            val offsetEnd = rawOffsetEnd
+            var offsetStart = rawOffsetStart.coerceIn(minPx, offsetEnd)
+            offsetStart = snapValueToTick(offsetStart, tickFractions, minPx, maxPx)
+            offsetStart..offsetEnd
+        } else {
+            rawOffsetEnd = (rawOffsetEnd + offset)
+            rawOffsetStart = scaleToOffset(minPx, maxPx, activeRangeStart)
+            val offsetStart = rawOffsetStart
+            var offsetEnd = rawOffsetEnd.coerceIn(offsetStart, maxPx)
+            offsetEnd = snapValueToTick(offsetEnd, tickFractions, minPx, maxPx)
+            offsetStart..offsetEnd
+        }
+        onValueChange(scaleToUserValue(minPx, maxPx, offsetRange))
+    }
+
+    internal val coercedStart
+        get() = activeRangeStart.coerceIn(valueRange.start, activeRangeEnd)
+
+    internal val coercedEnd
+        get() = activeRangeEnd.coerceIn(activeRangeStart, valueRange.endInclusive)
+
+    internal val coercedActiveRangeStartAsFraction
+        get() = calcFraction(
+            valueRange.start,
+            valueRange.endInclusive,
+            coercedStart
+        )
+
+    internal val coercedActiveRangeEndAsFraction
+        get() = calcFraction(
+            valueRange.start,
+            valueRange.endInclusive,
+            coercedEnd
+        )
+
+    internal val startSteps
+        get() = floor(steps * coercedActiveRangeEndAsFraction).toInt()
+
+    internal val endSteps
+        get() = floor(steps * (1f - coercedActiveRangeStartAsFraction)).toInt()
+
+    private fun defaultOnValueChange(newRange: ClosedFloatingPointRange<Float>) {
+        activeRangeStart = newRange.start
+        activeRangeEnd = newRange.endInclusive
+    }
+
+    // scales range offset from within minPx..maxPx to within valueRange.start..valueRange.end
+    private fun scaleToUserValue(
+        minPx: Float,
+        maxPx: Float,
+        offset:
+        ClosedFloatingPointRange<Float>
+    ) = scale(minPx, maxPx, offset, valueRange.start, valueRange.endInclusive)
+
+    // scales float userValue within valueRange.start..valueRange.end to within minPx..maxPx
+    private fun scaleToOffset(minPx: Float, maxPx: Float, userValue: Float) =
+        scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
+
+    internal fun updateMinMaxPx() {
+        val newMaxPx = max(totalWidth - endThumbWidth / 2, 0f)
+        val newMinPx = min(startThumbWidth / 2, maxPx)
+        if (minPx != newMinPx || maxPx != newMaxPx) {
+            minPx = newMinPx
+            maxPx = newMaxPx
+            rawOffsetStart = scaleToOffset(
+                minPx,
+                maxPx,
+                activeRangeStart
+            )
+            rawOffsetEnd = scaleToOffset(
+                minPx,
+                maxPx,
+                activeRangeEnd
+            )
+        }
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
index 05b2b2c8..dfd656f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
@@ -90,7 +90,6 @@
 class DismissState(
     initialValue: DismissValue,
     confirmValueChange: (DismissValue) -> Boolean = { true },
-    @Suppress("PrimitiveInLambda")
     positionalThreshold: Density.(totalDistance: Float) -> Float =
         SwipeToDismissDefaults.FixedPositionalThreshold,
 ) {
@@ -180,7 +179,6 @@
          */
         fun Saver(
             confirmValueChange: (DismissValue) -> Boolean,
-            @Suppress("PrimitiveInLambda")
             positionalThreshold: Density.(totalDistance: Float) -> Float,
         ) =
             Saver<DismissState, DismissValue>(
@@ -208,7 +206,6 @@
 fun rememberDismissState(
     initialValue: DismissValue = Default,
     confirmValueChange: (DismissValue) -> Boolean = { true },
-    @Suppress("PrimitiveInLambda")
     positionalThreshold: Density.(totalDistance: Float) -> Float =
         SwipeToDismissDefaults.FixedPositionalThreshold,
 ): DismissState {
@@ -276,7 +273,6 @@
 @ExperimentalMaterial3Api
 object SwipeToDismissDefaults {
     /** Default positional threshold of 56.dp for [DismissState]. */
-    @Suppress("PrimitiveInLambda")
     val FixedPositionalThreshold: Density.(totalDistance: Float) -> Float = { _ -> 56.dp.toPx() }
 }
 
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
index f768d19..3155cfd 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
@@ -193,7 +193,6 @@
         }
     }
 
-    @Suppress("PrimitiveInLambda")
     internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
 
     internal var velocityThreshold by mutableFloatStateOf(0f)
@@ -759,7 +758,6 @@
     offset: Float,
     lastValue: Float,
     anchors: Set<Float>,
-    @Suppress("PrimitiveInLambda")
     thresholds: (Float, Float) -> Float,
     velocity: Float,
     velocityThreshold: Float
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
index 7b8f75e..8db36b9 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
@@ -110,7 +110,6 @@
     state: SwipeableV2State<T>,
     possibleValues: Set<T>,
     anchorChangeHandler: AnchorChangeHandler<T>? = null,
-    @Suppress("PrimitiveInLambda")
     calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,
 ) = this.then(SwipeAnchorsModifier(
     onDensityChanged = { state.density = it },
@@ -169,7 +168,6 @@
     initialValue: T,
     internal val animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
     internal val confirmValueChange: (newValue: T) -> Boolean = { true },
-    @Suppress("PrimitiveInLambda")
     internal val positionalThreshold: Density.(totalDistance: Float) -> Float =
         SwipeableV2Defaults.PositionalThreshold,
     internal val velocityThreshold: Dp = SwipeableV2Defaults.VelocityThreshold,
@@ -492,7 +490,6 @@
         fun <T : Any> Saver(
             animationSpec: AnimationSpec<Float>,
             confirmValueChange: (T) -> Boolean,
-            @Suppress("PrimitiveInLambda")
             positionalThreshold: Density.(distance: Float) -> Float,
             velocityThreshold: Dp
         ) = Saver<SwipeableV2State<T>, T>(
@@ -550,7 +547,6 @@
  * @see [fractionalPositionalThreshold] for a fractional positional threshold
  */
 @ExperimentalMaterial3Api
-@Suppress("PrimitiveInLambda")
 internal fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {
     threshold.toPx()
 }
@@ -563,7 +559,6 @@
  * @see [fixedPositionalThreshold] for a fixed positional threshold
  */
 @ExperimentalMaterial3Api
-@Suppress("PrimitiveInLambda")
 internal fun fractionalPositionalThreshold(
     fraction: Float
 ): Density.(distance: Float) -> Float = { distance -> distance * fraction }
@@ -590,7 +585,6 @@
      * The default positional threshold (56 dp) used by [rememberSwipeableV2State]
      */
     @ExperimentalMaterial3Api
-    @Suppress("PrimitiveInLambda")
     val PositionalThreshold: Density.(totalDistance: Float) -> Float =
         fixedPositionalThreshold(56.dp)
 
@@ -611,7 +605,6 @@
     @ExperimentalMaterial3Api
     internal fun <T> ReconcileAnimationOnAnchorChangeHandler(
         state: SwipeableV2State<T>,
-        @Suppress("PrimitiveInLambda")
         animate: (target: T, velocity: Float) -> Unit,
         snap: (target: T) -> Unit
     ) = AnchorChangeHandler { previousTarget, previousAnchors, newAnchors ->
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 e5e80146..98ac45c 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
@@ -106,7 +106,6 @@
     val thumbPaddingStart = (SwitchHeight - uncheckedThumbDiameter) / 2
     val minBound = with(LocalDensity.current) { thumbPaddingStart.toPx() }
     val maxBound = with(LocalDensity.current) { ThumbPathLength.toPx() }
-    @Suppress("PrimitiveInLambda")
     val valueToOffset = remember<(Boolean) -> Float>(minBound, maxBound) {
         { value -> if (value) maxBound else minBound }
     }
@@ -342,27 +341,45 @@
 /**
  * Represents the colors used by a [Switch] in different states
  *
+ * @constructor create an instance with arbitrary colors.
  * See [SwitchDefaults.colors] for the default implementation that follows Material
  * specifications.
+ *
+ * @param checkedThumbColor the color used for the thumb when enabled and checked
+ * @param checkedTrackColor the color used for the track when enabled and checked
+ * @param checkedBorderColor the color used for the border when enabled and checked
+ * @param checkedIconColor the color used for the icon when enabled and checked
+ * @param uncheckedThumbColor the color used for the thumb when enabled and unchecked
+ * @param uncheckedTrackColor the color used for the track when enabled and unchecked
+ * @param uncheckedBorderColor the color used for the border when enabled and unchecked
+ * @param uncheckedIconColor the color used for the icon when enabled and unchecked
+ * @param disabledCheckedThumbColor the color used for the thumb when disabled and checked
+ * @param disabledCheckedTrackColor the color used for the track when disabled and checked
+ * @param disabledCheckedBorderColor the color used for the border when disabled and checked
+ * @param disabledCheckedIconColor the color used for the icon when disabled and checked
+ * @param disabledUncheckedThumbColor the color used for the thumb when disabled and unchecked
+ * @param disabledUncheckedTrackColor the color used for the track when disabled and unchecked
+ * @param disabledUncheckedBorderColor the color used for the border when disabled and unchecked
+ * @param disabledUncheckedIconColor the color used for the icon when disabled and unchecked
  */
 @Immutable
-class SwitchColors internal constructor(
-    private val checkedThumbColor: Color,
-    private val checkedTrackColor: Color,
-    private val checkedBorderColor: Color,
-    private val checkedIconColor: Color,
-    private val uncheckedThumbColor: Color,
-    private val uncheckedTrackColor: Color,
-    private val uncheckedBorderColor: Color,
-    private val uncheckedIconColor: Color,
-    private val disabledCheckedThumbColor: Color,
-    private val disabledCheckedTrackColor: Color,
-    private val disabledCheckedBorderColor: Color,
-    private val disabledCheckedIconColor: Color,
-    private val disabledUncheckedThumbColor: Color,
-    private val disabledUncheckedTrackColor: Color,
-    private val disabledUncheckedBorderColor: Color,
-    private val disabledUncheckedIconColor: Color
+class SwitchColors constructor(
+    val checkedThumbColor: Color,
+    val checkedTrackColor: Color,
+    val checkedBorderColor: Color,
+    val checkedIconColor: Color,
+    val uncheckedThumbColor: Color,
+    val uncheckedTrackColor: Color,
+    val uncheckedBorderColor: Color,
+    val uncheckedIconColor: Color,
+    val disabledCheckedThumbColor: Color,
+    val disabledCheckedTrackColor: Color,
+    val disabledCheckedBorderColor: Color,
+    val disabledCheckedIconColor: Color,
+    val disabledUncheckedThumbColor: Color,
+    val disabledUncheckedTrackColor: Color,
+    val disabledUncheckedBorderColor: Color,
+    val disabledUncheckedIconColor: Color
 ) {
     /**
      * Represents the color used for the switch's thumb, depending on [enabled] and [checked].
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 20f2e86..e23732f 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
@@ -830,7 +830,6 @@
     private fun intrinsicWidth(
         measurables: List<IntrinsicMeasurable>,
         height: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         val textFieldWidth =
@@ -868,7 +867,6 @@
     private fun IntrinsicMeasureScope.intrinsicHeight(
         measurables: List<IntrinsicMeasurable>,
         width: Int,
-        @Suppress("PrimitiveInLambda")
         intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int
     ): Int {
         var remainingWidth = width
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
index db2f2e7..7929f2e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
@@ -1688,54 +1688,105 @@
  * Represents the colors of the input text, container, and content (including label, placeholder,
  * leading and trailing icons) used in a text field in different states.
  *
+ * @constructor create an instance with arbitrary colors.
  * See [TextFieldDefaults.colors] for the default colors used in [TextField].
  * See [OutlinedTextFieldDefaults.colors] for the default colors used in [OutlinedTextField].
+ *
+ * @param focusedTextColor the color used for the input text of this text field when focused
+ * @param unfocusedTextColor the color used for the input text of this text field when not
+ * focused
+ * @param disabledTextColor the color used for the input text of this text field when disabled
+ * @param errorTextColor the color used for the input text of this text field when in error
+ * state
+ * @param focusedContainerColor the container color for this text field when focused
+ * @param unfocusedContainerColor the container color for this text field when not focused
+ * @param disabledContainerColor the container color for this text field when disabled
+ * @param errorContainerColor the container color for this text field when in error state
+ * @param cursorColor the cursor color for this text field
+ * @param errorCursorColor the cursor color for this text field when in error state
+ * @param textSelectionColors the colors used when the input text of this text field is selected
+ * @param focusedIndicatorColor the indicator color for this text field when focused
+ * @param unfocusedIndicatorColor the indicator color for this text field when not focused
+ * @param disabledIndicatorColor the indicator color for this text field when disabled
+ * @param errorIndicatorColor the indicator color for this text field when in error state
+ * @param focusedLeadingIconColor the leading icon color for this text field when focused
+ * @param unfocusedLeadingIconColor the leading icon color for this text field when not focused
+ * @param disabledLeadingIconColor the leading icon color for this text field when disabled
+ * @param errorLeadingIconColor the leading icon color for this text field when in error state
+ * @param focusedTrailingIconColor the trailing icon color for this text field when focused
+ * @param unfocusedTrailingIconColor the trailing icon color for this text field when not
+ * focused
+ * @param disabledTrailingIconColor the trailing icon color for this text field when disabled
+ * @param errorTrailingIconColor the trailing icon color for this text field when in error state
+ * @param focusedLabelColor the label color for this text field when focused
+ * @param unfocusedLabelColor the label color for this text field when not focused
+ * @param disabledLabelColor the label color for this text field when disabled
+ * @param errorLabelColor the label color for this text field when in error state
+ * @param focusedPlaceholderColor the placeholder color for this text field when focused
+ * @param unfocusedPlaceholderColor the placeholder color for this text field when not focused
+ * @param disabledPlaceholderColor the placeholder color for this text field when disabled
+ * @param errorPlaceholderColor the placeholder color for this text field when in error state
+ * @param focusedSupportingTextColor the supporting text color for this text field when focused
+ * @param unfocusedSupportingTextColor the supporting text color for this text field when not
+ * focused
+ * @param disabledSupportingTextColor the supporting text color for this text field when
+ * disabled
+ * @param errorSupportingTextColor the supporting text color for this text field when in error
+ * state
+ * @param focusedPrefixColor the prefix color for this text field when focused
+ * @param unfocusedPrefixColor the prefix color for this text field when not focused
+ * @param disabledPrefixColor the prefix color for this text field when disabled
+ * @param errorPrefixColor the prefix color for this text field when in error state
+ * @param focusedSuffixColor the suffix color for this text field when focused
+ * @param unfocusedSuffixColor the suffix color for this text field when not focused
+ * @param disabledSuffixColor the suffix color for this text field when disabled
+ * @param errorSuffixColor the suffix color for this text field when in error state
  */
 @Immutable
-class TextFieldColors internal constructor(
-    private val focusedTextColor: Color,
-    private val unfocusedTextColor: Color,
-    private val disabledTextColor: Color,
-    private val errorTextColor: Color,
-    private val focusedContainerColor: Color,
-    private val unfocusedContainerColor: Color,
-    private val disabledContainerColor: Color,
-    private val errorContainerColor: Color,
-    private val cursorColor: Color,
-    private val errorCursorColor: Color,
-    private val textSelectionColors: TextSelectionColors,
-    private val focusedIndicatorColor: Color,
-    private val unfocusedIndicatorColor: Color,
-    private val disabledIndicatorColor: Color,
-    private val errorIndicatorColor: Color,
-    private val focusedLeadingIconColor: Color,
-    private val unfocusedLeadingIconColor: Color,
-    private val disabledLeadingIconColor: Color,
-    private val errorLeadingIconColor: Color,
-    private val focusedTrailingIconColor: Color,
-    private val unfocusedTrailingIconColor: Color,
-    private val disabledTrailingIconColor: Color,
-    private val errorTrailingIconColor: Color,
-    private val focusedLabelColor: Color,
-    private val unfocusedLabelColor: Color,
-    private val disabledLabelColor: Color,
-    private val errorLabelColor: Color,
-    private val focusedPlaceholderColor: Color,
-    private val unfocusedPlaceholderColor: Color,
-    private val disabledPlaceholderColor: Color,
-    private val errorPlaceholderColor: Color,
-    private val focusedSupportingTextColor: Color,
-    private val unfocusedSupportingTextColor: Color,
-    private val disabledSupportingTextColor: Color,
-    private val errorSupportingTextColor: Color,
-    private val focusedPrefixColor: Color,
-    private val unfocusedPrefixColor: Color,
-    private val disabledPrefixColor: Color,
-    private val errorPrefixColor: Color,
-    private val focusedSuffixColor: Color,
-    private val unfocusedSuffixColor: Color,
-    private val disabledSuffixColor: Color,
-    private val errorSuffixColor: Color,
+class TextFieldColors constructor(
+    val focusedTextColor: Color,
+    val unfocusedTextColor: Color,
+    val disabledTextColor: Color,
+    val errorTextColor: Color,
+    val focusedContainerColor: Color,
+    val unfocusedContainerColor: Color,
+    val disabledContainerColor: Color,
+    val errorContainerColor: Color,
+    val cursorColor: Color,
+    val errorCursorColor: Color,
+    val textSelectionColors: TextSelectionColors,
+    val focusedIndicatorColor: Color,
+    val unfocusedIndicatorColor: Color,
+    val disabledIndicatorColor: Color,
+    val errorIndicatorColor: Color,
+    val focusedLeadingIconColor: Color,
+    val unfocusedLeadingIconColor: Color,
+    val disabledLeadingIconColor: Color,
+    val errorLeadingIconColor: Color,
+    val focusedTrailingIconColor: Color,
+    val unfocusedTrailingIconColor: Color,
+    val disabledTrailingIconColor: Color,
+    val errorTrailingIconColor: Color,
+    val focusedLabelColor: Color,
+    val unfocusedLabelColor: Color,
+    val disabledLabelColor: Color,
+    val errorLabelColor: Color,
+    val focusedPlaceholderColor: Color,
+    val unfocusedPlaceholderColor: Color,
+    val disabledPlaceholderColor: Color,
+    val errorPlaceholderColor: Color,
+    val focusedSupportingTextColor: Color,
+    val unfocusedSupportingTextColor: Color,
+    val disabledSupportingTextColor: Color,
+    val errorSupportingTextColor: Color,
+    val focusedPrefixColor: Color,
+    val unfocusedPrefixColor: Color,
+    val disabledPrefixColor: Color,
+    val errorPrefixColor: Color,
+    val focusedSuffixColor: Color,
+    val unfocusedSuffixColor: Color,
+    val disabledSuffixColor: Color,
+    val errorSuffixColor: Color,
 ) {
     /**
      * Represents the color used for the leading icon of this text field.
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
index 698b2a5..2ee2a6c 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldImpl.kt
@@ -297,7 +297,6 @@
         unfocusedTextStyleColor: Color,
         contentColor: @Composable (InputPhase) -> Color,
         showLabel: Boolean,
-        @Suppress("PrimitiveInLambda")
         content: @Composable (
             labelProgress: Float,
             labelTextStyleColor: Color,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
index ca5f3c1..dded021 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
@@ -320,26 +320,52 @@
 /**
  * Represents the colors used by a [TimePicker] in different states
  *
+ * @constructor create an instance with arbitrary colors.
  * See [TimePickerDefaults.colors] for the default implementation that follows Material
  * specifications.
+ *
+ * @param clockDialColor The color of the clock dial.
+ * @param clockDialSelectedContentColor the color of the numbers of the clock dial when they
+ * are selected or overlapping with the selector
+ * @param clockDialUnselectedContentColor the color of the numbers of the clock dial when they
+ * are unselected
+ * @param selectorColor The color of the clock dial selector.
+ * @param containerColor The container color of the time picker.
+ * @param periodSelectorBorderColor the color used for the border of the AM/PM toggle.
+ * @param periodSelectorSelectedContainerColor the color used for the selected container of
+ * the AM/PM toggle
+ * @param periodSelectorUnselectedContainerColor the color used for the unselected container
+ * of the AM/PM toggle
+ * @param periodSelectorSelectedContentColor color used for the selected content of
+ * the AM/PM toggle
+ * @param periodSelectorUnselectedContentColor color used for the unselected content
+ * of the AM/PM toggle
+ * @param timeSelectorSelectedContainerColor color used for the selected container of the
+ * display buttons to switch between hour and minutes
+ * @param timeSelectorUnselectedContainerColor color used for the unselected container of the
+ * display buttons to switch between hour and minutes
+ * @param timeSelectorSelectedContentColor color used for the selected content of the display
+ * buttons to switch between hour and minutes
+ * @param timeSelectorUnselectedContentColor color used for the unselected content of the
+ * display buttons to switch between hour and minutes
  */
 @Immutable
 @ExperimentalMaterial3Api
-class TimePickerColors internal constructor(
-    internal val clockDialColor: Color,
-    internal val selectorColor: Color,
-    internal val containerColor: Color,
-    internal val periodSelectorBorderColor: Color,
-    private val clockDialSelectedContentColor: Color,
-    private val clockDialUnselectedContentColor: Color,
-    private val periodSelectorSelectedContainerColor: Color,
-    private val periodSelectorUnselectedContainerColor: Color,
-    private val periodSelectorSelectedContentColor: Color,
-    private val periodSelectorUnselectedContentColor: Color,
-    private val timeSelectorSelectedContainerColor: Color,
-    private val timeSelectorUnselectedContainerColor: Color,
-    private val timeSelectorSelectedContentColor: Color,
-    private val timeSelectorUnselectedContentColor: Color,
+class TimePickerColors constructor(
+    val clockDialColor: Color,
+    val selectorColor: Color,
+    val containerColor: Color,
+    val periodSelectorBorderColor: Color,
+    val clockDialSelectedContentColor: Color,
+    val clockDialUnselectedContentColor: Color,
+    val periodSelectorSelectedContainerColor: Color,
+    val periodSelectorUnselectedContainerColor: Color,
+    val periodSelectorSelectedContentColor: Color,
+    val periodSelectorUnselectedContentColor: Color,
+    val timeSelectorSelectedContainerColor: Color,
+    val timeSelectorUnselectedContainerColor: Color,
+    val timeSelectorSelectedContentColor: Color,
+    val timeSelectorUnselectedContentColor: Color,
 ) {
     internal fun periodSelectorContainerColor(selected: Boolean) =
         if (selected) {
@@ -496,7 +522,7 @@
 ) {
     init {
         require(initialHour in 0..23) { "initialHour should in [0..23] range" }
-        require(initialHour in 0..59) { "initialMinute should be in [0..59] range" }
+        require(initialMinute in 0..59) { "initialMinute should be in [0..59] range" }
     }
 
     val minute: Int get() = minuteAngle.toMinute()
@@ -524,11 +550,11 @@
     internal val values get() = if (selection == Selection.Minute) Minutes else Hours
 
     internal var selection by mutableStateOf(Selection.Hour)
-    internal var isAfternoonToggle by mutableStateOf(initialHour > 12 && !is24Hour)
+    internal var isAfternoonToggle by mutableStateOf(initialHour >= 12 && !is24Hour)
     internal var isInnerCircle by mutableStateOf(initialHour >= 12)
 
     internal var hourAngle by mutableFloatStateOf(
-        RadiansPerHour * initialHour % 12 - FullCircle / 4
+        RadiansPerHour * (initialHour % 12) - FullCircle / 4
     )
     internal var minuteAngle by mutableFloatStateOf(
         RadiansPerMinute * initialMinute - FullCircle / 4
@@ -544,8 +570,8 @@
     }
 
     internal fun setHour(hour: Int) {
-        isInnerCircle = hour > 12 || hour == 0
-        hourAngle = RadiansPerHour * hour % 12 - FullCircle / 4
+        isInnerCircle = hour >= 12
+        hourAngle = RadiansPerHour * (hour % 12) - FullCircle / 4
     }
 
     internal fun moveSelector(x: Float, y: Float, maxDist: Float) {
@@ -591,7 +617,6 @@
     }
 
     private fun hourForDisplay(hour: Int): Int = when {
-        is24hour && isInnerCircle && hour == 0 -> 12
         is24hour -> hour % 24
         hour % 12 == 0 -> 12
         isAfternoon -> hour - 12
@@ -610,8 +635,8 @@
     }
 
     private fun Float.toMinute(): Int {
-        val hourOffset: Float = RadiansPerMinute / 2
-        val totalOffset = hourOffset + QuarterCircle
+        val minuteOffset: Float = RadiansPerMinute / 2
+        val totalOffset = minuteOffset + QuarterCircle
         return ((this + totalOffset) / RadiansPerMinute).toInt() % 60
     }
 
@@ -788,7 +813,7 @@
         }
 
         if (!state.is24hour) {
-            Box(modifier.padding(start = PeriodToggleMargin)) {
+            Box(Modifier.padding(start = PeriodToggleMargin)) {
                 VerticalPeriodToggle(
                     modifier = Modifier.size(
                         PeriodSelectorContainerWidth,
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
index b013276..06d4a03 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
@@ -172,7 +172,7 @@
                 "specialized primitive state implementation for `Int`, `Long`, `Float`, and " +
                 "`Double` when the state does not need to track null values and does not " +
                 "override the default `SnapshotMutationPolicy`.",
-            category = Category.PERFORMANCE, priority = 3, severity = Severity.WARNING,
+            category = Category.PERFORMANCE, priority = 3, severity = Severity.INFORMATIONAL,
             implementation = Implementation(
                 AutoboxingStateCreationDetector::class.java,
                 EnumSet.of(Scope.JAVA_FILE)
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
index 06eb0d1..35b6b07 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
@@ -94,10 +94,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         val state = mutableStateOf<$type>($stateValue)
                                     ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -130,10 +130,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         val state = mutableStateOf($stateValue)
                                     ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -166,10 +166,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         val state = mutableStateOf<$fqType>($stateValue)
                                     ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -202,10 +202,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         var state by mutableStateOf<$type>($stateValue)
                                      ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -238,10 +238,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         var state by mutableStateOf($stateValue)
                                      ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -274,10 +274,10 @@
                 )
             ).run().expect(
                 """
-src/androidx/compose/runtime/lint/test/Test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/Test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         var state by mutableStateOf(initialValue)
                                      ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
             ).expectFixDiffs(
                 """
@@ -310,10 +310,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         var state: $type by mutableStateOf($stateValue)
                                    ${" ".repeat(type.length)}    ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
@@ -368,10 +368,10 @@
             )
         ).run().expect(
             """
-src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+src/androidx/compose/runtime/lint/test/test.kt:8: Information: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
                         val state = mutableStateOf($stateValue, structuralEqualityPolicy())
                                     ~~~~~~~~~~~~~~
-0 errors, 1 warnings
+0 errors, 0 warnings
             """
         ).expectFixDiffs(
             """
diff --git a/compose/runtime/runtime-livedata/api/public_plus_experimental_1.5.0-beta01.txt b/compose/runtime/runtime-livedata/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..192cf6a
--- /dev/null
+++ b/compose/runtime/runtime-livedata/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.compose.runtime.livedata {
+
+  public final class LiveDataAdapterKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> observeAsState(androidx.lifecycle.LiveData<T>);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> observeAsState(androidx.lifecycle.LiveData<T>, R initial);
+  }
+
+}
+
diff --git a/compose/runtime/runtime-rxjava2/api/public_plus_experimental_1.5.0-beta01.txt b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..43f9fd4
--- /dev/null
+++ b/compose/runtime/runtime-rxjava2/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,13 @@
+// Signature format: 4.0
+package androidx.compose.runtime.rxjava2 {
+
+  public final class RxJava2AdapterKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.Completable);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Flowable<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Maybe<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Observable<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.Single<T>, R initial);
+  }
+
+}
+
diff --git a/compose/runtime/runtime-rxjava3/api/public_plus_experimental_1.5.0-beta01.txt b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..357541c8
--- /dev/null
+++ b/compose/runtime/runtime-rxjava3/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,13 @@
+// Signature format: 4.0
+package androidx.compose.runtime.rxjava3 {
+
+  public final class RxJava3AdapterKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<java.lang.Boolean> subscribeAsState(io.reactivex.rxjava3.core.Completable);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Flowable<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Maybe<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Observable<T>, R initial);
+    method @androidx.compose.runtime.Composable public static <R, T extends R> androidx.compose.runtime.State<R> subscribeAsState(io.reactivex.rxjava3.core.Single<T>, R initial);
+  }
+
+}
+
diff --git a/compose/runtime/runtime-saveable-lint/lint-baseline.xml b/compose/runtime/runtime-saveable-lint/lint-baseline.xml
deleted file mode 100644
index fe5f34e..0000000
--- a/compose/runtime/runtime-saveable-lint/lint-baseline.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="LintError"
-        message="Unexpected failure during lint analysis (this is a bug in lint or one of the libraries it depends on)&#xA;&#xA;Message: GC overhead limit exceeded&#xA;Stack: `OutOfMemoryError:`&#xA;&#xA;You can run with --stacktrace or set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.">
-        <location
-            file="runtime-saveable-lint"/>
-    </issue>
-
-</issues>
diff --git a/compose/runtime/runtime-saveable/api/public_plus_experimental_1.5.0-beta01.txt b/compose/runtime/runtime-saveable/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..6cf4941
--- /dev/null
+++ b/compose/runtime/runtime-saveable/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,58 @@
+// Signature format: 4.0
+package androidx.compose.runtime.saveable {
+
+  public final class ListSaverKt {
+    method public static <Original, Saveable> androidx.compose.runtime.saveable.Saver<Original,java.lang.Object> listSaver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.saveable.SaverScope,? super Original,? extends java.util.List<? extends Saveable>> save, kotlin.jvm.functions.Function1<? super java.util.List<? extends Saveable>,? extends Original> restore);
+  }
+
+  public final class MapSaverKt {
+    method public static <T> androidx.compose.runtime.saveable.Saver<T,java.lang.Object> mapSaver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.saveable.SaverScope,? super T,? extends java.util.Map<java.lang.String,?>> save, kotlin.jvm.functions.Function1<? super java.util.Map<java.lang.String,?>,? extends T> restore);
+  }
+
+  public final class RememberSaveableKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.MutableState<T> rememberSaveable(Object![]? inputs, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, optional String? key, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
+    method @androidx.compose.runtime.Composable public static <T> T rememberSaveable(Object![]? inputs, optional androidx.compose.runtime.saveable.Saver<T,?> saver, optional String? key, kotlin.jvm.functions.Function0<? extends T> init);
+  }
+
+  public interface SaveableStateHolder {
+    method @androidx.compose.runtime.Composable public void SaveableStateProvider(Object key, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public void removeState(Object key);
+  }
+
+  public final class SaveableStateHolderKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.saveable.SaveableStateHolder rememberSaveableStateHolder();
+  }
+
+  public interface SaveableStateRegistry {
+    method public boolean canBeSaved(Object value);
+    method public Object? consumeRestored(String key);
+    method public java.util.Map<java.lang.String,java.util.List<java.lang.Object>> performSave();
+    method public androidx.compose.runtime.saveable.SaveableStateRegistry.Entry registerProvider(String key, kotlin.jvm.functions.Function0<?> valueProvider);
+  }
+
+  public static interface SaveableStateRegistry.Entry {
+    method public void unregister();
+  }
+
+  public final class SaveableStateRegistryKt {
+    method public static androidx.compose.runtime.saveable.SaveableStateRegistry SaveableStateRegistry(java.util.Map<java.lang.String,? extends java.util.List<?>>? restoredValues, kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Boolean> canBeSaved);
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.runtime.saveable.SaveableStateRegistry> getLocalSaveableStateRegistry();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.runtime.saveable.SaveableStateRegistry> LocalSaveableStateRegistry;
+  }
+
+  public interface Saver<Original, Saveable> {
+    method public Original? restore(Saveable value);
+    method public Saveable? save(androidx.compose.runtime.saveable.SaverScope, Original value);
+  }
+
+  public final class SaverKt {
+    method public static <Original, Saveable> androidx.compose.runtime.saveable.Saver<Original,Saveable> Saver(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.saveable.SaverScope,? super Original,? extends Saveable> save, kotlin.jvm.functions.Function1<? super Saveable,? extends Original> restore);
+    method public static <T> androidx.compose.runtime.saveable.Saver<T,java.lang.Object> autoSaver();
+  }
+
+  public fun interface SaverScope {
+    method public boolean canBeSaved(Object value);
+  }
+
+}
+
diff --git a/compose/runtime/runtime-saveable/build.gradle b/compose/runtime/runtime-saveable/build.gradle
index d23376d..c219a78 100644
--- a/compose/runtime/runtime-saveable/build.gradle
+++ b/compose/runtime/runtime-saveable/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -30,6 +31,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/runtime/runtime/api/1.5.0-beta01.txt b/compose/runtime/runtime/api/1.5.0-beta01.txt
index 095c02f..ac9ddb4 100644
--- a/compose/runtime/runtime/api/1.5.0-beta01.txt
+++ b/compose/runtime/runtime/api/1.5.0-beta01.txt
@@ -47,11 +47,6 @@
   @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface Composable {
   }
 
-  @androidx.compose.runtime.InternalComposeApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ComposableInferredTarget {
-    method public abstract String scheme();
-    property public abstract String scheme;
-  }
-
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface ComposableOpenTarget {
     method public abstract int index();
     property public abstract int index;
@@ -104,7 +99,6 @@
 
   public sealed interface Composer {
     method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
-    method @androidx.compose.runtime.InternalComposeApi public androidx.compose.runtime.CompositionContext buildContext();
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(byte value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -116,7 +110,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(short value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changedInstance(Object? value);
     method public void collectParameterInformation();
-    method @androidx.compose.runtime.InternalComposeApi public <T> T consume(androidx.compose.runtime.CompositionLocal<T> key);
     method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
     method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
     method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
@@ -125,7 +118,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endNode();
-    method @androidx.compose.runtime.InternalComposeApi public void endProviders();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReplaceableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.ScopeUpdateScope? endRestartGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReusableGroup();
@@ -142,11 +134,7 @@
     method public androidx.compose.runtime.RecomposeScope? getRecomposeScope();
     method public Object? getRecomposeScopeIdentity();
     method public boolean getSkipping();
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<?> value, Object? parameter);
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContentReferences(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
     method @androidx.compose.runtime.ComposeCompilerApi public Object joinKey(Object? left, Object? right);
-    method @androidx.compose.runtime.InternalComposeApi public void recordSideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
-    method @androidx.compose.runtime.InternalComposeApi public void recordUsed(androidx.compose.runtime.RecomposeScope scope);
     method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
     method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
@@ -156,7 +144,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
     method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
-    method @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<?>![] values);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
@@ -164,7 +151,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public void useNode();
     property public abstract androidx.compose.runtime.Applier<?> applier;
-    property @androidx.compose.runtime.InternalComposeApi @org.jetbrains.annotations.TestOnly public abstract kotlin.coroutines.CoroutineContext applyCoroutineContext;
     property @org.jetbrains.annotations.TestOnly public abstract androidx.compose.runtime.ControlledComposition composition;
     property public abstract androidx.compose.runtime.tooling.CompositionData compositionData;
     property public abstract int compoundKeyHash;
@@ -180,7 +166,6 @@
 
   public static final class Composer.Companion {
     method public Object getEmpty();
-    method @androidx.compose.runtime.InternalComposeTracingApi public void setTracer(androidx.compose.runtime.CompositionTracer tracer);
     property public final Object Empty;
   }
 
@@ -211,10 +196,7 @@
 
   public final class CompositionKt {
     method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
-    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
     method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
-    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
   @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
@@ -242,21 +224,13 @@
     property public final androidx.compose.runtime.CompositionLocalMap Empty;
   }
 
-  @androidx.compose.runtime.InternalComposeTracingApi public interface CompositionTracer {
-    method public boolean isTraceInProgress();
-    method public void traceEventEnd();
-    method public void traceEventStart(int key, int dirty1, int dirty2, String info);
-  }
-
   public sealed interface ControlledComposition extends androidx.compose.runtime.Composition {
     method public void applyChanges();
     method public void applyLateChanges();
     method public void changesApplied();
     method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
-    method @androidx.compose.runtime.InternalComposeApi public void disposeUnusedMovableContent(androidx.compose.runtime.MovableContentState state);
     method public boolean getHasPendingChanges();
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
     method public void invalidateAll();
     method public boolean isComposing();
     method public boolean observesAnyOf(java.util.Set<?> values);
@@ -265,7 +239,6 @@
     method public void recordModificationsOf(java.util.Set<?> values);
     method public void recordReadOf(Object value);
     method public void recordWriteOf(Object value);
-    method @androidx.compose.runtime.InternalComposeApi public void verifyConsistent();
     property public abstract boolean hasPendingChanges;
     property public abstract boolean isComposing;
   }
@@ -304,9 +277,6 @@
     method @androidx.compose.runtime.Composable public static inline kotlinx.coroutines.CoroutineScope rememberCoroutineScope(optional kotlin.jvm.functions.Function0<? extends kotlin.coroutines.CoroutineContext> getContext);
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API for Compose and is likely to change before becoming " + "stable.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalComposeApi {
-  }
-
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExplicitGroupsComposable {
   }
 
@@ -327,12 +297,6 @@
     property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API for Compose modules that may change frequently " + "and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalComposeApi {
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeTracingApi {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LongState extends androidx.compose.runtime.State<java.lang.Long> {
     method public long getLongValue();
     method public default Long getValue();
@@ -357,12 +321,6 @@
     method public static suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
   }
 
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContent<P> {
-    ctor public MovableContent(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
-    method public kotlin.jvm.functions.Function1<P,kotlin.Unit> getContent();
-    property public final kotlin.jvm.functions.Function1<P,kotlin.Unit> content;
-  }
-
   public final class MovableContentKt {
     method public static kotlin.jvm.functions.Function0<kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <P> kotlin.jvm.functions.Function1<P,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
@@ -375,12 +333,6 @@
     method public static <R, P1, P2, P3> kotlin.jvm.functions.Function4<R,P1,P2,P3,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function4<? super R,? super P1,? super P2,? super P3,kotlin.Unit> content);
   }
 
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContentState {
-  }
-
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContentStateReference {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableDoubleState extends androidx.compose.runtime.DoubleState androidx.compose.runtime.MutableState<java.lang.Double> {
     method public void setDoubleValue(double);
     method public default void setValue(double);
@@ -477,7 +429,6 @@
     method public void pauseCompositionFrameClock();
     method public void resumeCompositionFrameClock();
     method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public final long changeCount;
     property public final kotlinx.coroutines.flow.StateFlow<androidx.compose.runtime.Recomposer.State> currentState;
     property public kotlin.coroutines.CoroutineContext effectCoroutineContext;
@@ -705,20 +656,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
   }
 
-  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface Decoy {
-    method public abstract String[] signature();
-    method public abstract String targetName();
-    property public abstract String[] signature;
-    property public abstract String targetName;
-  }
-
-  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface DecoyImplementation {
-    method public abstract long id();
-    method public abstract String name();
-    property public abstract long id;
-    property public abstract String name;
-  }
-
   public final class DecoyKt {
     method @androidx.compose.runtime.ComposeCompilerApi public static Void illegalDecoyCallException(String fName);
   }
@@ -754,10 +691,7 @@
   }
 
   public final class LiveLiteralKt {
-    method @androidx.compose.runtime.InternalComposeApi public static void enableLiveLiterals();
     method public static boolean isLiveLiteralsEnabled();
-    method @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.InternalComposeApi public static <T> androidx.compose.runtime.State<T> liveLiteral(String key, T value);
-    method @androidx.compose.runtime.InternalComposeApi public static void updateLiveLiteralValue(String key, Object? value);
     property public static final boolean isLiveLiteralsEnabled;
   }
 
@@ -822,8 +756,6 @@
     method public abstract androidx.compose.runtime.snapshots.Snapshot getRoot();
     method public abstract boolean hasPendingChanges();
     method public abstract androidx.compose.runtime.snapshots.Snapshot takeNestedSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
-    method @androidx.compose.runtime.ExperimentalComposeApi public final androidx.compose.runtime.snapshots.Snapshot? unsafeEnter();
-    method @androidx.compose.runtime.ExperimentalComposeApi public final void unsafeLeave(androidx.compose.runtime.snapshots.Snapshot? oldSnapshot);
     property public int id;
     property public abstract boolean readOnly;
     property public abstract androidx.compose.runtime.snapshots.Snapshot root;
@@ -836,7 +768,6 @@
     method public boolean isApplyObserverNotificationPending();
     method public void notifyObjectsInitialized();
     method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
-    method @androidx.compose.runtime.InternalComposeApi public int openSnapshotCount();
     method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
     method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
     method public void sendApplyNotifications();
@@ -876,17 +807,6 @@
     field public static final androidx.compose.runtime.snapshots.SnapshotApplyResult.Success INSTANCE;
   }
 
-  @androidx.compose.runtime.ExperimentalComposeApi public interface SnapshotContextElement extends kotlin.coroutines.CoroutineContext.Element {
-    field public static final androidx.compose.runtime.snapshots.SnapshotContextElement.Key Key;
-  }
-
-  public static final class SnapshotContextElement.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.runtime.snapshots.SnapshotContextElement> {
-  }
-
-  public final class SnapshotContextElementKt {
-    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.snapshots.SnapshotContextElement asContextElement(androidx.compose.runtime.snapshots.Snapshot);
-  }
-
   public final class SnapshotKt {
     method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state);
     method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
diff --git a/compose/runtime/runtime/api/public_plus_experimental_1.5.0-beta01.txt b/compose/runtime/runtime/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..095c02f
--- /dev/null
+++ b/compose/runtime/runtime/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,1021 @@
+// Signature format: 4.0
+package androidx.compose.runtime {
+
+  public abstract class AbstractApplier<T> implements androidx.compose.runtime.Applier<T> {
+    ctor public AbstractApplier(T root);
+    method public final void clear();
+    method public void down(T node);
+    method public T getCurrent();
+    method public final T getRoot();
+    method protected final void move(java.util.List<T>, int from, int to, int count);
+    method protected abstract void onClear();
+    method protected final void remove(java.util.List<T>, int index, int count);
+    method protected void setCurrent(T!);
+    method public void up();
+    property public T current;
+    property public final T root;
+  }
+
+  public final class ActualAndroid_androidKt {
+    method @Deprecated public static androidx.compose.runtime.MonotonicFrameClock getDefaultMonotonicFrameClock();
+    property @Deprecated public static final androidx.compose.runtime.MonotonicFrameClock DefaultMonotonicFrameClock;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface Applier<N> {
+    method public void clear();
+    method public void down(N node);
+    method public N getCurrent();
+    method public void insertBottomUp(int index, N instance);
+    method public void insertTopDown(int index, N instance);
+    method public void move(int from, int to, int count);
+    method public default void onBeginChanges();
+    method public default void onEndChanges();
+    method public void remove(int index, int count);
+    method public void up();
+    property public abstract N current;
+  }
+
+  public final class BroadcastFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
+    ctor public BroadcastFrameClock(optional kotlin.jvm.functions.Function0<kotlin.Unit>? onNewAwaiters);
+    method public void cancel(optional java.util.concurrent.CancellationException cancellationException);
+    method public boolean getHasAwaiters();
+    method public void sendFrame(long timeNanos);
+    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    property public final boolean hasAwaiters;
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface Composable {
+  }
+
+  @androidx.compose.runtime.InternalComposeApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ComposableInferredTarget {
+    method public abstract String scheme();
+    property public abstract String scheme;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface ComposableOpenTarget {
+    method public abstract int index();
+    property public abstract int index;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface ComposableTarget {
+    method public abstract String applier();
+    property public abstract String applier;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS) public @interface ComposableTargetMarker {
+    method public abstract String description() default "";
+    property public abstract String description;
+  }
+
+  public final class ComposablesKt {
+    method @androidx.compose.runtime.Composable public static inline <T extends java.lang.Object, reified E extends androidx.compose.runtime.Applier<?>> void ComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static inline <T extends java.lang.Object, reified E extends androidx.compose.runtime.Applier<?>> void ComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static inline <T, reified E extends androidx.compose.runtime.Applier<?>> void ComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.SkippableUpdater<T>,kotlin.Unit> skippableUpdate, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static inline <T extends java.lang.Object, reified E extends androidx.compose.runtime.Applier<?>> void ReusableComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static inline <T extends java.lang.Object, reified E extends androidx.compose.runtime.Applier<?>> void ReusableComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static inline <T, reified E extends androidx.compose.runtime.Applier<?>> void ReusableComposeNode(kotlin.jvm.functions.Function0<? extends T> factory, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> update, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.SkippableUpdater<T>,kotlin.Unit> skippableUpdate, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static inline void ReusableContent(Object? key, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static inline void ReusableContentHost(boolean active, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.runtime.Composer getCurrentComposer();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static int getCurrentCompositeKeyHash();
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionLocalContext getCurrentCompositionLocalContext();
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.runtime.RecomposeScope getCurrentRecomposeScope();
+    method @androidx.compose.runtime.Composable public static inline <T> T key(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> block);
+    method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, Object? key2, kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.Composable public static inline <T> T remember(Object? key1, kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.Composable public static inline <T> T remember(Object![]? keys, kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.Composable public static inline <T> T remember(kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.CompositionContext rememberCompositionContext();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static final androidx.compose.runtime.Composer currentComposer;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ExplicitGroupsComposable public static final int currentCompositeKeyHash;
+    property @androidx.compose.runtime.Composable public static final androidx.compose.runtime.CompositionLocalContext currentCompositionLocalContext;
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static final androidx.compose.runtime.RecomposeScope currentRecomposeScope;
+  }
+
+  @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.TYPEALIAS}) public @interface ComposeCompilerApi {
+  }
+
+  public interface ComposeNodeLifecycleCallback {
+    method public void onDeactivate();
+    method public void onRelease();
+    method public void onReuse();
+  }
+
+  public sealed interface Composer {
+    method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+    method @androidx.compose.runtime.InternalComposeApi public androidx.compose.runtime.CompositionContext buildContext();
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(byte value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(double value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(float value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(int value);
+    method @androidx.compose.runtime.ComposeCompilerApi public boolean changed(Object? value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(long value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(short value);
+    method @androidx.compose.runtime.ComposeCompilerApi public default boolean changedInstance(Object? value);
+    method public void collectParameterInformation();
+    method @androidx.compose.runtime.InternalComposeApi public <T> T consume(androidx.compose.runtime.CompositionLocal<T> key);
+    method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
+    method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
+    method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
+    method @org.jetbrains.annotations.TestOnly public void disableSourceInformation();
+    method @androidx.compose.runtime.ComposeCompilerApi public void enableReusing();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endNode();
+    method @androidx.compose.runtime.InternalComposeApi public void endProviders();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endReplaceableGroup();
+    method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.ScopeUpdateScope? endRestartGroup();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endReusableGroup();
+    method @androidx.compose.runtime.ComposeCompilerApi public void endToMarker(int marker);
+    method public androidx.compose.runtime.Applier<?> getApplier();
+    method @org.jetbrains.annotations.TestOnly public kotlin.coroutines.CoroutineContext getApplyCoroutineContext();
+    method @org.jetbrains.annotations.TestOnly public androidx.compose.runtime.ControlledComposition getComposition();
+    method public androidx.compose.runtime.tooling.CompositionData getCompositionData();
+    method public int getCompoundKeyHash();
+    method public androidx.compose.runtime.CompositionLocalMap getCurrentCompositionLocalMap();
+    method public int getCurrentMarker();
+    method public boolean getDefaultsInvalid();
+    method public boolean getInserting();
+    method public androidx.compose.runtime.RecomposeScope? getRecomposeScope();
+    method public Object? getRecomposeScopeIdentity();
+    method public boolean getSkipping();
+    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<?> value, Object? parameter);
+    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContentReferences(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
+    method @androidx.compose.runtime.ComposeCompilerApi public Object joinKey(Object? left, Object? right);
+    method @androidx.compose.runtime.InternalComposeApi public void recordSideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
+    method @androidx.compose.runtime.InternalComposeApi public void recordUsed(androidx.compose.runtime.RecomposeScope scope);
+    method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
+    method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
+    method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
+    method public void sourceInformation(String sourceInformation);
+    method public void sourceInformationMarkerEnd();
+    method public void sourceInformationMarkerStart(int key, String sourceInformation);
+    method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
+    method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
+    method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
+    method @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<?>![] values);
+    method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
+    method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
+    method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
+    method @androidx.compose.runtime.ComposeCompilerApi public void startReusableNode();
+    method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
+    method @androidx.compose.runtime.ComposeCompilerApi public void useNode();
+    property public abstract androidx.compose.runtime.Applier<?> applier;
+    property @androidx.compose.runtime.InternalComposeApi @org.jetbrains.annotations.TestOnly public abstract kotlin.coroutines.CoroutineContext applyCoroutineContext;
+    property @org.jetbrains.annotations.TestOnly public abstract androidx.compose.runtime.ControlledComposition composition;
+    property public abstract androidx.compose.runtime.tooling.CompositionData compositionData;
+    property public abstract int compoundKeyHash;
+    property public abstract androidx.compose.runtime.CompositionLocalMap currentCompositionLocalMap;
+    property public abstract int currentMarker;
+    property public abstract boolean defaultsInvalid;
+    property public abstract boolean inserting;
+    property public abstract androidx.compose.runtime.RecomposeScope? recomposeScope;
+    property public abstract Object? recomposeScopeIdentity;
+    property public abstract boolean skipping;
+    field public static final androidx.compose.runtime.Composer.Companion Companion;
+  }
+
+  public static final class Composer.Companion {
+    method public Object getEmpty();
+    method @androidx.compose.runtime.InternalComposeTracingApi public void setTracer(androidx.compose.runtime.CompositionTracer tracer);
+    property public final Object Empty;
+  }
+
+  public final class ComposerKt {
+    method @androidx.compose.runtime.ComposeCompilerApi public static inline <T> T cache(androidx.compose.runtime.Composer, boolean invalid, kotlin.jvm.functions.Function0<? extends T> block);
+    method @androidx.compose.runtime.ComposeCompilerApi public static boolean isTraceInProgress();
+    method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformation(androidx.compose.runtime.Composer composer, String sourceInformation);
+    method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerEnd(androidx.compose.runtime.Composer composer);
+    method @androidx.compose.runtime.ComposeCompilerApi public static void sourceInformationMarkerStart(androidx.compose.runtime.Composer composer, int key, String sourceInformation);
+    method @androidx.compose.runtime.ComposeCompilerApi public static void traceEventEnd();
+    method @androidx.compose.runtime.ComposeCompilerApi public static void traceEventStart(int key, int dirty1, int dirty2, String info);
+    method @Deprecated @androidx.compose.runtime.ComposeCompilerApi public static void traceEventStart(int key, String info);
+  }
+
+  public interface Composition {
+    method public void dispose();
+    method public boolean getHasInvalidations();
+    method public boolean isDisposed();
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    property public abstract boolean hasInvalidations;
+    property public abstract boolean isDisposed;
+  }
+
+  public abstract class CompositionContext {
+    method public abstract kotlin.coroutines.CoroutineContext getEffectCoroutineContext();
+    property public abstract kotlin.coroutines.CoroutineContext effectCoroutineContext;
+  }
+
+  public final class CompositionKt {
+    method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
+    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
+    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
+  }
+
+  @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final inline T getCurrent();
+    property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final inline T current;
+  }
+
+  @androidx.compose.runtime.Stable public final class CompositionLocalContext {
+  }
+
+  public final class CompositionLocalKt {
+    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.CompositionLocalContext context, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void CompositionLocalProvider(androidx.compose.runtime.ProvidedValue<?>![] values, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> compositionLocalOf(optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> defaultFactory);
+    method public static <T> androidx.compose.runtime.ProvidableCompositionLocal<T> staticCompositionLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
+  }
+
+  public sealed interface CompositionLocalMap {
+    method public operator <T> T get(androidx.compose.runtime.CompositionLocal<T> key);
+    field public static final androidx.compose.runtime.CompositionLocalMap.Companion Companion;
+  }
+
+  public static final class CompositionLocalMap.Companion {
+    method public androidx.compose.runtime.CompositionLocalMap getEmpty();
+    property public final androidx.compose.runtime.CompositionLocalMap Empty;
+  }
+
+  @androidx.compose.runtime.InternalComposeTracingApi public interface CompositionTracer {
+    method public boolean isTraceInProgress();
+    method public void traceEventEnd();
+    method public void traceEventStart(int key, int dirty1, int dirty2, String info);
+  }
+
+  public sealed interface ControlledComposition extends androidx.compose.runtime.Composition {
+    method public void applyChanges();
+    method public void applyLateChanges();
+    method public void changesApplied();
+    method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
+    method @androidx.compose.runtime.InternalComposeApi public void disposeUnusedMovableContent(androidx.compose.runtime.MovableContentState state);
+    method public boolean getHasPendingChanges();
+    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
+    method public void invalidateAll();
+    method public boolean isComposing();
+    method public boolean observesAnyOf(java.util.Set<?> values);
+    method public void prepareCompose(kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public boolean recompose();
+    method public void recordModificationsOf(java.util.Set<?> values);
+    method public void recordReadOf(Object value);
+    method public void recordWriteOf(Object value);
+    method @androidx.compose.runtime.InternalComposeApi public void verifyConsistent();
+    property public abstract boolean hasPendingChanges;
+    property public abstract boolean isComposing;
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.TYPE) public @interface DisallowComposableCalls {
+  }
+
+  public interface DisposableEffectResult {
+    method public void dispose();
+  }
+
+  public final class DisposableEffectScope {
+    ctor public DisposableEffectScope();
+    method public inline androidx.compose.runtime.DisposableEffectResult onDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDisposeEffect);
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface DoubleState extends androidx.compose.runtime.State<java.lang.Double> {
+    method public double getDoubleValue();
+    method public default Double getValue();
+    property public abstract double doubleValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
+  }
+
+  public final class EffectsKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void DisposableEffect(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.DisposableEffectScope,? extends androidx.compose.runtime.DisposableEffectResult> effect);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void DisposableEffect(Object? key1, Object? key2, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.DisposableEffectScope,? extends androidx.compose.runtime.DisposableEffectResult> effect);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void DisposableEffect(Object? key1, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.DisposableEffectScope,? extends androidx.compose.runtime.DisposableEffectResult> effect);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void DisposableEffect(Object![]? keys, kotlin.jvm.functions.Function1<? super androidx.compose.runtime.DisposableEffectScope,? extends androidx.compose.runtime.DisposableEffectResult> effect);
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void DisposableEffect(kotlin.jvm.functions.Function1<? super androidx.compose.runtime.DisposableEffectScope,? extends androidx.compose.runtime.DisposableEffectResult> effect);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void LaunchedEffect(Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void LaunchedEffect(Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void LaunchedEffect(Object? key1, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void LaunchedEffect(Object![]? keys, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated @androidx.compose.runtime.Composable public static void LaunchedEffect(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable public static void SideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
+    method @androidx.compose.runtime.Composable public static inline kotlinx.coroutines.CoroutineScope rememberCoroutineScope(optional kotlin.jvm.functions.Function0<? extends kotlin.coroutines.CoroutineContext> getContext);
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API for Compose and is likely to change before becoming " + "stable.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalComposeApi {
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExplicitGroupsComposable {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface FloatState extends androidx.compose.runtime.State<java.lang.Float> {
+    method public float getFloatValue();
+    method public default Float getValue();
+    property public abstract float floatValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
+  }
+
+  @androidx.compose.runtime.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface Immutable {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface IntState extends androidx.compose.runtime.State<java.lang.Integer> {
+    method public int getIntValue();
+    method public default Integer getValue();
+    property public abstract int intValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API for Compose modules that may change frequently " + "and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalComposeApi {
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeTracingApi {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LongState extends androidx.compose.runtime.State<java.lang.Long> {
+    method public long getLongValue();
+    method public default Long getValue();
+    property public abstract long longValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface MonotonicFrameClock extends kotlin.coroutines.CoroutineContext.Element {
+    method public default kotlin.coroutines.CoroutineContext.Key<?> getKey();
+    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    property public default kotlin.coroutines.CoroutineContext.Key<?> key;
+    field public static final androidx.compose.runtime.MonotonicFrameClock.Key Key;
+  }
+
+  public static final class MonotonicFrameClock.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.runtime.MonotonicFrameClock> {
+  }
+
+  public final class MonotonicFrameClockKt {
+    method public static androidx.compose.runtime.MonotonicFrameClock getMonotonicFrameClock(kotlin.coroutines.CoroutineContext);
+    method public static suspend inline <R> Object? withFrameMillis(androidx.compose.runtime.MonotonicFrameClock, kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend <R> Object? withFrameMillis(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+  }
+
+  @androidx.compose.runtime.InternalComposeApi public final class MovableContent<P> {
+    ctor public MovableContent(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
+    method public kotlin.jvm.functions.Function1<P,kotlin.Unit> getContent();
+    property public final kotlin.jvm.functions.Function1<P,kotlin.Unit> content;
+  }
+
+  public final class MovableContentKt {
+    method public static kotlin.jvm.functions.Function0<kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static <P> kotlin.jvm.functions.Function1<P,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
+    method public static <P1, P2> kotlin.jvm.functions.Function2<P1,P2,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function2<? super P1,? super P2,kotlin.Unit> content);
+    method public static <P1, P2, P3> kotlin.jvm.functions.Function3<P1,P2,P3,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function3<? super P1,? super P2,? super P3,kotlin.Unit> content);
+    method public static <P1, P2, P3, P4> kotlin.jvm.functions.Function4<P1,P2,P3,P4,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function4<? super P1,? super P2,? super P3,? super P4,kotlin.Unit> content);
+    method public static <R> kotlin.jvm.functions.Function1<R,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function1<? super R,kotlin.Unit> content);
+    method public static <R, P> kotlin.jvm.functions.Function2<R,P,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function2<? super R,? super P,kotlin.Unit> content);
+    method public static <R, P1, P2> kotlin.jvm.functions.Function3<R,P1,P2,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function3<? super R,? super P1,? super P2,kotlin.Unit> content);
+    method public static <R, P1, P2, P3> kotlin.jvm.functions.Function4<R,P1,P2,P3,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function4<? super R,? super P1,? super P2,? super P3,kotlin.Unit> content);
+  }
+
+  @androidx.compose.runtime.InternalComposeApi public final class MovableContentState {
+  }
+
+  @androidx.compose.runtime.InternalComposeApi public final class MovableContentStateReference {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableDoubleState extends androidx.compose.runtime.DoubleState androidx.compose.runtime.MutableState<java.lang.Double> {
+    method public void setDoubleValue(double);
+    method public default void setValue(double);
+    property public abstract double doubleValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="doubleValue") public default Double value;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableFloatState extends androidx.compose.runtime.FloatState androidx.compose.runtime.MutableState<java.lang.Float> {
+    method public void setFloatValue(float);
+    method public default void setValue(float);
+    property public abstract float floatValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="floatValue") public default Float value;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableIntState extends androidx.compose.runtime.IntState androidx.compose.runtime.MutableState<java.lang.Integer> {
+    method public void setIntValue(int);
+    method public default void setValue(int);
+    property public abstract int intValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableLongState extends androidx.compose.runtime.LongState androidx.compose.runtime.MutableState<java.lang.Long> {
+    method public void setLongValue(long);
+    method public default void setValue(long);
+    property public abstract long longValue;
+    property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="longValue") public default Long value;
+  }
+
+  @androidx.compose.runtime.Stable public interface MutableState<T> extends androidx.compose.runtime.State<T> {
+    method public operator T component1();
+    method public operator kotlin.jvm.functions.Function1<T,kotlin.Unit> component2();
+    method public void setValue(T!);
+    property public abstract T value;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FILE}) public @interface NoLiveLiterals {
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface NonRestartableComposable {
+  }
+
+  public final class PausableMonotonicFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
+    ctor public PausableMonotonicFrameClock(androidx.compose.runtime.MonotonicFrameClock frameClock);
+    method public boolean isPaused();
+    method public void pause();
+    method public void resume();
+    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    property public final boolean isPaused;
+  }
+
+  public final class PrimitiveSnapshotStateKt {
+    method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<?> property);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<?> property, float value);
+  }
+
+  public interface ProduceStateScope<T> extends androidx.compose.runtime.MutableState<T> kotlinx.coroutines.CoroutineScope {
+    method public suspend Object? awaitDispose(kotlin.jvm.functions.Function0<kotlin.Unit> onDispose, kotlin.coroutines.Continuation<?>);
+  }
+
+  @androidx.compose.runtime.Stable public abstract class ProvidableCompositionLocal<T> extends androidx.compose.runtime.CompositionLocal<T> {
+    method public final infix androidx.compose.runtime.ProvidedValue<T> provides(T value);
+    method public final infix androidx.compose.runtime.ProvidedValue<T> providesDefault(T value);
+  }
+
+  public final class ProvidedValue<T> {
+    method public boolean getCanOverride();
+    method public androidx.compose.runtime.CompositionLocal<T> getCompositionLocal();
+    method public T getValue();
+    property public final boolean canOverride;
+    property public final androidx.compose.runtime.CompositionLocal<T> compositionLocal;
+    property public final T value;
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ReadOnlyComposable {
+  }
+
+  public interface RecomposeScope {
+    method public void invalidate();
+  }
+
+  public final class Recomposer extends androidx.compose.runtime.CompositionContext {
+    ctor public Recomposer(kotlin.coroutines.CoroutineContext effectCoroutineContext);
+    method public androidx.compose.runtime.RecomposerInfo asRecomposerInfo();
+    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public void cancel();
+    method public void close();
+    method public long getChangeCount();
+    method public kotlinx.coroutines.flow.StateFlow<androidx.compose.runtime.Recomposer.State> getCurrentState();
+    method public kotlin.coroutines.CoroutineContext getEffectCoroutineContext();
+    method public boolean getHasPendingWork();
+    method @Deprecated public kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> getState();
+    method public suspend Object? join(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public void pauseCompositionFrameClock();
+    method public void resumeCompositionFrameClock();
+    method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final long changeCount;
+    property public final kotlinx.coroutines.flow.StateFlow<androidx.compose.runtime.Recomposer.State> currentState;
+    property public kotlin.coroutines.CoroutineContext effectCoroutineContext;
+    property public final boolean hasPendingWork;
+    property @Deprecated public final kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> state;
+    field public static final androidx.compose.runtime.Recomposer.Companion Companion;
+  }
+
+  public static final class Recomposer.Companion {
+    method public kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.compose.runtime.RecomposerInfo>> getRunningRecomposers();
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.compose.runtime.RecomposerInfo>> runningRecomposers;
+  }
+
+  public enum Recomposer.State {
+    method public static androidx.compose.runtime.Recomposer.State valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.runtime.Recomposer.State[] values();
+    enum_constant public static final androidx.compose.runtime.Recomposer.State Idle;
+    enum_constant public static final androidx.compose.runtime.Recomposer.State Inactive;
+    enum_constant public static final androidx.compose.runtime.Recomposer.State InactivePendingWork;
+    enum_constant public static final androidx.compose.runtime.Recomposer.State PendingWork;
+    enum_constant public static final androidx.compose.runtime.Recomposer.State ShutDown;
+    enum_constant public static final androidx.compose.runtime.Recomposer.State ShuttingDown;
+  }
+
+  public interface RecomposerInfo {
+    method public long getChangeCount();
+    method public boolean getHasPendingWork();
+    method public kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> getState();
+    property public abstract long changeCount;
+    property public abstract boolean hasPendingWork;
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.compose.runtime.Recomposer.State> state;
+  }
+
+  public final class RecomposerKt {
+    method public static suspend <R> Object? withRunningRecomposer(kotlin.jvm.functions.Function3<? super kotlinx.coroutines.CoroutineScope,? super androidx.compose.runtime.Recomposer,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+  }
+
+  public interface RememberObserver {
+    method public void onAbandoned();
+    method public void onForgotten();
+    method public void onRemembered();
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi public interface ScopeUpdateScope {
+    method public void updateScope(kotlin.jvm.functions.Function2<? super androidx.compose.runtime.Composer,? super java.lang.Integer,kotlin.Unit> block);
+  }
+
+  @kotlin.jvm.JvmInline public final value class SkippableUpdater<T> {
+    ctor public SkippableUpdater(@kotlin.PublishedApi androidx.compose.runtime.Composer composer);
+    method public inline void update(kotlin.jvm.functions.Function1<? super androidx.compose.runtime.Updater<T>,kotlin.Unit> block);
+  }
+
+  public final class SnapshotDoubleStateKt {
+    method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property, double value);
+  }
+
+  public final class SnapshotIntStateKt {
+    method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<?> property);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<?> property, int value);
+  }
+
+  public final class SnapshotLongStateKt {
+    method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<?> property);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
+    method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<?> property, long value);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface SnapshotMutationPolicy<T> {
+    method public boolean equivalent(T a, T b);
+    method public default T? merge(T previous, T current, T applied);
+  }
+
+  public final class SnapshotStateExtensionsKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.runtime.DoubleState asDoubleState(androidx.compose.runtime.State<java.lang.Double>);
+    method @androidx.compose.runtime.Stable public static androidx.compose.runtime.FloatState asFloatState(androidx.compose.runtime.State<java.lang.Float>);
+    method @androidx.compose.runtime.Stable public static androidx.compose.runtime.IntState asIntState(androidx.compose.runtime.State<java.lang.Integer>);
+    method @androidx.compose.runtime.Stable public static androidx.compose.runtime.LongState asLongState(androidx.compose.runtime.State<java.lang.Long>);
+  }
+
+  public final class SnapshotStateKt {
+    method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
+    method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+    method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+    method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, Object? key3, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
+    method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> referentialEqualityPolicy();
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> rememberUpdatedState(T newValue);
+    method public static inline operator <T> void setValue(androidx.compose.runtime.MutableState<T>, Object? thisObj, kotlin.reflect.KProperty<?> property, T value);
+    method public static <T> kotlinx.coroutines.flow.Flow<T> snapshotFlow(kotlin.jvm.functions.Function0<? extends T> block);
+    method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> structuralEqualityPolicy();
+    method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> toMutableStateList(java.util.Collection<? extends T>);
+    method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> toMutableStateMap(Iterable<? extends kotlin.Pair<? extends K,? extends V>>);
+  }
+
+  @androidx.compose.runtime.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface Stable {
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public @interface StableMarker {
+  }
+
+  @androidx.compose.runtime.Stable public interface State<T> {
+    method public T getValue();
+    property public abstract T value;
+  }
+
+  @kotlin.jvm.JvmInline public final value class Updater<T> {
+    ctor public Updater(@kotlin.PublishedApi androidx.compose.runtime.Composer composer);
+    method public void init(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public void reconcile(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public inline void set(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
+    method public <V> void set(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+    method public inline void update(int value, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> block);
+    method public <V> void update(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
+  }
+
+}
+
+package androidx.compose.runtime.collection {
+
+  public final class MutableVector<T> implements java.util.RandomAccess {
+    method public void add(int index, T element);
+    method public boolean add(T element);
+    method public inline boolean addAll(androidx.compose.runtime.collection.MutableVector<T> elements);
+    method public boolean addAll(int index, androidx.compose.runtime.collection.MutableVector<T> elements);
+    method public boolean addAll(int index, java.util.Collection<? extends T> elements);
+    method public boolean addAll(int index, java.util.List<? extends T> elements);
+    method public boolean addAll(java.util.Collection<? extends T> elements);
+    method public inline boolean addAll(java.util.List<? extends T> elements);
+    method public boolean addAll(T![] elements);
+    method public inline boolean any(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public java.util.List<T> asMutableList();
+    method public void clear();
+    method public operator boolean contains(T element);
+    method public boolean containsAll(androidx.compose.runtime.collection.MutableVector<T> elements);
+    method public boolean containsAll(java.util.Collection<? extends T> elements);
+    method public boolean containsAll(java.util.List<? extends T> elements);
+    method public boolean contentEquals(androidx.compose.runtime.collection.MutableVector<T> other);
+    method public void ensureCapacity(int capacity);
+    method public T first();
+    method public inline T first(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public inline T? firstOrNull();
+    method public inline T? firstOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public inline <R> R fold(R initial, kotlin.jvm.functions.Function2<? super R,? super T,? extends R> operation);
+    method public inline <R> R foldIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super R,? super T,? extends R> operation);
+    method public inline <R> R foldRight(R initial, kotlin.jvm.functions.Function2<? super T,? super R,? extends R> operation);
+    method public inline <R> R foldRightIndexed(R initial, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super T,? super R,? extends R> operation);
+    method public inline void forEach(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public inline void forEachIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
+    method public inline void forEachReversed(kotlin.jvm.functions.Function1<? super T,kotlin.Unit> block);
+    method public inline void forEachReversedIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> block);
+    method public inline operator T get(int index);
+    method public inline kotlin.ranges.IntRange getIndices();
+    method public inline int getLastIndex();
+    method public int getSize();
+    method public int indexOf(T element);
+    method public inline int indexOfFirst(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public inline int indexOfLast(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public boolean isEmpty();
+    method public boolean isNotEmpty();
+    method public T last();
+    method public inline T last(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public int lastIndexOf(T element);
+    method public inline T? lastOrNull();
+    method public inline T? lastOrNull(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public inline <reified R> R![] map(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
+    method public inline <reified R> R![] mapIndexed(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
+    method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapIndexedNotNull(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,? extends R> transform);
+    method public inline <reified R> androidx.compose.runtime.collection.MutableVector<R> mapNotNull(kotlin.jvm.functions.Function1<? super T,? extends R> transform);
+    method public inline operator void minusAssign(T element);
+    method public inline operator void plusAssign(T element);
+    method public boolean remove(T element);
+    method public boolean removeAll(androidx.compose.runtime.collection.MutableVector<T> elements);
+    method public boolean removeAll(java.util.Collection<? extends T> elements);
+    method public boolean removeAll(java.util.List<? extends T> elements);
+    method public T removeAt(int index);
+    method public void removeRange(int start, int end);
+    method public boolean retainAll(java.util.Collection<? extends T> elements);
+    method public inline boolean reversedAny(kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public operator T set(int index, T element);
+    method public void sortWith(java.util.Comparator<T> comparator);
+    method public inline int sumBy(kotlin.jvm.functions.Function1<? super T,java.lang.Integer> selector);
+    property public final inline kotlin.ranges.IntRange indices;
+    property public final inline int lastIndex;
+    property public final int size;
+  }
+
+  public final class MutableVectorKt {
+    method public static inline <reified T> androidx.compose.runtime.collection.MutableVector<T> MutableVector(optional int capacity);
+    method public static inline <reified T> androidx.compose.runtime.collection.MutableVector<T> MutableVector(int size, kotlin.jvm.functions.Function1<? super java.lang.Integer,? extends T> init);
+    method public static inline <reified T> androidx.compose.runtime.collection.MutableVector<T> mutableVectorOf();
+    method public static inline <reified T> androidx.compose.runtime.collection.MutableVector<T> mutableVectorOf(T?... elements);
+  }
+
+}
+
+package androidx.compose.runtime.internal {
+
+  @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambda extends kotlin.jvm.functions.Function2<androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function10<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function11<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function13<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function14<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function15<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function16<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function17<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function18<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function19<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function20<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function21<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function3<java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function4<java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function5<java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function6<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function7<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function8<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> kotlin.jvm.functions.Function9<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,androidx.compose.runtime.Composer,java.lang.Integer,java.lang.Object> {
+  }
+
+  public final class ComposableLambdaKt {
+    method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambda(androidx.compose.runtime.Composer composer, int key, boolean tracked, Object block);
+    method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambda composableLambdaInstance(int key, boolean tracked, Object block);
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.Stable public interface ComposableLambdaN extends kotlin.jvm.functions.FunctionN<java.lang.Object> {
+  }
+
+  public final class ComposableLambdaN_jvmKt {
+    method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaN(androidx.compose.runtime.Composer composer, int key, boolean tracked, int arity, Object block);
+    method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
+  }
+
+  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface Decoy {
+    method public abstract String[] signature();
+    method public abstract String targetName();
+    property public abstract String[] signature;
+    property public abstract String targetName;
+  }
+
+  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface DecoyImplementation {
+    method public abstract long id();
+    method public abstract String name();
+    property public abstract long id;
+    property public abstract String name;
+  }
+
+  public final class DecoyKt {
+    method @androidx.compose.runtime.ComposeCompilerApi public static Void illegalDecoyCallException(String fName);
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface FunctionKeyMeta {
+    method public abstract int endOffset();
+    method public abstract int key();
+    method public abstract int startOffset();
+    property public abstract int endOffset;
+    property public abstract int key;
+    property public abstract int startOffset;
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public static @interface FunctionKeyMeta.Container {
+    method public abstract androidx.compose.runtime.internal.FunctionKeyMeta[] value();
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface FunctionKeyMetaClass {
+    method public abstract String file();
+    property public abstract String file;
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface LiveLiteralFileInfo {
+    method public abstract String file();
+    property public abstract String file;
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface LiveLiteralInfo {
+    method public abstract String key();
+    method public abstract int offset();
+    property public abstract String key;
+    property public abstract int offset;
+  }
+
+  public final class LiveLiteralKt {
+    method @androidx.compose.runtime.InternalComposeApi public static void enableLiveLiterals();
+    method public static boolean isLiveLiteralsEnabled();
+    method @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.InternalComposeApi public static <T> androidx.compose.runtime.State<T> liveLiteral(String key, T value);
+    method @androidx.compose.runtime.InternalComposeApi public static void updateLiveLiteralValue(String key, Object? value);
+    property public static final boolean isLiveLiteralsEnabled;
+  }
+
+  @androidx.compose.runtime.ComposeCompilerApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.CLASS) public @interface StabilityInferred {
+    method public abstract int parameters();
+    property public abstract int parameters;
+  }
+
+}
+
+package androidx.compose.runtime.reflect {
+
+  public final class ComposableMethod {
+    method public java.lang.reflect.Method asMethod();
+    method public int getParameterCount();
+    method public Class<?>![] getParameterTypes();
+    method public java.lang.reflect.Parameter![] getParameters();
+    method public operator Object? invoke(androidx.compose.runtime.Composer composer, Object? instance, java.lang.Object?... args);
+    property public final int parameterCount;
+    property public final Class<?>![] parameterTypes;
+    property public final java.lang.reflect.Parameter![] parameters;
+  }
+
+  public final class ComposableMethodKt {
+    method public static androidx.compose.runtime.reflect.ComposableMethod? asComposableMethod(java.lang.reflect.Method);
+    method @kotlin.jvm.Throws(exceptionClasses=NoSuchMethodException::class) public static androidx.compose.runtime.reflect.ComposableMethod getDeclaredComposableMethod(Class<?>, String methodName, Class<?>... args) throws java.lang.NoSuchMethodException;
+  }
+
+}
+
+package androidx.compose.runtime.snapshots {
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.PROPERTY) public @interface AutoboxingStateValueProperty {
+    method public abstract String preferredPropertyName();
+    property public abstract String preferredPropertyName;
+  }
+
+  public class MutableSnapshot extends androidx.compose.runtime.snapshots.Snapshot {
+    method public androidx.compose.runtime.snapshots.SnapshotApplyResult apply();
+    method public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? getReadObserver();
+    method public boolean getReadOnly();
+    method public androidx.compose.runtime.snapshots.Snapshot getRoot();
+    method public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? getWriteObserver();
+    method public boolean hasPendingChanges();
+    method public androidx.compose.runtime.snapshots.MutableSnapshot takeNestedMutableSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver);
+    method public androidx.compose.runtime.snapshots.Snapshot takeNestedSnapshot(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
+    property public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver;
+    property public boolean readOnly;
+    property public androidx.compose.runtime.snapshots.Snapshot root;
+    property public kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver;
+  }
+
+  public fun interface ObserverHandle {
+    method public void dispose();
+  }
+
+  public abstract sealed class Snapshot {
+    method public void dispose();
+    method public final inline <T> T enter(kotlin.jvm.functions.Function0<? extends T> block);
+    method public int getId();
+    method public abstract boolean getReadOnly();
+    method public abstract androidx.compose.runtime.snapshots.Snapshot getRoot();
+    method public abstract boolean hasPendingChanges();
+    method public abstract androidx.compose.runtime.snapshots.Snapshot takeNestedSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
+    method @androidx.compose.runtime.ExperimentalComposeApi public final androidx.compose.runtime.snapshots.Snapshot? unsafeEnter();
+    method @androidx.compose.runtime.ExperimentalComposeApi public final void unsafeLeave(androidx.compose.runtime.snapshots.Snapshot? oldSnapshot);
+    property public int id;
+    property public abstract boolean readOnly;
+    property public abstract androidx.compose.runtime.snapshots.Snapshot root;
+    field public static final androidx.compose.runtime.snapshots.Snapshot.Companion Companion;
+  }
+
+  public static final class Snapshot.Companion {
+    method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
+    method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
+    method public boolean isApplyObserverNotificationPending();
+    method public void notifyObjectsInitialized();
+    method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
+    method @androidx.compose.runtime.InternalComposeApi public int openSnapshotCount();
+    method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
+    method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
+    method public void sendApplyNotifications();
+    method public androidx.compose.runtime.snapshots.MutableSnapshot takeMutableSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver);
+    method public androidx.compose.runtime.snapshots.Snapshot takeSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
+    method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
+    method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
+    property public final androidx.compose.runtime.snapshots.Snapshot current;
+    property public final boolean isApplyObserverNotificationPending;
+  }
+
+  public final class SnapshotApplyConflictException extends java.lang.Exception {
+    ctor public SnapshotApplyConflictException(androidx.compose.runtime.snapshots.Snapshot snapshot);
+    method public androidx.compose.runtime.snapshots.Snapshot getSnapshot();
+    property public final androidx.compose.runtime.snapshots.Snapshot snapshot;
+  }
+
+  public abstract sealed class SnapshotApplyResult {
+    method public abstract void check();
+    method public abstract boolean getSucceeded();
+    property public abstract boolean succeeded;
+  }
+
+  public static final class SnapshotApplyResult.Failure extends androidx.compose.runtime.snapshots.SnapshotApplyResult {
+    ctor public SnapshotApplyResult.Failure(androidx.compose.runtime.snapshots.Snapshot snapshot);
+    method public void check();
+    method public androidx.compose.runtime.snapshots.Snapshot getSnapshot();
+    method public boolean getSucceeded();
+    property public final androidx.compose.runtime.snapshots.Snapshot snapshot;
+    property public boolean succeeded;
+  }
+
+  public static final class SnapshotApplyResult.Success extends androidx.compose.runtime.snapshots.SnapshotApplyResult {
+    method public void check();
+    method public boolean getSucceeded();
+    property public boolean succeeded;
+    field public static final androidx.compose.runtime.snapshots.SnapshotApplyResult.Success INSTANCE;
+  }
+
+  @androidx.compose.runtime.ExperimentalComposeApi public interface SnapshotContextElement extends kotlin.coroutines.CoroutineContext.Element {
+    field public static final androidx.compose.runtime.snapshots.SnapshotContextElement.Key Key;
+  }
+
+  public static final class SnapshotContextElement.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.runtime.snapshots.SnapshotContextElement> {
+  }
+
+  public final class SnapshotContextElementKt {
+    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.snapshots.SnapshotContextElement asContextElement(androidx.compose.runtime.snapshots.Snapshot);
+  }
+
+  public final class SnapshotKt {
+    method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state);
+    method public static <T extends androidx.compose.runtime.snapshots.StateRecord> T readable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot);
+    method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R withCurrent(T, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+    method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, androidx.compose.runtime.snapshots.Snapshot snapshot, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+    method public static inline <T extends androidx.compose.runtime.snapshots.StateRecord, R> R writable(T, androidx.compose.runtime.snapshots.StateObject state, kotlin.jvm.functions.Function1<? super T,? extends R> block);
+  }
+
+  public interface SnapshotMutableState<T> extends androidx.compose.runtime.MutableState<T> {
+    method public androidx.compose.runtime.SnapshotMutationPolicy<T> getPolicy();
+    property public abstract androidx.compose.runtime.SnapshotMutationPolicy<T> policy;
+  }
+
+  @androidx.compose.runtime.Stable public final class SnapshotStateList<T> implements kotlin.jvm.internal.markers.KMutableList java.util.List<T> androidx.compose.runtime.snapshots.StateObject {
+    ctor public SnapshotStateList();
+    method public void add(int index, T element);
+    method public boolean add(T element);
+    method public boolean addAll(int index, java.util.Collection<? extends T> elements);
+    method public boolean addAll(java.util.Collection<? extends T> elements);
+    method public void clear();
+    method public boolean contains(T element);
+    method public boolean containsAll(java.util.Collection<E!> elements);
+    method public T get(int index);
+    method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
+    method public int getSize();
+    method public int indexOf(T element);
+    method public boolean isEmpty();
+    method public java.util.Iterator<T> iterator();
+    method public int lastIndexOf(T element);
+    method public java.util.ListIterator<T> listIterator();
+    method public java.util.ListIterator<T> listIterator(int index);
+    method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
+    method public boolean remove(T element);
+    method public boolean removeAll(java.util.Collection<E!> elements);
+    method public T removeAt(int index);
+    method public void removeRange(int fromIndex, int toIndex);
+    method public boolean retainAll(java.util.Collection<E!> elements);
+    method public T set(int index, T element);
+    method public java.util.List<T> subList(int fromIndex, int toIndex);
+    method public java.util.List<T> toList();
+    property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
+    property public int size;
+  }
+
+  @androidx.compose.runtime.Stable public final class SnapshotStateMap<K, V> implements kotlin.jvm.internal.markers.KMutableMap java.util.Map<K,V> androidx.compose.runtime.snapshots.StateObject {
+    ctor public SnapshotStateMap();
+    method public void clear();
+    method public boolean containsKey(K key);
+    method public boolean containsValue(V value);
+    method public V? get(Object key);
+    method public java.util.Set<java.util.Map.Entry<K,V>> getEntries();
+    method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
+    method public java.util.Set<K> getKeys();
+    method public int getSize();
+    method public java.util.Collection<V> getValues();
+    method public boolean isEmpty();
+    method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
+    method public V? put(K key, V value);
+    method public void putAll(java.util.Map<? extends K,? extends V> from);
+    method public V? remove(Object key);
+    method public java.util.Map<K,V> toMap();
+    property public java.util.Set<java.util.Map.Entry<K,V>> entries;
+    property public androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
+    property public java.util.Set<K> keys;
+    property public int size;
+    property public java.util.Collection<V> values;
+  }
+
+  public final class SnapshotStateObserver {
+    ctor public SnapshotStateObserver(kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> onChangedExecutor);
+    method public void clear();
+    method public void clear(Object scope);
+    method public void clearIf(kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Boolean> predicate);
+    method @org.jetbrains.annotations.TestOnly public void notifyChanges(java.util.Set<?> changes, androidx.compose.runtime.snapshots.Snapshot snapshot);
+    method public <T> void observeReads(T scope, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onValueChangedForScope, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public void start();
+    method public void stop();
+    method @Deprecated public void withNoObservations(kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface StateFactoryMarker {
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface StateObject {
+    method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
+    method public default androidx.compose.runtime.snapshots.StateRecord? mergeRecords(androidx.compose.runtime.snapshots.StateRecord previous, androidx.compose.runtime.snapshots.StateRecord current, androidx.compose.runtime.snapshots.StateRecord applied);
+    method public void prependStateRecord(androidx.compose.runtime.snapshots.StateRecord value);
+    property public abstract androidx.compose.runtime.snapshots.StateRecord firstStateRecord;
+  }
+
+  public abstract class StateRecord {
+    ctor public StateRecord();
+    method public abstract void assign(androidx.compose.runtime.snapshots.StateRecord value);
+    method public abstract androidx.compose.runtime.snapshots.StateRecord create();
+  }
+
+}
+
+package androidx.compose.runtime.tooling {
+
+  public interface CompositionData {
+    method public default androidx.compose.runtime.tooling.CompositionGroup? find(Object identityToFind);
+    method public Iterable<androidx.compose.runtime.tooling.CompositionGroup> getCompositionGroups();
+    method public boolean isEmpty();
+    property public abstract Iterable<androidx.compose.runtime.tooling.CompositionGroup> compositionGroups;
+    property public abstract boolean isEmpty;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface CompositionGroup extends androidx.compose.runtime.tooling.CompositionData {
+    method public Iterable<java.lang.Object> getData();
+    method public default int getGroupSize();
+    method public default Object? getIdentity();
+    method public Object getKey();
+    method public Object? getNode();
+    method public default int getSlotsSize();
+    method public String? getSourceInfo();
+    property public abstract Iterable<java.lang.Object> data;
+    property public default int groupSize;
+    property public default Object? identity;
+    property public abstract Object key;
+    property public abstract Object? node;
+    property public default int slotsSize;
+    property public abstract String? sourceInfo;
+  }
+
+  public final class InspectionTablesKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.util.Set<androidx.compose.runtime.tooling.CompositionData>> getLocalInspectionTables();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.util.Set<androidx.compose.runtime.tooling.CompositionData>> LocalInspectionTables;
+  }
+
+}
+
diff --git a/compose/runtime/runtime/api/restricted_1.5.0-beta01.txt b/compose/runtime/runtime/api/restricted_1.5.0-beta01.txt
index 6cfdfcb..fd14be5 100644
--- a/compose/runtime/runtime/api/restricted_1.5.0-beta01.txt
+++ b/compose/runtime/runtime/api/restricted_1.5.0-beta01.txt
@@ -51,11 +51,6 @@
   @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface Composable {
   }
 
-  @androidx.compose.runtime.InternalComposeApi @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ComposableInferredTarget {
-    method public abstract String scheme();
-    property public abstract String scheme;
-  }
-
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface ComposableOpenTarget {
     method public abstract int index();
     property public abstract int index;
@@ -109,7 +104,6 @@
 
   public sealed interface Composer {
     method @androidx.compose.runtime.ComposeCompilerApi public <V, T> void apply(V value, kotlin.jvm.functions.Function2<? super T,? super V,kotlin.Unit> block);
-    method @androidx.compose.runtime.InternalComposeApi public androidx.compose.runtime.CompositionContext buildContext();
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(boolean value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(byte value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(char value);
@@ -121,7 +115,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changed(short value);
     method @androidx.compose.runtime.ComposeCompilerApi public default boolean changedInstance(Object? value);
     method public void collectParameterInformation();
-    method @androidx.compose.runtime.InternalComposeApi public <T> T consume(androidx.compose.runtime.CompositionLocal<T> key);
     method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
     method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
     method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
@@ -130,7 +123,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endNode();
-    method @androidx.compose.runtime.InternalComposeApi public void endProviders();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReplaceableGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.ScopeUpdateScope? endRestartGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void endReusableGroup();
@@ -147,11 +139,7 @@
     method public androidx.compose.runtime.RecomposeScope? getRecomposeScope();
     method public Object? getRecomposeScopeIdentity();
     method public boolean getSkipping();
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(androidx.compose.runtime.MovableContent<?> value, Object? parameter);
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContentReferences(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
     method @androidx.compose.runtime.ComposeCompilerApi public Object joinKey(Object? left, Object? right);
-    method @androidx.compose.runtime.InternalComposeApi public void recordSideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
-    method @androidx.compose.runtime.InternalComposeApi public void recordUsed(androidx.compose.runtime.RecomposeScope scope);
     method @androidx.compose.runtime.ComposeCompilerApi public Object? rememberedValue();
     method @androidx.compose.runtime.ComposeCompilerApi public void skipCurrentGroup();
     method @androidx.compose.runtime.ComposeCompilerApi public void skipToGroupEnd();
@@ -161,7 +149,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void startDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void startMovableGroup(int key, Object? dataKey);
     method @androidx.compose.runtime.ComposeCompilerApi public void startNode();
-    method @androidx.compose.runtime.InternalComposeApi public void startProviders(androidx.compose.runtime.ProvidedValue<?>![] values);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReplaceableGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public androidx.compose.runtime.Composer startRestartGroup(int key);
     method @androidx.compose.runtime.ComposeCompilerApi public void startReusableGroup(int key, Object? dataKey);
@@ -169,7 +156,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public void updateRememberedValue(Object? value);
     method @androidx.compose.runtime.ComposeCompilerApi public void useNode();
     property public abstract androidx.compose.runtime.Applier<?> applier;
-    property @androidx.compose.runtime.InternalComposeApi @org.jetbrains.annotations.TestOnly public abstract kotlin.coroutines.CoroutineContext applyCoroutineContext;
     property @org.jetbrains.annotations.TestOnly public abstract androidx.compose.runtime.ControlledComposition composition;
     property public abstract androidx.compose.runtime.tooling.CompositionData compositionData;
     property public abstract int compoundKeyHash;
@@ -185,7 +171,6 @@
 
   public static final class Composer.Companion {
     method public Object getEmpty();
-    method @androidx.compose.runtime.InternalComposeTracingApi public void setTracer(androidx.compose.runtime.CompositionTracer tracer);
     property public final Object Empty;
   }
 
@@ -229,10 +214,7 @@
 
   public final class CompositionKt {
     method public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
-    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.Composition Composition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
     method @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent);
-    method @androidx.compose.runtime.ExperimentalComposeApi @org.jetbrains.annotations.TestOnly public static androidx.compose.runtime.ControlledComposition ControlledComposition(androidx.compose.runtime.Applier<?> applier, androidx.compose.runtime.CompositionContext parent, kotlin.coroutines.CoroutineContext recomposeCoroutineContext);
-    method @androidx.compose.runtime.ExperimentalComposeApi public static kotlin.coroutines.CoroutineContext getRecomposeCoroutineContext(androidx.compose.runtime.ControlledComposition);
   }
 
   @androidx.compose.runtime.Stable public abstract sealed class CompositionLocal<T> {
@@ -269,21 +251,13 @@
     property public final kotlinx.coroutines.CoroutineScope coroutineScope;
   }
 
-  @androidx.compose.runtime.InternalComposeTracingApi public interface CompositionTracer {
-    method public boolean isTraceInProgress();
-    method public void traceEventEnd();
-    method public void traceEventStart(int key, int dirty1, int dirty2, String info);
-  }
-
   public sealed interface ControlledComposition extends androidx.compose.runtime.Composition {
     method public void applyChanges();
     method public void applyLateChanges();
     method public void changesApplied();
     method public void composeContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public <R> R delegateInvalidations(androidx.compose.runtime.ControlledComposition? to, int groupIndex, kotlin.jvm.functions.Function0<? extends R> block);
-    method @androidx.compose.runtime.InternalComposeApi public void disposeUnusedMovableContent(androidx.compose.runtime.MovableContentState state);
     method public boolean getHasPendingChanges();
-    method @androidx.compose.runtime.InternalComposeApi public void insertMovableContent(java.util.List<kotlin.Pair<androidx.compose.runtime.MovableContentStateReference,androidx.compose.runtime.MovableContentStateReference>> references);
     method public void invalidateAll();
     method public boolean isComposing();
     method public boolean observesAnyOf(java.util.Set<?> values);
@@ -292,7 +266,6 @@
     method public void recordModificationsOf(java.util.Set<?> values);
     method public void recordReadOf(Object value);
     method public void recordWriteOf(Object value);
-    method @androidx.compose.runtime.InternalComposeApi public void verifyConsistent();
     property public abstract boolean hasPendingChanges;
     property public abstract boolean isComposing;
   }
@@ -336,9 +309,6 @@
     method @kotlin.PublishedApi internal static inline <R> R synchronized(Object lock, kotlin.jvm.functions.Function0<? extends R> block);
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is an experimental API for Compose and is likely to change before becoming " + "stable.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExperimentalComposeApi {
-  }
-
   @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER}) public @interface ExplicitGroupsComposable {
   }
 
@@ -359,12 +329,6 @@
     property @androidx.compose.runtime.snapshots.AutoboxingStateValueProperty(preferredPropertyName="intValue") public default Integer value;
   }
 
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API for Compose modules that may change frequently " + "and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalComposeApi {
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeTracingApi {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface LongState extends androidx.compose.runtime.State<java.lang.Long> {
     method public long getLongValue();
     method public default Long getValue();
@@ -389,12 +353,6 @@
     method public static suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
   }
 
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContent<P> {
-    ctor public MovableContent(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
-    method public kotlin.jvm.functions.Function1<P,kotlin.Unit> getContent();
-    property public final kotlin.jvm.functions.Function1<P,kotlin.Unit> content;
-  }
-
   public final class MovableContentKt {
     method public static kotlin.jvm.functions.Function0<kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function0<kotlin.Unit> content);
     method public static <P> kotlin.jvm.functions.Function1<P,kotlin.Unit> movableContentOf(kotlin.jvm.functions.Function1<? super P,kotlin.Unit> content);
@@ -407,12 +365,6 @@
     method public static <R, P1, P2, P3> kotlin.jvm.functions.Function4<R,P1,P2,P3,kotlin.Unit> movableContentWithReceiverOf(kotlin.jvm.functions.Function4<? super R,? super P1,? super P2,? super P3,kotlin.Unit> content);
   }
 
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContentState {
-  }
-
-  @androidx.compose.runtime.InternalComposeApi public final class MovableContentStateReference {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface MutableDoubleState extends androidx.compose.runtime.DoubleState androidx.compose.runtime.MutableState<java.lang.Double> {
     method public void setDoubleValue(double);
     method public default void setValue(double);
@@ -513,7 +465,6 @@
     method public void pauseCompositionFrameClock();
     method public void resumeCompositionFrameClock();
     method public suspend Object? runRecomposeAndApplyChanges(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method @androidx.compose.runtime.ExperimentalComposeApi public suspend Object? runRecomposeConcurrentlyAndApplyChanges(kotlin.coroutines.CoroutineContext recomposeCoroutineContext, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     property public final long changeCount;
     property public final kotlinx.coroutines.flow.StateFlow<androidx.compose.runtime.Recomposer.State> currentState;
     property public kotlin.coroutines.CoroutineContext effectCoroutineContext;
@@ -743,20 +694,6 @@
     method @androidx.compose.runtime.ComposeCompilerApi public static androidx.compose.runtime.internal.ComposableLambdaN composableLambdaNInstance(int key, boolean tracked, int arity, Object block);
   }
 
-  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface Decoy {
-    method public abstract String[] signature();
-    method public abstract String targetName();
-    property public abstract String[] signature;
-    property public abstract String targetName;
-  }
-
-  @androidx.compose.runtime.ExperimentalComposeApi @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.CONSTRUCTOR}) public @interface DecoyImplementation {
-    method public abstract long id();
-    method public abstract String name();
-    property public abstract long id;
-    property public abstract String name;
-  }
-
   public final class DecoyKt {
     method @androidx.compose.runtime.ComposeCompilerApi public static Void illegalDecoyCallException(String fName);
   }
@@ -792,10 +729,7 @@
   }
 
   public final class LiveLiteralKt {
-    method @androidx.compose.runtime.InternalComposeApi public static void enableLiveLiterals();
     method public static boolean isLiveLiteralsEnabled();
-    method @androidx.compose.runtime.ComposeCompilerApi @androidx.compose.runtime.InternalComposeApi public static <T> androidx.compose.runtime.State<T> liveLiteral(String key, T value);
-    method @androidx.compose.runtime.InternalComposeApi public static void updateLiveLiteralValue(String key, Object? value);
     property public static final boolean isLiveLiteralsEnabled;
   }
 
@@ -862,8 +796,6 @@
     method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot? makeCurrent();
     method @kotlin.PublishedApi internal void restoreCurrent(androidx.compose.runtime.snapshots.Snapshot? snapshot);
     method public abstract androidx.compose.runtime.snapshots.Snapshot takeNestedSnapshot(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver);
-    method @androidx.compose.runtime.ExperimentalComposeApi public final androidx.compose.runtime.snapshots.Snapshot? unsafeEnter();
-    method @androidx.compose.runtime.ExperimentalComposeApi public final void unsafeLeave(androidx.compose.runtime.snapshots.Snapshot? oldSnapshot);
     property public int id;
     property public abstract boolean readOnly;
     property public abstract androidx.compose.runtime.snapshots.Snapshot root;
@@ -877,7 +809,6 @@
     method public boolean isApplyObserverNotificationPending();
     method public void notifyObjectsInitialized();
     method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
-    method @androidx.compose.runtime.InternalComposeApi public int openSnapshotCount();
     method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
     method public androidx.compose.runtime.snapshots.ObserverHandle registerGlobalWriteObserver(kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit> observer);
     method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot? removeCurrent();
@@ -919,17 +850,6 @@
     field public static final androidx.compose.runtime.snapshots.SnapshotApplyResult.Success INSTANCE;
   }
 
-  @androidx.compose.runtime.ExperimentalComposeApi public interface SnapshotContextElement extends kotlin.coroutines.CoroutineContext.Element {
-    field public static final androidx.compose.runtime.snapshots.SnapshotContextElement.Key Key;
-  }
-
-  public static final class SnapshotContextElement.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.runtime.snapshots.SnapshotContextElement> {
-  }
-
-  public final class SnapshotContextElementKt {
-    method @androidx.compose.runtime.ExperimentalComposeApi public static androidx.compose.runtime.snapshots.SnapshotContextElement asContextElement(androidx.compose.runtime.snapshots.Snapshot);
-  }
-
   public final class SnapshotKt {
     method @kotlin.PublishedApi internal static <T extends androidx.compose.runtime.snapshots.StateRecord> T current(T r);
     method @kotlin.PublishedApi internal static <T extends androidx.compose.runtime.snapshots.StateRecord> T current(T r, androidx.compose.runtime.snapshots.Snapshot snapshot);
diff --git a/compose/runtime/runtime/build.gradle b/compose/runtime/runtime/build.gradle
index 851abc9a..e5aab05 100644
--- a/compose/runtime/runtime/build.gradle
+++ b/compose/runtime/runtime/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/runtime/runtime/lint-baseline.xml b/compose/runtime/runtime/lint-baseline.xml
index 2777e16..6e1428d 100644
--- a/compose/runtime/runtime/lint-baseline.xml
+++ b/compose/runtime/runtime/lint-baseline.xml
@@ -1,14 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="                Thread.sleep(0)"
-        errorLine2="                       ~~~~~">
-        <location
-            file="src/jvmTest/kotlin/androidx/compose/runtime/snapshots/SnapshotTestsJvm.kt"/>
-    </issue>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="ExperimentalPropertyAnnotation"
@@ -28,4 +19,130 @@
             file="src/commonMain/kotlin/androidx/compose/runtime/internal/LiveLiteral.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;realFn&apos; with type Function2&lt;? super Composer, ? super Integer, ? extends Unit>."
+        errorLine1="    @Suppress(&quot;UNCHECKED_CAST&quot;)"
+        errorLine2="    ^">
+        <location
+            file="src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;realFn&apos; with type Function2&lt;? super Composer, ? super Integer, ? extends T>."
+        errorLine1="    @Suppress(&quot;UNCHECKED_CAST&quot;)"
+        errorLine2="    ^">
+        <location
+            file="src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor FrameAwaiter has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="    private class FrameAwaiter&lt;R>(val onFrame: (Long) -> R, val continuation: Continuation&lt;R>) {"
+        errorLine2="                                               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, R> of &apos;getOnFrame&apos;."
+        errorLine1="    private class FrameAwaiter&lt;R>(val onFrame: (Long) -> R, val continuation: Continuation&lt;R>) {"
+        errorLine2="                                               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method updateScope has parameter &apos;block&apos; with type Function2&lt;? super Composer, ? super Integer, Unit>."
+        errorLine1="    fun updateScope(block: (Composer, Int) -> Unit)"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/Composer.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method set has parameter &apos;block&apos; with type Function2&lt;? super T, ? super Integer, Unit>."
+        errorLine1="        noinline block: T.(value: Int) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/Composer.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method update has parameter &apos;block&apos; with type Function2&lt;? super T, ? super Integer, Unit>."
+        errorLine1="        noinline block: T.(value: Int) -> Unit"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/Composer.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method withFrameNanos has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="    suspend fun &lt;R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method withFrameNanos has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="suspend fun &lt;R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R ="
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method withFrameMillis has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="suspend fun &lt;R> withFrameMillis(onFrame: (frameTimeMillis: Long) -> R): R ="
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method MutableVector has parameter &apos;init&apos; with type Function1&lt;? super Integer, ? extends T>."
+        errorLine1="inline fun &lt;reified T> MutableVector(size: Int, noinline init: (Int) -> T): MutableVector&lt;T> {"
+        errorLine2="                                                               ~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/collection/MutableVector.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method forEachData$lint_module has parameter &apos;block&apos; with type Function2&lt;? super Integer, Object, Unit>."
+        errorLine1="    internal fun forEachData(group: Int, block: (index: Int, data: Any?) -> Unit) {"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method accept$lint_module has parameter &apos;visitor&apos; with type Function5&lt;? super TrieNode&lt;K, V>, ? super Integer, ? super Integer, ? super Integer, ? super Integer, Unit>."
+        errorLine1="    internal fun accept(visitor: (node: TrieNode&lt;K, V>, shift: Int, hash: Int, dataMap: Int, nodeMap: Int) -> Unit) {"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method accept has parameter &apos;visitor&apos; with type Function5&lt;? super TrieNode&lt;K, V>, ? super Integer, ? super Integer, ? super Integer, ? super Integer, Unit>."
+        errorLine1="            visitor: (node: TrieNode&lt;K, V>, shift: Int, hash: Int, dataMap: Int, nodeMap: Int) -> Unit,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/runtime/runtime/src/androidMain/kotlin/androidx/compose/runtime/ActualAndroid.android.kt b/compose/runtime/runtime/src/androidMain/kotlin/androidx/compose/runtime/ActualAndroid.android.kt
index 0c49967f..26a2698 100644
--- a/compose/runtime/runtime/src/androidMain/kotlin/androidx/compose/runtime/ActualAndroid.android.kt
+++ b/compose/runtime/runtime/src/androidMain/kotlin/androidx/compose/runtime/ActualAndroid.android.kt
@@ -47,10 +47,7 @@
 private object SdkStubsFallbackFrameClock : MonotonicFrameClock {
     private const val DefaultFrameDelay = 16L // milliseconds
 
-    override suspend fun <R> withFrameNanos(
-        @Suppress("PrimitiveInLambda")
-        onFrame: (frameTimeNanos: Long) -> R
-    ): R =
+    override suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R =
         withContext(Dispatchers.Main) {
             delay(DefaultFrameDelay)
             onFrame(System.nanoTime())
@@ -63,7 +60,6 @@
     }
 
     override suspend fun <R> withFrameNanos(
-        @Suppress("PrimitiveInLambda")
         onFrame: (frameTimeNanos: Long) -> R
     ): R = suspendCancellableCoroutine<R> { co ->
         val callback = Choreographer.FrameCallback { frameTimeNanos ->
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
index f93a372..1718d92 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
@@ -37,11 +37,7 @@
     private val onNewAwaiters: (() -> Unit)? = null
 ) : MonotonicFrameClock {
 
-    private class FrameAwaiter<R>(
-        @Suppress("PrimitiveInLambda")
-        val onFrame: (Long) -> R,
-        val continuation: Continuation<R>
-    ) {
+    private class FrameAwaiter<R>(val onFrame: (Long) -> R, val continuation: Continuation<R>) {
         fun resume(timeNanos: Long) {
             continuation.resumeWith(runCatching { onFrame(timeNanos) })
         }
@@ -79,7 +75,6 @@
     }
 
     override suspend fun <R> withFrameNanos(
-        @Suppress("PrimitiveInLambda")
         onFrame: (Long) -> R
     ): R = suspendCancellableCoroutine { co ->
         lateinit var awaiter: FrameAwaiter<R>
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index fca7293..9445e5b6 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -248,7 +248,7 @@
      * recompose the scope. This is called by code generated by the compose compiler plugin and
      * should not be called directly.
      */
-    fun updateScope(@Suppress("PrimitiveInLambda") block: (Composer, Int) -> Unit)
+    fun updateScope(block: (Composer, Int) -> Unit)
 }
 
 internal enum class InvalidationResult {
@@ -3321,16 +3321,20 @@
                 } else if (key == referenceKey && objectKey == reference) {
                     // Group is a composition context reference. As this is being removed assume
                     // all movable groups in the composition that have this context will also be
-                    // released whe the compositions are disposed.
+                    // released when the compositions are disposed.
                     val contextHolder = reader.groupGet(group, 0) as? CompositionContextHolder
                     if (contextHolder != null) {
-                        // The contextHolder can be EMPTY in cases wher the content has been
+                        // The contextHolder can be EMPTY in cases where the content has been
                         // deactivated. Content is deactivated if the content is just being
                         // held onto for recycling and is not otherwise active. In this case
                         // the composers we are likely to find here have already been disposed.
                         val compositionContext = contextHolder.ref
                         compositionContext.composers.forEach { composer ->
                             composer.reportAllMovableContent()
+
+                            // Mark the composition as being removed so it will not be recomposed
+                            // this turn.
+                            parentContext.reportRemovedComposition(composer.composition)
                         }
                     }
                     reader.nodeCount(group)
@@ -3551,6 +3555,10 @@
         ) {
             parentContext.movableContentStateReleased(reference, data)
         }
+
+        override fun reportRemovedComposition(composition: ControlledComposition) {
+            parentContext.reportRemovedComposition(composition)
+        }
     }
 
     private fun updateCompoundKeyWhenWeEnterGroup(groupKey: Int, dataKey: Any?, data: Any?) {
@@ -3613,7 +3621,6 @@
     @Suppress("NOTHING_TO_INLINE") // Inlining the compare has noticeable impact
     inline fun set(
         value: Int,
-        @Suppress("PrimitiveInLambda")
         noinline block: T.(value: Int) -> Unit
     ) = with(composer) {
         if (inserting || rememberedValue() != value) {
@@ -3654,7 +3661,6 @@
     @Suppress("NOTHING_TO_INLINE") // Inlining the compare has noticeable impact
     inline fun update(
         value: Int,
-        @Suppress("PrimitiveInLambda")
         noinline block: T.(value: Int) -> Unit
     ) = with(composer) {
         val inserting = inserting
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
index 596d03d..5295c43 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt
@@ -72,4 +72,6 @@
     internal open fun movableContentStateResolve(
         reference: MovableContentStateReference
     ): MovableContentState? = null
+
+    internal abstract fun reportRemovedComposition(composition: ControlledComposition)
 }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
index 4bf9756..c6227a5 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
@@ -40,10 +40,7 @@
      * Time values provided are strictly monotonically increasing; after a call to [withFrameNanos]
      * completes it must not provide the same value again for a subsequent call.
      */
-    suspend fun <R> withFrameNanos(
-        @Suppress("PrimitiveInLambda")
-        onFrame: (frameTimeNanos: Long) -> R
-    ): R
+    suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R
 
     override val key: CoroutineContext.Key<*> get() = Key
 
@@ -86,10 +83,8 @@
  * not present in the [CoroutineContext].
  */
 @OptIn(ExperimentalComposeApi::class)
-suspend fun <R> withFrameNanos(
-    @Suppress("PrimitiveInLambda")
-    onFrame: (frameTimeNanos: Long) -> R
-): R = coroutineContext.monotonicFrameClock.withFrameNanos(onFrame)
+suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R =
+    coroutineContext.monotonicFrameClock.withFrameNanos(onFrame)
 
 /**
  * Suspends until a new frame is requested, immediately invokes [onFrame] with the frame time
@@ -109,10 +104,8 @@
  * not present in the [CoroutineContext].
  */
 @OptIn(ExperimentalComposeApi::class)
-suspend fun <R> withFrameMillis(
-    @Suppress("PrimitiveInLambda")
-    onFrame: (frameTimeMillis: Long) -> R
-): R = coroutineContext.monotonicFrameClock.withFrameMillis(onFrame)
+suspend fun <R> withFrameMillis(onFrame: (frameTimeMillis: Long) -> R): R =
+    coroutineContext.monotonicFrameClock.withFrameMillis(onFrame)
 
 /**
  * Returns the [MonotonicFrameClock] for this [CoroutineContext] or throws [IllegalStateException]
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/PausableMonotonicFrameClock.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/PausableMonotonicFrameClock.kt
index c6431d8..b8a9246c 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/PausableMonotonicFrameClock.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/PausableMonotonicFrameClock.kt
@@ -58,10 +58,7 @@
         latch.openLatch()
     }
 
-    override suspend fun <R> withFrameNanos(
-        @Suppress("PrimitiveInLambda")
-        onFrame: (frameTimeNanos: Long) -> R
-    ): R {
+    override suspend fun <R> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R {
         latch.await()
         return frameClock.withFrameNanos(onFrame)
     }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/RecomposeScopeImpl.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/RecomposeScopeImpl.kt
index f7c7b86..61f8d70 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/RecomposeScopeImpl.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/RecomposeScopeImpl.kt
@@ -209,10 +209,7 @@
      * Update [block]. The scope is returned by [Composer.endRestartGroup] when [used] is true
      * and implements [ScopeUpdateScope].
      */
-    override fun updateScope(
-        @Suppress("PrimitiveInLambda")
-        block: (Composer, Int) -> Unit
-    ) { this.block = block }
+    override fun updateScope(block: (Composer, Int) -> Unit) { this.block = block }
 
     private var currentToken = 0
     private var trackedInstances: IdentityArrayIntMap? = null
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
index e60bf00..e16cdd8 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
@@ -215,6 +215,7 @@
     private val compositionValueStatesAvailable =
         mutableMapOf<MovableContentStateReference, MovableContentState>()
     private var failedCompositions: MutableList<ControlledComposition>? = null
+    private var compositionsRemoved: MutableSet<ControlledComposition>? = null
     private var workContinuation: CancellableContinuation<Unit>? = null
     private var concurrentCompositionsOutstanding = 0
     private var isClosed: Boolean = false
@@ -563,7 +564,9 @@
                     // composers to work on
                     recordComposerModifications()
                     synchronized(stateLock) {
-                        compositionInvalidations.fastForEach { toRecompose += it }
+                        compositionInvalidations.fastForEach {
+                            toRecompose += it
+                        }
                         compositionInvalidations.clear()
                     }
 
@@ -682,6 +685,7 @@
                     Snapshot.notifyObjectsInitialized()
                     alreadyComposed.clear()
                     modifiedValues.clear()
+                    compositionsRemoved = null
                 }
             }
 
@@ -1105,7 +1109,10 @@
         composition: ControlledComposition,
         modifiedValues: IdentityArraySet<Any>?
     ): ControlledComposition? {
-        if (composition.isComposing || composition.isDisposed) return null
+        if (composition.isComposing ||
+            composition.isDisposed ||
+            compositionsRemoved?.contains(composition) == true) return null
+
         return if (
             composing(composition, modifiedValues) {
                 if (modifiedValues?.isNotEmpty() == true) {
@@ -1333,6 +1340,16 @@
         }
     }
 
+    internal override fun reportRemovedComposition(composition: ControlledComposition) {
+        synchronized(stateLock) {
+            val compositionsRemoved = compositionsRemoved
+                ?: mutableSetOf<ControlledComposition>().also {
+                    compositionsRemoved = it
+                }
+            compositionsRemoved.add(composition)
+        }
+    }
+
     override fun movableContentStateResolve(
         reference: MovableContentStateReference
     ): MovableContentState? =
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
index 328f19c..e38e77f 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
@@ -1047,11 +1047,7 @@
         return result
     }
 
-    internal fun forEachData(
-        group: Int,
-        @Suppress("PrimitiveInLambda")
-        block: (index: Int, data: Any?) -> Unit
-    ) {
+    internal fun forEachData(group: Int, block: (index: Int, data: Any?) -> Unit) {
         val start = groups.slotAnchor(group)
         val end = if (group + 1 < table.groupsSize)
             table.groups.dataAnchor(group + 1) else table.slotsSize
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/changelist/Operations.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/changelist/Operations.kt
index fb71e29..95823fb 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/changelist/Operations.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/changelist/Operations.kt
@@ -70,11 +70,15 @@
      * Resets the collection to its initial state, clearing all stored operations and arguments.
      */
     fun clear() {
-        opCodes = arrayOfNulls(InitialCapacity)
+        // We don't technically need to clear the opCodes or intArgs arrays, because we ensure
+        // that every operation that gets pushed to this data structure has all of its arguments
+        // set exactly once. This guarantees that they'll overwrite any stale, dirty values from
+        // previous entries on the stack, so we shouldn't ever run into problems of having
+        // uninitialized values causing undefined behavior for other operations.
         opCodesSize = 0
-        intArgs = IntArray(InitialCapacity)
         intArgsSize = 0
-        objectArgs = arrayOfNulls(InitialCapacity)
+        // Clear the object arguments array to prevent leaking memory
+        objectArgs.fill(null, fromIndex = 0, toIndex = objectArgsSize)
         objectArgsSize = 0
     }
 
@@ -98,7 +102,8 @@
 
         // Resize arrays if needed
         if (opCodesSize == opCodes.size) {
-            opCodes = opCodes.copyOf(opCodesSize * 2)
+            val resizeAmount = opCodesSize.coerceAtMost(MaxResizeAmount)
+            opCodes = opCodes.copyOf(opCodesSize + resizeAmount)
         }
         ensureIntArgsSizeAtLeast(intArgsSize + operation.ints)
         ensureObjectArgsSizeAtLeast(objectArgsSize + operation.objects)
@@ -109,15 +114,22 @@
         objectArgsSize += operation.objects
     }
 
-    private fun ensureIntArgsSizeAtLeast(size: Int) {
-        if (size > intArgs.size) {
-            intArgs = intArgs.copyOf((intArgsSize * 2).coerceAtLeast(size))
+    private fun determineNewSize(currentSize: Int, requiredSize: Int): Int {
+        val resizeAmount = currentSize.coerceAtMost(MaxResizeAmount)
+        return (currentSize + resizeAmount).coerceAtLeast(requiredSize)
+    }
+
+    private fun ensureIntArgsSizeAtLeast(requiredSize: Int) {
+        val currentSize = intArgs.size
+        if (requiredSize > currentSize) {
+            intArgs = intArgs.copyOf(determineNewSize(currentSize, requiredSize))
         }
     }
 
-    private fun ensureObjectArgsSizeAtLeast(size: Int) {
-        if (size > objectArgs.size) {
-            objectArgs = objectArgs.copyOf((objectArgsSize * 2).coerceAtLeast(size))
+    private fun ensureObjectArgsSizeAtLeast(requiredSize: Int) {
+        val currentSize = objectArgs.size
+        if (requiredSize > currentSize) {
+            objectArgs = objectArgs.copyOf(determineNewSize(currentSize, requiredSize))
         }
     }
 
@@ -373,6 +385,7 @@
     }
 
     companion object {
+        private const val MaxResizeAmount = 1024
         internal const val InitialCapacity = 16
     }
 
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/MutableVector.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/MutableVector.kt
index 50f5fe2..72de7b1 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/MutableVector.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/collection/MutableVector.kt
@@ -1169,11 +1169,7 @@
  * return the value to be assigned to the element at its given index.
  */
 @OptIn(ExperimentalContracts::class)
-inline fun <reified T> MutableVector(
-    size: Int,
-    @Suppress("PrimitiveInLambda")
-    noinline init: (Int) -> T
-): MutableVector<T> {
+inline fun <reified T> MutableVector(size: Int, noinline init: (Int) -> T): MutableVector<T> {
     contract { callsInPlace(init) }
     val arr = Array(size, init)
     return MutableVector(arr as Array<T?>, size)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt
index b97e1f4..f97c0ed 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/external/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt
@@ -867,15 +867,11 @@
     }
 
     // For testing trie structure
-    internal fun accept(
-        @Suppress("PrimitiveInLambda")
-        visitor: (node: TrieNode<K, V>, shift: Int, hash: Int, dataMap: Int, nodeMap: Int) -> Unit
-    ) {
+    internal fun accept(visitor: (node: TrieNode<K, V>, shift: Int, hash: Int, dataMap: Int, nodeMap: Int) -> Unit) {
         accept(visitor, 0, 0)
     }
 
     private fun accept(
-        @Suppress("PrimitiveInLambda")
             visitor: (node: TrieNode<K, V>, shift: Int, hash: Int, dataMap: Int, nodeMap: Int) -> Unit,
             hash: Int,
             shift: Int
diff --git a/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/changelist/OperationsTest.kt b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/changelist/OperationsTest.kt
index e2e1559..12e524b 100644
--- a/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/changelist/OperationsTest.kt
+++ b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/changelist/OperationsTest.kt
@@ -591,14 +591,14 @@
         }
 
         val actualOpCodes = stack.opCodes
-        if (!actualOpCodes.asIterable().startsWith(expectedOperations, null)) {
+        if (!actualOpCodes.asIterable().startsWith(expectedOperations)) {
             errors += "opCodes array did not match expected operations " +
                 "(expected [${expectedOperations.joinToString()}], was " +
                 "[${actualOpCodes.joinToString()}])"
         }
 
         val actualIntArgs = stack.intArgs
-        if (!actualIntArgs.asIterable().startsWith(expectedIntArgs, 0)) {
+        if (!actualIntArgs.asIterable().startsWith(expectedIntArgs)) {
             errors += "intArgs array did not match expected operations " +
                 "(expected [${expectedIntArgs.joinToString()}], was " +
                 "[${actualIntArgs.joinToString()}])"
@@ -621,6 +621,21 @@
     }
 
     private fun <T> Iterable<T>.startsWith(
+        other: Iterable<T>
+    ): Boolean {
+        val thisIterator = iterator()
+        val otherIterator = other.iterator()
+
+        while (otherIterator.hasNext()) {
+            if (!thisIterator.hasNext() || thisIterator.next() != otherIterator.next()) {
+                return false
+            }
+        }
+
+        return true
+    }
+
+    private fun <T> Iterable<T>.startsWith(
         other: Iterable<T>,
         endFill: T
     ): Boolean {
diff --git a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
index ba0a267..acafe13 100644
--- a/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
+++ b/compose/runtime/runtime/src/jvmMain/kotlin/androidx/compose/runtime/ActualJvm.jvm.kt
@@ -73,7 +73,7 @@
 internal actual typealias TestOnly = org.jetbrains.annotations.TestOnly
 
 internal actual fun invokeComposable(composer: Composer, composable: @Composable () -> Unit) {
-    @Suppress("UNCHECKED_CAST", "PrimitiveInLambda")
+    @Suppress("UNCHECKED_CAST")
     val realFn = composable as Function2<Composer, Int, Unit>
     realFn(composer, 1)
 }
@@ -82,7 +82,7 @@
     composer: Composer,
     composable: @Composable () -> T
 ): T {
-    @Suppress("UNCHECKED_CAST", "PrimitiveInLambda")
+    @Suppress("UNCHECKED_CAST")
     val realFn = composable as Function2<Composer, Int, T>
     return realFn(composer, 1)
 }
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
index 56886e5..bc3a3d5 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/RecomposerTests.kt
@@ -180,16 +180,19 @@
         var someState by mutableStateOf(0)
         var someOtherState by mutableStateOf(1)
 
-        @Composable fun B(@Suppress("UNUSED_PARAMETER") value: Int) {
+        @Composable
+        fun B(@Suppress("UNUSED_PARAMETER") value: Int) {
             // empty
         }
 
-        @Composable fun A() {
+        @Composable
+        fun A() {
             B(someState)
             someState++
         }
 
-        @Composable fun T() {
+        @Composable
+        fun T() {
             TestSubcomposition {
                 // Take up some slot space
                 // This makes it more likely to reproduce bug 157111271.
@@ -263,6 +266,22 @@
         advance()
     }
 
+    @Test // b/254645321
+    fun testSubcompositionDisposedInParent() = compositionTest {
+        var state by mutableStateOf(true)
+
+        compose {
+            if (state) {
+                TestSubcomposition {
+                    assert(state) { "Subcomposition should be disposed if state is false" }
+                }
+            }
+        }
+
+        state = false
+        advance()
+    }
+
     @Test
     @OptIn(ExperimentalComposeApi::class)
     fun compositionRecomposeContextDelegation() {
diff --git a/compose/ui/ui-android-stubs/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-android-stubs/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..8e22228
--- /dev/null
+++ b/compose/ui/ui-android-stubs/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,78 @@
+// Signature format: 4.0
+package android.view {
+
+  public final class DisplayListCanvas extends android.graphics.Canvas {
+    ctor public DisplayListCanvas();
+    method public void drawRenderNode(android.view.RenderNode);
+  }
+
+  public class RenderNode {
+    method public static android.view.RenderNode create(String?, android.view.View?);
+    method public void destroy();
+    method public void destroyDisplayListData();
+    method public void discardDisplayList();
+    method public void end(android.view.DisplayListCanvas);
+    method public float getAlpha();
+    method public int getAmbientShadowColor();
+    method public float getCameraDistance();
+    method public boolean getClipToOutline();
+    method public float getElevation();
+    method public void getInverseMatrix(android.graphics.Matrix);
+    method public void getMatrix(android.graphics.Matrix);
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getRotation();
+    method public float getRotationX();
+    method public float getRotationY();
+    method public float getScaleX();
+    method public float getScaleY();
+    method public int getSpotShadowColor();
+    method public float getTranslationX();
+    method public float getTranslationY();
+    method public float getTranslationZ();
+    method public boolean hasIdentityMatrix();
+    method public boolean hasOverlappingRendering();
+    method public boolean hasShadow();
+    method public boolean isAttached();
+    method public boolean isPivotExplicitlySet();
+    method public boolean isValid();
+    method public boolean offsetLeftAndRight(int);
+    method public boolean offsetTopAndBottom(int);
+    method public void output();
+    method public boolean setAlpha(float);
+    method public boolean setAmbientShadowColor(int);
+    method public boolean setAnimationMatrix(android.graphics.Matrix);
+    method public boolean setBottom(int);
+    method public boolean setCameraDistance(float);
+    method public boolean setClipBounds(android.graphics.Rect?);
+    method public boolean setClipToBounds(boolean);
+    method public boolean setClipToOutline(boolean);
+    method public boolean setElevation(float);
+    method public boolean setHasOverlappingRendering(boolean);
+    method public boolean setLayerPaint(android.graphics.Paint?);
+    method public boolean setLayerType(int);
+    method public boolean setLeft(int);
+    method public boolean setLeftTopRightBottom(int, int, int, int);
+    method public boolean setOutline(android.graphics.Outline?);
+    method public boolean setPivotX(float);
+    method public boolean setPivotY(float);
+    method public boolean setProjectBackwards(boolean);
+    method public boolean setProjectionReceiver(boolean);
+    method public boolean setRevealClip(boolean, float, float, float);
+    method public boolean setRight(int);
+    method public boolean setRotation(float);
+    method public boolean setRotationX(float);
+    method public boolean setRotationY(float);
+    method public boolean setScaleX(float);
+    method public boolean setScaleY(float);
+    method public boolean setSpotShadowColor(int);
+    method public boolean setStaticMatrix(android.graphics.Matrix);
+    method public boolean setTop(int);
+    method public boolean setTranslationX(float);
+    method public boolean setTranslationY(float);
+    method public boolean setTranslationZ(float);
+    method public android.view.DisplayListCanvas start(int, int);
+  }
+
+}
+
diff --git a/compose/ui/ui-geometry/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-geometry/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..5aabfcd
--- /dev/null
+++ b/compose/ui/ui-geometry/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,272 @@
+// Signature format: 4.0
+package androidx.compose.ui.geometry {
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class CornerRadius {
+    method @androidx.compose.runtime.Stable public inline operator float component1();
+    method @androidx.compose.runtime.Stable public inline operator float component2();
+    method public long copy(optional float x, optional float y);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method public float getX();
+    method public float getY();
+    method @androidx.compose.runtime.Stable public operator long minus(long other);
+    method @androidx.compose.runtime.Stable public operator long plus(long other);
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    method @androidx.compose.runtime.Stable public operator long unaryMinus();
+    property @androidx.compose.runtime.Stable public final float x;
+    property @androidx.compose.runtime.Stable public final float y;
+    field public static final androidx.compose.ui.geometry.CornerRadius.Companion Companion;
+  }
+
+  public static final class CornerRadius.Companion {
+    method public long getZero();
+    property public final long Zero;
+  }
+
+  public final class CornerRadiusKt {
+    method @androidx.compose.runtime.Stable public static long CornerRadius(float x, optional float y);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+  }
+
+  public final class MutableRect {
+    ctor public MutableRect(float left, float top, float right, float bottom);
+    method public operator boolean contains(long offset);
+    method public float getBottom();
+    method public inline float getHeight();
+    method public float getLeft();
+    method public float getRight();
+    method public long getSize();
+    method public float getTop();
+    method public inline float getWidth();
+    method @androidx.compose.runtime.Stable public void intersect(float left, float top, float right, float bottom);
+    method public boolean isEmpty();
+    method public void set(float left, float top, float right, float bottom);
+    method public void setBottom(float);
+    method public void setLeft(float);
+    method public void setRight(float);
+    method public void setTop(float);
+    property public final float bottom;
+    property public final inline float height;
+    property public final boolean isEmpty;
+    property public final float left;
+    property public final float right;
+    property public final long size;
+    property public final float top;
+    property public final inline float width;
+  }
+
+  public final class MutableRectKt {
+    method public static androidx.compose.ui.geometry.Rect toRect(androidx.compose.ui.geometry.MutableRect);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Offset {
+    method @androidx.compose.runtime.Stable public operator float component1();
+    method @androidx.compose.runtime.Stable public operator float component2();
+    method public long copy(optional float x, optional float y);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method @androidx.compose.runtime.Stable public float getDistance();
+    method @androidx.compose.runtime.Stable public float getDistanceSquared();
+    method public float getX();
+    method public float getY();
+    method @androidx.compose.runtime.Stable public boolean isValid();
+    method @androidx.compose.runtime.Stable public operator long minus(long other);
+    method @androidx.compose.runtime.Stable public operator long plus(long other);
+    method @androidx.compose.runtime.Stable public operator long rem(float operand);
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    method @androidx.compose.runtime.Stable public operator long unaryMinus();
+    property @androidx.compose.runtime.Stable public final float x;
+    property @androidx.compose.runtime.Stable public final float y;
+    field public static final androidx.compose.ui.geometry.Offset.Companion Companion;
+  }
+
+  public static final class Offset.Companion {
+    method public long getInfinite();
+    method public long getUnspecified();
+    method public long getZero();
+    property public final long Infinite;
+    property public final long Unspecified;
+    property public final long Zero;
+  }
+
+  public final class OffsetKt {
+    method @androidx.compose.runtime.Stable public static long Offset(float x, float y);
+    method public static boolean isFinite(long);
+    method public static boolean isSpecified(long);
+    method public static boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Offset> block);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Rect {
+    ctor public Rect(@androidx.compose.runtime.Stable float left, @androidx.compose.runtime.Stable float top, @androidx.compose.runtime.Stable float right, @androidx.compose.runtime.Stable float bottom);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public operator boolean contains(long offset);
+    method public androidx.compose.ui.geometry.Rect copy(float left, float top, float right, float bottom);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect deflate(float delta);
+    method public float getBottom();
+    method public long getBottomCenter();
+    method public long getBottomLeft();
+    method public long getBottomRight();
+    method public long getCenter();
+    method public long getCenterLeft();
+    method public long getCenterRight();
+    method public float getHeight();
+    method public float getLeft();
+    method public float getMaxDimension();
+    method public float getMinDimension();
+    method public float getRight();
+    method public long getSize();
+    method public float getTop();
+    method public long getTopCenter();
+    method public long getTopLeft();
+    method public long getTopRight();
+    method public float getWidth();
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect inflate(float delta);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect intersect(androidx.compose.ui.geometry.Rect other);
+    method public boolean isEmpty();
+    method public boolean isFinite();
+    method public boolean isInfinite();
+    method public boolean overlaps(androidx.compose.ui.geometry.Rect other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect translate(float translateX, float translateY);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.geometry.Rect translate(long offset);
+    property public final float bottom;
+    property public final long bottomCenter;
+    property public final long bottomLeft;
+    property public final long bottomRight;
+    property public final long center;
+    property public final long centerLeft;
+    property public final long centerRight;
+    property @androidx.compose.runtime.Stable public final float height;
+    property @androidx.compose.runtime.Stable public final boolean isEmpty;
+    property @androidx.compose.runtime.Stable public final boolean isFinite;
+    property @androidx.compose.runtime.Stable public final boolean isInfinite;
+    property public final float left;
+    property public final float maxDimension;
+    property public final float minDimension;
+    property public final float right;
+    property @androidx.compose.runtime.Stable public final long size;
+    property public final float top;
+    property public final long topCenter;
+    property public final long topLeft;
+    property public final long topRight;
+    property @androidx.compose.runtime.Stable public final float width;
+    field public static final androidx.compose.ui.geometry.Rect.Companion Companion;
+  }
+
+  public static final class Rect.Companion {
+    method public androidx.compose.ui.geometry.Rect getZero();
+    property public final androidx.compose.ui.geometry.Rect Zero;
+  }
+
+  public final class RectKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect Rect(long center, float radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect Rect(long offset, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect Rect(long topLeft, long bottomRight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect lerp(androidx.compose.ui.geometry.Rect start, androidx.compose.ui.geometry.Rect stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class RoundRect {
+    ctor public RoundRect(float left, float top, float right, float bottom, optional long topLeftCornerRadius, optional long topRightCornerRadius, optional long bottomRightCornerRadius, optional long bottomLeftCornerRadius);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public long component5-kKHJgLs();
+    method public long component6-kKHJgLs();
+    method public long component7-kKHJgLs();
+    method public long component8-kKHJgLs();
+    method public operator boolean contains(long point);
+    method public androidx.compose.ui.geometry.RoundRect copy-MDFrsts(float left, float top, float right, float bottom, long topLeftCornerRadius, long topRightCornerRadius, long bottomRightCornerRadius, long bottomLeftCornerRadius);
+    method public float getBottom();
+    method public long getBottomLeftCornerRadius();
+    method public long getBottomRightCornerRadius();
+    method public float getHeight();
+    method public float getLeft();
+    method public float getRight();
+    method public float getTop();
+    method public long getTopLeftCornerRadius();
+    method public long getTopRightCornerRadius();
+    method public float getWidth();
+    method public static androidx.compose.ui.geometry.RoundRect getZero();
+    property public static final androidx.compose.ui.geometry.RoundRect Zero;
+    property public final float bottom;
+    property public final long bottomLeftCornerRadius;
+    property public final long bottomRightCornerRadius;
+    property public final float height;
+    property public final float left;
+    property public final float right;
+    property public final float top;
+    property public final long topLeftCornerRadius;
+    property public final long topRightCornerRadius;
+    property public final float width;
+    field public static final androidx.compose.ui.geometry.RoundRect.Companion Companion;
+  }
+
+  public static final class RoundRect.Companion {
+    method public androidx.compose.ui.geometry.RoundRect getZero();
+    property public final androidx.compose.ui.geometry.RoundRect Zero;
+  }
+
+  public final class RoundRectKt {
+    method public static androidx.compose.ui.geometry.RoundRect RoundRect(androidx.compose.ui.geometry.Rect rect, float radiusX, float radiusY);
+    method public static androidx.compose.ui.geometry.RoundRect RoundRect(androidx.compose.ui.geometry.Rect rect, long cornerRadius);
+    method public static androidx.compose.ui.geometry.RoundRect RoundRect(androidx.compose.ui.geometry.Rect rect, optional long topLeft, optional long topRight, optional long bottomRight, optional long bottomLeft);
+    method public static androidx.compose.ui.geometry.RoundRect RoundRect(float left, float top, float right, float bottom, float radiusX, float radiusY);
+    method public static androidx.compose.ui.geometry.RoundRect RoundRect(float left, float top, float right, float bottom, long cornerRadius);
+    method public static androidx.compose.ui.geometry.Rect getBoundingRect(androidx.compose.ui.geometry.RoundRect);
+    method public static long getCenter(androidx.compose.ui.geometry.RoundRect);
+    method public static float getMaxDimension(androidx.compose.ui.geometry.RoundRect);
+    method public static float getMinDimension(androidx.compose.ui.geometry.RoundRect);
+    method public static androidx.compose.ui.geometry.Rect getSafeInnerRect(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isCircle(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isEllipse(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isEmpty(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isFinite(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isRect(androidx.compose.ui.geometry.RoundRect);
+    method public static boolean isSimple(androidx.compose.ui.geometry.RoundRect);
+    method public static androidx.compose.ui.geometry.RoundRect lerp(androidx.compose.ui.geometry.RoundRect start, androidx.compose.ui.geometry.RoundRect stop, float fraction);
+    method public static androidx.compose.ui.geometry.RoundRect translate(androidx.compose.ui.geometry.RoundRect, long offset);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Size {
+    method @androidx.compose.runtime.Stable public inline operator float component1();
+    method @androidx.compose.runtime.Stable public inline operator float component2();
+    method public long copy(optional float width, optional float height);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method public float getHeight();
+    method public float getMaxDimension();
+    method public float getMinDimension();
+    method public float getWidth();
+    method @androidx.compose.runtime.Stable public boolean isEmpty();
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    property @androidx.compose.runtime.Stable public final float height;
+    property @androidx.compose.runtime.Stable public final float maxDimension;
+    property @androidx.compose.runtime.Stable public final float minDimension;
+    property @androidx.compose.runtime.Stable public final float width;
+    field public static final androidx.compose.ui.geometry.Size.Companion Companion;
+  }
+
+  public static final class Size.Companion {
+    method public long getUnspecified();
+    method public long getZero();
+    property public final long Unspecified;
+    property public final long Zero;
+  }
+
+  public final class SizeKt {
+    method @androidx.compose.runtime.Stable public static long Size(float width, float height);
+    method public static long getCenter(long);
+    method public static inline boolean isSpecified(long);
+    method public static inline boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.geometry.Size> block);
+    method @androidx.compose.runtime.Stable public static inline operator long times(double, long size);
+    method @androidx.compose.runtime.Stable public static inline operator long times(float, long size);
+    method @androidx.compose.runtime.Stable public static inline operator long times(int, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect toRect(long);
+  }
+
+}
+
diff --git a/compose/ui/ui-geometry/build.gradle b/compose/ui/ui-geometry/build.gradle
index 15e6e16..951f1d1 100644
--- a/compose/ui/ui-geometry/build.gradle
+++ b/compose/ui/ui-geometry/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-graphics/api/1.5.0-beta01.txt b/compose/ui/ui-graphics/api/1.5.0-beta01.txt
index eb84156..ed2ed75 100644
--- a/compose/ui/ui-graphics/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-graphics/api/1.5.0-beta01.txt
@@ -404,9 +404,6 @@
     method public operator long invoke();
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGraphicsApi {
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class FilterQuality {
     method public int getValue();
     property public final int value;
diff --git a/compose/ui/ui-graphics/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-graphics/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..eb84156
--- /dev/null
+++ b/compose/ui/ui-graphics/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,1632 @@
+// Signature format: 4.0
+package androidx.compose.ui.graphics {
+
+  public final class AndroidBlendMode_androidKt {
+    method public static boolean isSupported(int);
+  }
+
+  public final class AndroidCanvas_androidKt {
+    method public static androidx.compose.ui.graphics.Canvas Canvas(android.graphics.Canvas c);
+    method public static android.graphics.Canvas getNativeCanvas(androidx.compose.ui.graphics.Canvas);
+  }
+
+  public final class AndroidColorFilter_androidKt {
+    method public static android.graphics.ColorFilter asAndroidColorFilter(androidx.compose.ui.graphics.ColorFilter);
+    method public static androidx.compose.ui.graphics.ColorFilter asComposeColorFilter(android.graphics.ColorFilter);
+  }
+
+  public final class AndroidColorSpace_androidKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static android.graphics.ColorSpace toAndroidColorSpace(androidx.compose.ui.graphics.colorspace.ColorSpace);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.compose.ui.graphics.colorspace.ColorSpace toComposeColorSpace(android.graphics.ColorSpace);
+  }
+
+  public final class AndroidImageBitmap_androidKt {
+    method public static android.graphics.Bitmap asAndroidBitmap(androidx.compose.ui.graphics.ImageBitmap);
+    method public static androidx.compose.ui.graphics.ImageBitmap asImageBitmap(android.graphics.Bitmap);
+  }
+
+  public final class AndroidMatrixConversions_androidKt {
+    method public static void setFrom(android.graphics.Matrix, float[] matrix);
+    method public static void setFrom(float[], android.graphics.Matrix matrix);
+  }
+
+  public final class AndroidPaint implements androidx.compose.ui.graphics.Paint {
+    ctor public AndroidPaint();
+    ctor public AndroidPaint(android.graphics.Paint internalPaint);
+    method public android.graphics.Paint asFrameworkPaint();
+    method public float getAlpha();
+    method public int getBlendMode();
+    method public long getColor();
+    method public androidx.compose.ui.graphics.ColorFilter? getColorFilter();
+    method public int getFilterQuality();
+    method public androidx.compose.ui.graphics.PathEffect? getPathEffect();
+    method public android.graphics.Shader? getShader();
+    method public int getStrokeCap();
+    method public int getStrokeJoin();
+    method public float getStrokeMiterLimit();
+    method public float getStrokeWidth();
+    method public int getStyle();
+    method public boolean isAntiAlias();
+    method public void setAlpha(float);
+    method public void setAntiAlias(boolean);
+    method public void setBlendMode(int);
+    method public void setColor(long);
+    method public void setColorFilter(androidx.compose.ui.graphics.ColorFilter?);
+    method public void setFilterQuality(int);
+    method public void setPathEffect(androidx.compose.ui.graphics.PathEffect?);
+    method public void setShader(android.graphics.Shader?);
+    method public void setStrokeCap(int);
+    method public void setStrokeJoin(int);
+    method public void setStrokeMiterLimit(float);
+    method public void setStrokeWidth(float);
+    method public void setStyle(int);
+    property public float alpha;
+    property public int blendMode;
+    property public long color;
+    property public androidx.compose.ui.graphics.ColorFilter? colorFilter;
+    property public int filterQuality;
+    property public boolean isAntiAlias;
+    property public androidx.compose.ui.graphics.PathEffect? pathEffect;
+    property public android.graphics.Shader? shader;
+    property public int strokeCap;
+    property public int strokeJoin;
+    property public float strokeMiterLimit;
+    property public float strokeWidth;
+    property public int style;
+  }
+
+  public final class AndroidPaint_androidKt {
+    method public static androidx.compose.ui.graphics.Paint Paint();
+    method public static androidx.compose.ui.graphics.Paint toComposePaint(android.graphics.Paint);
+  }
+
+  public final class AndroidPath implements androidx.compose.ui.graphics.Path {
+    ctor public AndroidPath(optional android.graphics.Path internalPath);
+    method public void addArc(androidx.compose.ui.geometry.Rect oval, float startAngleDegrees, float sweepAngleDegrees);
+    method public void addArcRad(androidx.compose.ui.geometry.Rect oval, float startAngleRadians, float sweepAngleRadians);
+    method public void addOval(androidx.compose.ui.geometry.Rect oval);
+    method public void addPath(androidx.compose.ui.graphics.Path path, long offset);
+    method public void addRect(androidx.compose.ui.geometry.Rect rect);
+    method public void addRoundRect(androidx.compose.ui.geometry.RoundRect roundRect);
+    method public void arcTo(androidx.compose.ui.geometry.Rect rect, float startAngleDegrees, float sweepAngleDegrees, boolean forceMoveTo);
+    method public void close();
+    method public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3);
+    method public androidx.compose.ui.geometry.Rect getBounds();
+    method public int getFillType();
+    method public android.graphics.Path getInternalPath();
+    method public boolean isConvex();
+    method public boolean isEmpty();
+    method public void lineTo(float x, float y);
+    method public void moveTo(float x, float y);
+    method public boolean op(androidx.compose.ui.graphics.Path path1, androidx.compose.ui.graphics.Path path2, int operation);
+    method public void quadraticBezierTo(float x1, float y1, float x2, float y2);
+    method public void relativeCubicTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3);
+    method public void relativeLineTo(float dx, float dy);
+    method public void relativeMoveTo(float dx, float dy);
+    method public void relativeQuadraticBezierTo(float dx1, float dy1, float dx2, float dy2);
+    method public void reset();
+    method public void setFillType(int);
+    method public void translate(long offset);
+    property public int fillType;
+    property public final android.graphics.Path internalPath;
+    property public boolean isConvex;
+    property public boolean isEmpty;
+  }
+
+  public final class AndroidPathEffect_androidKt {
+    method public static android.graphics.PathEffect asAndroidPathEffect(androidx.compose.ui.graphics.PathEffect);
+    method public static androidx.compose.ui.graphics.PathEffect toComposePathEffect(android.graphics.PathEffect);
+  }
+
+  public final class AndroidPathMeasure implements androidx.compose.ui.graphics.PathMeasure {
+    method public float getLength();
+    method public long getPosition(float distance);
+    method public boolean getSegment(float startDistance, float stopDistance, androidx.compose.ui.graphics.Path destination, boolean startWithMoveTo);
+    method public long getTangent(float distance);
+    method public void setPath(androidx.compose.ui.graphics.Path? path, boolean forceClosed);
+    property public float length;
+  }
+
+  public final class AndroidPathMeasure_androidKt {
+    method public static androidx.compose.ui.graphics.PathMeasure PathMeasure();
+  }
+
+  public final class AndroidPath_androidKt {
+    method public static androidx.compose.ui.graphics.Path Path();
+    method public static inline android.graphics.Path asAndroidPath(androidx.compose.ui.graphics.Path);
+    method public static androidx.compose.ui.graphics.Path asComposePath(android.graphics.Path);
+  }
+
+  public final class AndroidRenderEffect_androidKt {
+    method public static androidx.compose.ui.graphics.RenderEffect asComposeRenderEffect(android.graphics.RenderEffect);
+  }
+
+  public final class AndroidTileMode_androidKt {
+    method public static boolean isSupported(int);
+    method public static android.graphics.Shader.TileMode toAndroidTileMode(int);
+    method public static int toComposeTileMode(android.graphics.Shader.TileMode);
+  }
+
+  public final class AndroidVertexMode_androidKt {
+    method public static android.graphics.Canvas.VertexMode toAndroidVertexMode(int);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class BlendMode {
+    field public static final androidx.compose.ui.graphics.BlendMode.Companion Companion;
+  }
+
+  public static final class BlendMode.Companion {
+    method public int getClear();
+    method public int getColor();
+    method public int getColorBurn();
+    method public int getColorDodge();
+    method public int getDarken();
+    method public int getDifference();
+    method public int getDst();
+    method public int getDstAtop();
+    method public int getDstIn();
+    method public int getDstOut();
+    method public int getDstOver();
+    method public int getExclusion();
+    method public int getHardlight();
+    method public int getHue();
+    method public int getLighten();
+    method public int getLuminosity();
+    method public int getModulate();
+    method public int getMultiply();
+    method public int getOverlay();
+    method public int getPlus();
+    method public int getSaturation();
+    method public int getScreen();
+    method public int getSoftlight();
+    method public int getSrc();
+    method public int getSrcAtop();
+    method public int getSrcIn();
+    method public int getSrcOut();
+    method public int getSrcOver();
+    method public int getXor();
+    property public final int Clear;
+    property public final int Color;
+    property public final int ColorBurn;
+    property public final int ColorDodge;
+    property public final int Darken;
+    property public final int Difference;
+    property public final int Dst;
+    property public final int DstAtop;
+    property public final int DstIn;
+    property public final int DstOut;
+    property public final int DstOver;
+    property public final int Exclusion;
+    property public final int Hardlight;
+    property public final int Hue;
+    property public final int Lighten;
+    property public final int Luminosity;
+    property public final int Modulate;
+    property public final int Multiply;
+    property public final int Overlay;
+    property public final int Plus;
+    property public final int Saturation;
+    property public final int Screen;
+    property public final int Softlight;
+    property public final int Src;
+    property public final int SrcAtop;
+    property public final int SrcIn;
+    property public final int SrcOut;
+    property public final int SrcOver;
+    property public final int Xor;
+  }
+
+  @androidx.compose.runtime.Immutable public final class BlurEffect extends androidx.compose.ui.graphics.RenderEffect {
+    ctor public BlurEffect(androidx.compose.ui.graphics.RenderEffect? renderEffect, float radiusX, float radiusY, int edgeTreatment);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) protected android.graphics.RenderEffect createRenderEffect();
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class Brush {
+    method public abstract void applyTo(long size, androidx.compose.ui.graphics.Paint p, float alpha);
+    method public long getIntrinsicSize();
+    property public long intrinsicSize;
+    field public static final androidx.compose.ui.graphics.Brush.Companion Companion;
+  }
+
+  public static final class Brush.Companion {
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush horizontalGradient(java.util.List<androidx.compose.ui.graphics.Color> colors, optional float startX, optional float endX, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush horizontalGradient(kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional float startX, optional float endX, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush linearGradient(java.util.List<androidx.compose.ui.graphics.Color> colors, optional long start, optional long end, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush linearGradient(kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional long start, optional long end, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush radialGradient(java.util.List<androidx.compose.ui.graphics.Color> colors, optional long center, optional float radius, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush radialGradient(kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional long center, optional float radius, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush sweepGradient(java.util.List<androidx.compose.ui.graphics.Color> colors, optional long center);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush sweepGradient(kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional long center);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush verticalGradient(java.util.List<androidx.compose.ui.graphics.Color> colors, optional float startY, optional float endY, optional int tileMode);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.Brush verticalGradient(kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional float startY, optional float endY, optional int tileMode);
+  }
+
+  public final class BrushKt {
+    method public static androidx.compose.ui.graphics.ShaderBrush ShaderBrush(android.graphics.Shader shader);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface Canvas {
+    method public void clipPath(androidx.compose.ui.graphics.Path path, optional int clipOp);
+    method public default void clipRect(androidx.compose.ui.geometry.Rect rect, optional int clipOp);
+    method public void clipRect(float left, float top, float right, float bottom, optional int clipOp);
+    method public void concat(float[] matrix);
+    method public void disableZ();
+    method public default void drawArc(androidx.compose.ui.geometry.Rect rect, float startAngle, float sweepAngle, boolean useCenter, androidx.compose.ui.graphics.Paint paint);
+    method public void drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, androidx.compose.ui.graphics.Paint paint);
+    method public default void drawArcRad(androidx.compose.ui.geometry.Rect rect, float startAngleRad, float sweepAngleRad, boolean useCenter, androidx.compose.ui.graphics.Paint paint);
+    method public void drawCircle(long center, float radius, androidx.compose.ui.graphics.Paint paint);
+    method public void drawImage(androidx.compose.ui.graphics.ImageBitmap image, long topLeftOffset, androidx.compose.ui.graphics.Paint paint);
+    method public void drawImageRect(androidx.compose.ui.graphics.ImageBitmap image, optional long srcOffset, optional long srcSize, optional long dstOffset, optional long dstSize, androidx.compose.ui.graphics.Paint paint);
+    method public void drawLine(long p1, long p2, androidx.compose.ui.graphics.Paint paint);
+    method public default void drawOval(androidx.compose.ui.geometry.Rect rect, androidx.compose.ui.graphics.Paint paint);
+    method public void drawOval(float left, float top, float right, float bottom, androidx.compose.ui.graphics.Paint paint);
+    method public void drawPath(androidx.compose.ui.graphics.Path path, androidx.compose.ui.graphics.Paint paint);
+    method public void drawPoints(int pointMode, java.util.List<androidx.compose.ui.geometry.Offset> points, androidx.compose.ui.graphics.Paint paint);
+    method public void drawRawPoints(int pointMode, float[] points, androidx.compose.ui.graphics.Paint paint);
+    method public default void drawRect(androidx.compose.ui.geometry.Rect rect, androidx.compose.ui.graphics.Paint paint);
+    method public void drawRect(float left, float top, float right, float bottom, androidx.compose.ui.graphics.Paint paint);
+    method public void drawRoundRect(float left, float top, float right, float bottom, float radiusX, float radiusY, androidx.compose.ui.graphics.Paint paint);
+    method public void drawVertices(androidx.compose.ui.graphics.Vertices vertices, int blendMode, androidx.compose.ui.graphics.Paint paint);
+    method public void enableZ();
+    method public void restore();
+    method public void rotate(float degrees);
+    method public void save();
+    method public void saveLayer(androidx.compose.ui.geometry.Rect bounds, androidx.compose.ui.graphics.Paint paint);
+    method public void scale(float sx, optional float sy);
+    method public void skew(float sx, float sy);
+    method public default void skewRad(float sxRad, float syRad);
+    method public void translate(float dx, float dy);
+  }
+
+  public final class CanvasHolder {
+    ctor public CanvasHolder();
+    method public inline void drawInto(android.graphics.Canvas targetCanvas, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Canvas,kotlin.Unit> block);
+  }
+
+  public final class CanvasKt {
+    method public static androidx.compose.ui.graphics.Canvas Canvas(androidx.compose.ui.graphics.ImageBitmap image);
+    method public static void rotate(androidx.compose.ui.graphics.Canvas, float degrees, float pivotX, float pivotY);
+    method public static void rotateRad(androidx.compose.ui.graphics.Canvas, float radians, optional float pivotX, optional float pivotY);
+    method public static void scale(androidx.compose.ui.graphics.Canvas, float sx, optional float sy, float pivotX, float pivotY);
+    method public static inline void withSave(androidx.compose.ui.graphics.Canvas, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+    method public static inline void withSaveLayer(androidx.compose.ui.graphics.Canvas, androidx.compose.ui.geometry.Rect bounds, androidx.compose.ui.graphics.Paint paint, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class ClipOp {
+    field public static final androidx.compose.ui.graphics.ClipOp.Companion Companion;
+  }
+
+  public static final class ClipOp.Companion {
+    method public int getDifference();
+    method public int getIntersect();
+    property public final int Difference;
+    property public final int Intersect;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Color {
+    ctor public Color(long value);
+    method @androidx.compose.runtime.Stable public operator float component1();
+    method @androidx.compose.runtime.Stable public operator float component2();
+    method @androidx.compose.runtime.Stable public operator float component3();
+    method @androidx.compose.runtime.Stable public operator float component4();
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.graphics.colorspace.ColorSpace component5();
+    method public long convert(androidx.compose.ui.graphics.colorspace.ColorSpace colorSpace);
+    method @androidx.compose.runtime.Stable public long copy(optional float alpha, optional float red, optional float green, optional float blue);
+    method public float getAlpha();
+    method public float getBlue();
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace getColorSpace();
+    method public float getGreen();
+    method public float getRed();
+    method public long getValue();
+    property @androidx.compose.runtime.Stable public final float alpha;
+    property @androidx.compose.runtime.Stable public final float blue;
+    property @androidx.compose.runtime.Stable public final androidx.compose.ui.graphics.colorspace.ColorSpace colorSpace;
+    property @androidx.compose.runtime.Stable public final float green;
+    property @androidx.compose.runtime.Stable public final float red;
+    property public final long value;
+    field public static final androidx.compose.ui.graphics.Color.Companion Companion;
+  }
+
+  public static final class Color.Companion {
+    method public long getBlack();
+    method public long getBlue();
+    method public long getCyan();
+    method public long getDarkGray();
+    method public long getGray();
+    method public long getGreen();
+    method public long getLightGray();
+    method public long getMagenta();
+    method public long getRed();
+    method public long getTransparent();
+    method public long getUnspecified();
+    method public long getWhite();
+    method public long getYellow();
+    method public long hsl(float hue, float saturation, float lightness, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
+    method public long hsv(float hue, float saturation, float value, optional float alpha, optional androidx.compose.ui.graphics.colorspace.Rgb colorSpace);
+    property public final long Black;
+    property public final long Blue;
+    property public final long Cyan;
+    property public final long DarkGray;
+    property public final long Gray;
+    property public final long Green;
+    property public final long LightGray;
+    property public final long Magenta;
+    property public final long Red;
+    property public final long Transparent;
+    property public final long Unspecified;
+    property public final long White;
+    property public final long Yellow;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ColorFilter {
+    field public static final androidx.compose.ui.graphics.ColorFilter.Companion Companion;
+  }
+
+  public static final class ColorFilter.Companion {
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.ColorFilter colorMatrix(float[] colorMatrix);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.ColorFilter lighting(long multiply, long add);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.graphics.ColorFilter tint(long color, optional int blendMode);
+  }
+
+  public final class ColorKt {
+    method @androidx.compose.runtime.Stable public static long Color(float red, float green, float blue, optional float alpha, optional androidx.compose.ui.graphics.colorspace.ColorSpace colorSpace);
+    method @androidx.compose.runtime.Stable public static long Color(int color);
+    method @androidx.compose.runtime.Stable public static long Color(int red, int green, int blue, optional int alpha);
+    method @androidx.compose.runtime.Stable public static long Color(long color);
+    method @androidx.compose.runtime.Stable public static long compositeOver(long, long background);
+    method public static inline boolean isSpecified(long);
+    method public static inline boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method @androidx.compose.runtime.Stable public static float luminance(long);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.graphics.Color> block);
+    method @androidx.compose.runtime.Stable public static int toArgb(long);
+  }
+
+  @kotlin.jvm.JvmInline public final value class ColorMatrix {
+    ctor public ColorMatrix(optional float[] values);
+    method public void convertRgbToYuv();
+    method public void convertYuvToRgb();
+    method public inline operator float get(int row, int column);
+    method public float[] getValues();
+    method public void reset();
+    method public void set(float[] src);
+    method public inline operator void set(int row, int column, float v);
+    method public void setToRotateBlue(float degrees);
+    method public void setToRotateGreen(float degrees);
+    method public void setToRotateRed(float degrees);
+    method public void setToSaturation(float sat);
+    method public void setToScale(float redScale, float greenScale, float blueScale, float alphaScale);
+    method public operator void timesAssign(float[] colorMatrix);
+    property public final float[] values;
+  }
+
+  public fun interface ColorProducer {
+    method public operator long invoke();
+  }
+
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGraphicsApi {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class FilterQuality {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.compose.ui.graphics.FilterQuality.Companion Companion;
+  }
+
+  public static final class FilterQuality.Companion {
+    method public int getHigh();
+    method public int getLow();
+    method public int getMedium();
+    method public int getNone();
+    property public final int High;
+    property public final int Low;
+    property public final int Medium;
+    property public final int None;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ImageBitmap {
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace getColorSpace();
+    method public int getConfig();
+    method public boolean getHasAlpha();
+    method public int getHeight();
+    method public int getWidth();
+    method public void prepareToDraw();
+    method public void readPixels(int[] buffer, optional int startX, optional int startY, optional int width, optional int height, optional int bufferOffset, optional int stride);
+    property public abstract androidx.compose.ui.graphics.colorspace.ColorSpace colorSpace;
+    property public abstract int config;
+    property public abstract boolean hasAlpha;
+    property public abstract int height;
+    property public abstract int width;
+    field public static final androidx.compose.ui.graphics.ImageBitmap.Companion Companion;
+  }
+
+  public static final class ImageBitmap.Companion {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class ImageBitmapConfig {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.compose.ui.graphics.ImageBitmapConfig.Companion Companion;
+  }
+
+  public static final class ImageBitmapConfig.Companion {
+    method public int getAlpha8();
+    method public int getArgb8888();
+    method public int getF16();
+    method public int getGpu();
+    method public int getRgb565();
+    property public final int Alpha8;
+    property public final int Argb8888;
+    property public final int F16;
+    property public final int Gpu;
+    property public final int Rgb565;
+  }
+
+  public final class ImageBitmapKt {
+    method public static androidx.compose.ui.graphics.ImageBitmap ImageBitmap(int width, int height, optional int config, optional boolean hasAlpha, optional androidx.compose.ui.graphics.colorspace.ColorSpace colorSpace);
+    method public static androidx.compose.ui.graphics.PixelMap toPixelMap(androidx.compose.ui.graphics.ImageBitmap, optional int startX, optional int startY, optional int width, optional int height, optional int[] buffer, optional int bufferOffset, optional int stride);
+  }
+
+  @androidx.compose.runtime.Immutable public final class LinearGradient extends androidx.compose.ui.graphics.ShaderBrush {
+    method public android.graphics.Shader createShader(long size);
+    property public long intrinsicSize;
+  }
+
+  @kotlin.jvm.JvmInline public final value class Matrix {
+    ctor public Matrix(optional float[] values);
+    method public inline operator float get(int row, int column);
+    method public float[] getValues();
+    method public void invert();
+    method public void map(androidx.compose.ui.geometry.MutableRect rect);
+    method public androidx.compose.ui.geometry.Rect map(androidx.compose.ui.geometry.Rect rect);
+    method public long map(long point);
+    method public void reset();
+    method public void rotateX(float degrees);
+    method public void rotateY(float degrees);
+    method public void rotateZ(float degrees);
+    method public void scale(optional float x, optional float y, optional float z);
+    method public inline operator void set(int row, int column, float v);
+    method public void setFrom(float[] matrix);
+    method public operator void timesAssign(float[] m);
+    method public void translate(optional float x, optional float y, optional float z);
+    property public final float[] values;
+    field public static final androidx.compose.ui.graphics.Matrix.Companion Companion;
+    field public static final int Perspective0 = 3; // 0x3
+    field public static final int Perspective1 = 7; // 0x7
+    field public static final int Perspective2 = 15; // 0xf
+    field public static final int ScaleX = 0; // 0x0
+    field public static final int ScaleY = 5; // 0x5
+    field public static final int ScaleZ = 10; // 0xa
+    field public static final int SkewX = 4; // 0x4
+    field public static final int SkewY = 1; // 0x1
+    field public static final int TranslateX = 12; // 0xc
+    field public static final int TranslateY = 13; // 0xd
+    field public static final int TranslateZ = 14; // 0xe
+  }
+
+  public static final class Matrix.Companion {
+  }
+
+  public final class MatrixKt {
+    method public static boolean isIdentity(float[]);
+  }
+
+  @androidx.compose.runtime.Immutable public final class OffsetEffect extends androidx.compose.ui.graphics.RenderEffect {
+    ctor public OffsetEffect(androidx.compose.ui.graphics.RenderEffect? renderEffect, long offset);
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) protected android.graphics.RenderEffect createRenderEffect();
+  }
+
+  public abstract sealed class Outline {
+    method public abstract androidx.compose.ui.geometry.Rect getBounds();
+    property public abstract androidx.compose.ui.geometry.Rect bounds;
+  }
+
+  public static final class Outline.Generic extends androidx.compose.ui.graphics.Outline {
+    ctor public Outline.Generic(androidx.compose.ui.graphics.Path path);
+    method public androidx.compose.ui.geometry.Rect getBounds();
+    method public androidx.compose.ui.graphics.Path getPath();
+    property public androidx.compose.ui.geometry.Rect bounds;
+    property public final androidx.compose.ui.graphics.Path path;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class Outline.Rectangle extends androidx.compose.ui.graphics.Outline {
+    ctor public Outline.Rectangle(androidx.compose.ui.geometry.Rect rect);
+    method public androidx.compose.ui.geometry.Rect getBounds();
+    method public androidx.compose.ui.geometry.Rect getRect();
+    property public androidx.compose.ui.geometry.Rect bounds;
+    property public final androidx.compose.ui.geometry.Rect rect;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class Outline.Rounded extends androidx.compose.ui.graphics.Outline {
+    ctor public Outline.Rounded(androidx.compose.ui.geometry.RoundRect roundRect);
+    method public androidx.compose.ui.geometry.Rect getBounds();
+    method public androidx.compose.ui.geometry.RoundRect getRoundRect();
+    property public androidx.compose.ui.geometry.Rect bounds;
+    property public final androidx.compose.ui.geometry.RoundRect roundRect;
+  }
+
+  public final class OutlineKt {
+    method public static void addOutline(androidx.compose.ui.graphics.Path, androidx.compose.ui.graphics.Outline outline);
+    method public static void drawOutline(androidx.compose.ui.graphics.Canvas, androidx.compose.ui.graphics.Outline outline, androidx.compose.ui.graphics.Paint paint);
+    method public static void drawOutline(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.graphics.Outline outline, androidx.compose.ui.graphics.Brush brush, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public static void drawOutline(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.graphics.Outline outline, long color, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+  }
+
+  public interface Paint {
+    method public android.graphics.Paint asFrameworkPaint();
+    method public float getAlpha();
+    method public int getBlendMode();
+    method public long getColor();
+    method public androidx.compose.ui.graphics.ColorFilter? getColorFilter();
+    method public int getFilterQuality();
+    method public androidx.compose.ui.graphics.PathEffect? getPathEffect();
+    method public android.graphics.Shader? getShader();
+    method public int getStrokeCap();
+    method public int getStrokeJoin();
+    method public float getStrokeMiterLimit();
+    method public float getStrokeWidth();
+    method public int getStyle();
+    method public boolean isAntiAlias();
+    method public void setAlpha(float);
+    method public void setAntiAlias(boolean);
+    method public void setBlendMode(int);
+    method public void setColor(long);
+    method public void setColorFilter(androidx.compose.ui.graphics.ColorFilter?);
+    method public void setFilterQuality(int);
+    method public void setPathEffect(androidx.compose.ui.graphics.PathEffect?);
+    method public void setShader(android.graphics.Shader?);
+    method public void setStrokeCap(int);
+    method public void setStrokeJoin(int);
+    method public void setStrokeMiterLimit(float);
+    method public void setStrokeWidth(float);
+    method public void setStyle(int);
+    property public abstract float alpha;
+    property public abstract int blendMode;
+    property public abstract long color;
+    property public abstract androidx.compose.ui.graphics.ColorFilter? colorFilter;
+    property public abstract int filterQuality;
+    property public abstract boolean isAntiAlias;
+    property public abstract androidx.compose.ui.graphics.PathEffect? pathEffect;
+    property public abstract android.graphics.Shader? shader;
+    property public abstract int strokeCap;
+    property public abstract int strokeJoin;
+    property public abstract float strokeMiterLimit;
+    property public abstract float strokeWidth;
+    property public abstract int style;
+  }
+
+  public final class PaintKt {
+    method public static androidx.compose.ui.graphics.Paint Paint();
+    field public static final float DefaultAlpha = 1.0f;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class PaintingStyle {
+    field public static final androidx.compose.ui.graphics.PaintingStyle.Companion Companion;
+  }
+
+  public static final class PaintingStyle.Companion {
+    method public int getFill();
+    method public int getStroke();
+    property public final int Fill;
+    property public final int Stroke;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface Path {
+    method public void addArc(androidx.compose.ui.geometry.Rect oval, float startAngleDegrees, float sweepAngleDegrees);
+    method public void addArcRad(androidx.compose.ui.geometry.Rect oval, float startAngleRadians, float sweepAngleRadians);
+    method public void addOval(androidx.compose.ui.geometry.Rect oval);
+    method public void addPath(androidx.compose.ui.graphics.Path path, optional long offset);
+    method public void addRect(androidx.compose.ui.geometry.Rect rect);
+    method public void addRoundRect(androidx.compose.ui.geometry.RoundRect roundRect);
+    method public void arcTo(androidx.compose.ui.geometry.Rect rect, float startAngleDegrees, float sweepAngleDegrees, boolean forceMoveTo);
+    method public default void arcToRad(androidx.compose.ui.geometry.Rect rect, float startAngleRadians, float sweepAngleRadians, boolean forceMoveTo);
+    method public void close();
+    method public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3);
+    method public androidx.compose.ui.geometry.Rect getBounds();
+    method public int getFillType();
+    method public boolean isConvex();
+    method public boolean isEmpty();
+    method public void lineTo(float x, float y);
+    method public void moveTo(float x, float y);
+    method public boolean op(androidx.compose.ui.graphics.Path path1, androidx.compose.ui.graphics.Path path2, int operation);
+    method public void quadraticBezierTo(float x1, float y1, float x2, float y2);
+    method public void relativeCubicTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3);
+    method public void relativeLineTo(float dx, float dy);
+    method public void relativeMoveTo(float dx, float dy);
+    method public void relativeQuadraticBezierTo(float dx1, float dy1, float dx2, float dy2);
+    method public void reset();
+    method public default void rewind();
+    method public void setFillType(int);
+    method public default void transform(float[] matrix);
+    method public void translate(long offset);
+    property public abstract int fillType;
+    property public abstract boolean isConvex;
+    property public abstract boolean isEmpty;
+    field public static final androidx.compose.ui.graphics.Path.Companion Companion;
+  }
+
+  public static final class Path.Companion {
+    method public androidx.compose.ui.graphics.Path combine(int operation, androidx.compose.ui.graphics.Path path1, androidx.compose.ui.graphics.Path path2);
+  }
+
+  public interface PathEffect {
+    field public static final androidx.compose.ui.graphics.PathEffect.Companion Companion;
+  }
+
+  public static final class PathEffect.Companion {
+    method public androidx.compose.ui.graphics.PathEffect chainPathEffect(androidx.compose.ui.graphics.PathEffect outer, androidx.compose.ui.graphics.PathEffect inner);
+    method public androidx.compose.ui.graphics.PathEffect cornerPathEffect(float radius);
+    method public androidx.compose.ui.graphics.PathEffect dashPathEffect(float[] intervals, optional float phase);
+    method public androidx.compose.ui.graphics.PathEffect stampedPathEffect(androidx.compose.ui.graphics.Path shape, float advance, float phase, int style);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class PathFillType {
+    field public static final androidx.compose.ui.graphics.PathFillType.Companion Companion;
+  }
+
+  public static final class PathFillType.Companion {
+    method public int getEvenOdd();
+    method public int getNonZero();
+    property public final int EvenOdd;
+    property public final int NonZero;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface PathMeasure {
+    method public float getLength();
+    method public long getPosition(float distance);
+    method public boolean getSegment(float startDistance, float stopDistance, androidx.compose.ui.graphics.Path destination, optional boolean startWithMoveTo);
+    method public long getTangent(float distance);
+    method public void setPath(androidx.compose.ui.graphics.Path? path, boolean forceClosed);
+    property public abstract float length;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class PathOperation {
+    field public static final androidx.compose.ui.graphics.PathOperation.Companion Companion;
+  }
+
+  public static final class PathOperation.Companion {
+    method public int getDifference();
+    method public int getIntersect();
+    method public int getReverseDifference();
+    method public int getUnion();
+    method public int getXor();
+    property public final int Difference;
+    property public final int Intersect;
+    property public final int ReverseDifference;
+    property public final int Union;
+    property public final int Xor;
+  }
+
+  public final class PathOperationKt {
+    method @Deprecated public static int getDifference(androidx.compose.ui.graphics.PathOperation.Companion);
+    method @Deprecated public static int getIntersect(androidx.compose.ui.graphics.PathOperation.Companion);
+    method @Deprecated public static int getReverseDifference(androidx.compose.ui.graphics.PathOperation.Companion);
+    method @Deprecated public static int getUnion(androidx.compose.ui.graphics.PathOperation.Companion);
+    method @Deprecated public static int getXor(androidx.compose.ui.graphics.PathOperation.Companion);
+  }
+
+  public final class PixelMap {
+    ctor public PixelMap(int[] buffer, int width, int height, int bufferOffset, int stride);
+    method public operator long get(int x, int y);
+    method public int[] getBuffer();
+    method public int getBufferOffset();
+    method public int getHeight();
+    method public int getStride();
+    method public int getWidth();
+    property public final int[] buffer;
+    property public final int bufferOffset;
+    property public final int height;
+    property public final int stride;
+    property public final int width;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class PointMode {
+    field public static final androidx.compose.ui.graphics.PointMode.Companion Companion;
+  }
+
+  public static final class PointMode.Companion {
+    method public int getLines();
+    method public int getPoints();
+    method public int getPolygon();
+    property public final int Lines;
+    property public final int Points;
+    property public final int Polygon;
+  }
+
+  @androidx.compose.runtime.Immutable public final class RadialGradient extends androidx.compose.ui.graphics.ShaderBrush {
+    method public android.graphics.Shader createShader(long size);
+    property public long intrinsicSize;
+  }
+
+  public final class RectHelper_androidKt {
+    method @Deprecated public static android.graphics.Rect toAndroidRect(androidx.compose.ui.geometry.Rect);
+    method public static android.graphics.Rect toAndroidRect(androidx.compose.ui.unit.IntRect);
+    method public static android.graphics.RectF toAndroidRectF(androidx.compose.ui.geometry.Rect);
+    method public static androidx.compose.ui.unit.IntRect toComposeIntRect(android.graphics.Rect);
+    method public static androidx.compose.ui.geometry.Rect toComposeRect(android.graphics.Rect);
+  }
+
+  public final class RectangleShapeKt {
+    method public static androidx.compose.ui.graphics.Shape getRectangleShape();
+    property public static final androidx.compose.ui.graphics.Shape RectangleShape;
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class RenderEffect {
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) public final android.graphics.RenderEffect asAndroidRenderEffect();
+    method @RequiresApi(android.os.Build.VERSION_CODES.S) protected abstract android.graphics.RenderEffect createRenderEffect();
+    method public boolean isSupported();
+  }
+
+  public final class RenderEffectKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.graphics.BlurEffect BlurEffect(float radiusX, float radiusY, optional int edgeTreatment);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.graphics.OffsetEffect OffsetEffect(float offsetX, float offsetY);
+  }
+
+  @androidx.compose.runtime.Immutable public abstract class ShaderBrush extends androidx.compose.ui.graphics.Brush {
+    ctor public ShaderBrush();
+    method public final void applyTo(long size, androidx.compose.ui.graphics.Paint p, float alpha);
+    method public abstract android.graphics.Shader createShader(long size);
+  }
+
+  public final class ShaderKt {
+    method public static android.graphics.Shader ImageShader(androidx.compose.ui.graphics.ImageBitmap image, optional int tileModeX, optional int tileModeY);
+    method public static android.graphics.Shader LinearGradientShader(long from, long to, java.util.List<androidx.compose.ui.graphics.Color> colors, optional java.util.List<java.lang.Float>? colorStops, optional int tileMode);
+    method public static android.graphics.Shader RadialGradientShader(long center, float radius, java.util.List<androidx.compose.ui.graphics.Color> colors, optional java.util.List<java.lang.Float>? colorStops, optional int tileMode);
+    method public static android.graphics.Shader SweepGradientShader(long center, java.util.List<androidx.compose.ui.graphics.Color> colors, optional java.util.List<java.lang.Float>? colorStops);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Shadow {
+    ctor public Shadow(optional @androidx.compose.runtime.Stable long color, optional @androidx.compose.runtime.Stable long offset, optional @androidx.compose.runtime.Stable float blurRadius);
+    method public androidx.compose.ui.graphics.Shadow copy(optional long color, optional long offset, optional float blurRadius);
+    method public float getBlurRadius();
+    method public long getColor();
+    method public long getOffset();
+    property public final float blurRadius;
+    property public final long color;
+    property public final long offset;
+    field public static final androidx.compose.ui.graphics.Shadow.Companion Companion;
+  }
+
+  public static final class Shadow.Companion {
+    method public androidx.compose.ui.graphics.Shadow getNone();
+    property public final androidx.compose.ui.graphics.Shadow None;
+  }
+
+  public final class ShadowKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.graphics.Shadow lerp(androidx.compose.ui.graphics.Shadow start, androidx.compose.ui.graphics.Shadow stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public interface Shape {
+    method public androidx.compose.ui.graphics.Outline createOutline(long size, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.unit.Density density);
+  }
+
+  @androidx.compose.runtime.Immutable public final class SolidColor extends androidx.compose.ui.graphics.Brush {
+    ctor public SolidColor(long value);
+    method public void applyTo(long size, androidx.compose.ui.graphics.Paint p, float alpha);
+    method public long getValue();
+    property public final long value;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class StampedPathEffectStyle {
+    field public static final androidx.compose.ui.graphics.StampedPathEffectStyle.Companion Companion;
+  }
+
+  public static final class StampedPathEffectStyle.Companion {
+    method public int getMorph();
+    method public int getRotate();
+    method public int getTranslate();
+    property public final int Morph;
+    property public final int Rotate;
+    property public final int Translate;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class StrokeCap {
+    field public static final androidx.compose.ui.graphics.StrokeCap.Companion Companion;
+  }
+
+  public static final class StrokeCap.Companion {
+    method public int getButt();
+    method public int getRound();
+    method public int getSquare();
+    property public final int Butt;
+    property public final int Round;
+    property public final int Square;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class StrokeJoin {
+    field public static final androidx.compose.ui.graphics.StrokeJoin.Companion Companion;
+  }
+
+  public static final class StrokeJoin.Companion {
+    method public int getBevel();
+    method public int getMiter();
+    method public int getRound();
+    property public final int Bevel;
+    property public final int Miter;
+    property public final int Round;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SweepGradient extends androidx.compose.ui.graphics.ShaderBrush {
+    method public android.graphics.Shader createShader(long size);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TileMode {
+    field public static final androidx.compose.ui.graphics.TileMode.Companion Companion;
+  }
+
+  public static final class TileMode.Companion {
+    method public int getClamp();
+    method public int getDecal();
+    method public int getMirror();
+    method public int getRepeated();
+    property public final int Clamp;
+    property public final int Decal;
+    property public final int Mirror;
+    property public final int Repeated;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class VertexMode {
+    field public static final androidx.compose.ui.graphics.VertexMode.Companion Companion;
+  }
+
+  public static final class VertexMode.Companion {
+    method public int getTriangleFan();
+    method public int getTriangleStrip();
+    method public int getTriangles();
+    property public final int TriangleFan;
+    property public final int TriangleStrip;
+    property public final int Triangles;
+  }
+
+  public final class Vertices {
+    ctor public Vertices(int vertexMode, java.util.List<androidx.compose.ui.geometry.Offset> positions, java.util.List<androidx.compose.ui.geometry.Offset> textureCoordinates, java.util.List<androidx.compose.ui.graphics.Color> colors, java.util.List<java.lang.Integer> indices);
+    method public int[] getColors();
+    method public short[] getIndices();
+    method public float[] getPositions();
+    method public float[] getTextureCoordinates();
+    method public int getVertexMode();
+    property public final int[] colors;
+    property public final short[] indices;
+    property public final float[] positions;
+    property public final float[] textureCoordinates;
+    property public final int vertexMode;
+  }
+
+}
+
+package androidx.compose.ui.graphics.colorspace {
+
+  public abstract class Adaptation {
+    field public static final androidx.compose.ui.graphics.colorspace.Adaptation.Companion Companion;
+  }
+
+  public static final class Adaptation.Companion {
+    method public androidx.compose.ui.graphics.colorspace.Adaptation getBradford();
+    method public androidx.compose.ui.graphics.colorspace.Adaptation getCiecat02();
+    method public androidx.compose.ui.graphics.colorspace.Adaptation getVonKries();
+    property public final androidx.compose.ui.graphics.colorspace.Adaptation Bradford;
+    property public final androidx.compose.ui.graphics.colorspace.Adaptation Ciecat02;
+    property public final androidx.compose.ui.graphics.colorspace.Adaptation VonKries;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class ColorModel {
+    method public int getComponentCount();
+    property @androidx.compose.runtime.Stable public final int componentCount;
+    field public static final androidx.compose.ui.graphics.colorspace.ColorModel.Companion Companion;
+  }
+
+  public static final class ColorModel.Companion {
+    method public long getCmyk();
+    method public long getLab();
+    method public long getRgb();
+    method public long getXyz();
+    property public final long Cmyk;
+    property public final long Lab;
+    property public final long Rgb;
+    property public final long Xyz;
+  }
+
+  public abstract class ColorSpace {
+    ctor public ColorSpace(String name, long model);
+    method public final float[] fromXyz(float x, float y, float z);
+    method public abstract float[] fromXyz(float[] v);
+    method public final int getComponentCount();
+    method public abstract float getMaxValue(int component);
+    method public abstract float getMinValue(int component);
+    method public final long getModel();
+    method public final String getName();
+    method public boolean isSrgb();
+    method public abstract boolean isWideGamut();
+    method public final float[] toXyz(float r, float g, float b);
+    method public abstract float[] toXyz(float[] v);
+    property public final int componentCount;
+    property public boolean isSrgb;
+    property public abstract boolean isWideGamut;
+    property public final long model;
+    property public final String name;
+  }
+
+  public final class ColorSpaceKt {
+    method public static androidx.compose.ui.graphics.colorspace.ColorSpace adapt(androidx.compose.ui.graphics.colorspace.ColorSpace, androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint);
+    method public static androidx.compose.ui.graphics.colorspace.ColorSpace adapt(androidx.compose.ui.graphics.colorspace.ColorSpace, androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint, optional androidx.compose.ui.graphics.colorspace.Adaptation adaptation);
+    method public static androidx.compose.ui.graphics.colorspace.Connector connect(androidx.compose.ui.graphics.colorspace.ColorSpace, optional androidx.compose.ui.graphics.colorspace.ColorSpace destination, optional int intent);
+  }
+
+  public final class ColorSpaces {
+    method public androidx.compose.ui.graphics.colorspace.Rgb getAces();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getAcescg();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getAdobeRgb();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getBt2020();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getBt709();
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace getCieLab();
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace getCieXyz();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getDciP3();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getDisplayP3();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getExtendedSrgb();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getLinearExtendedSrgb();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getLinearSrgb();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getNtsc1953();
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace getOklab();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getProPhotoRgb();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getSmpteC();
+    method public androidx.compose.ui.graphics.colorspace.Rgb getSrgb();
+    method public androidx.compose.ui.graphics.colorspace.ColorSpace? match(float[] toXYZD50, androidx.compose.ui.graphics.colorspace.TransferParameters function);
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Aces;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Acescg;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb AdobeRgb;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Bt2020;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Bt709;
+    property public final androidx.compose.ui.graphics.colorspace.ColorSpace CieLab;
+    property public final androidx.compose.ui.graphics.colorspace.ColorSpace CieXyz;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb DciP3;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb DisplayP3;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb ExtendedSrgb;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb LinearExtendedSrgb;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb LinearSrgb;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Ntsc1953;
+    property public final androidx.compose.ui.graphics.colorspace.ColorSpace Oklab;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb ProPhotoRgb;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb SmpteC;
+    property public final androidx.compose.ui.graphics.colorspace.Rgb Srgb;
+    field public static final androidx.compose.ui.graphics.colorspace.ColorSpaces INSTANCE;
+  }
+
+  public class Connector {
+    method public final androidx.compose.ui.graphics.colorspace.ColorSpace getDestination();
+    method public final int getRenderIntent();
+    method public final androidx.compose.ui.graphics.colorspace.ColorSpace getSource();
+    method public final float[] transform(float r, float g, float b);
+    method public float[] transform(float[] v);
+    property public final androidx.compose.ui.graphics.colorspace.ColorSpace destination;
+    property public final int renderIntent;
+    property public final androidx.compose.ui.graphics.colorspace.ColorSpace source;
+  }
+
+  public final class Illuminant {
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getA();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getB();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getC();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getD50();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getD55();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getD60();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getD65();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getD75();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getE();
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint A;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint B;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint C;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint D50;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint D55;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint D60;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint D65;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint D75;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint E;
+    field public static final androidx.compose.ui.graphics.colorspace.Illuminant INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class RenderIntent {
+    field public static final androidx.compose.ui.graphics.colorspace.RenderIntent.Companion Companion;
+  }
+
+  public static final class RenderIntent.Companion {
+    method public int getAbsolute();
+    method public int getPerceptual();
+    method public int getRelative();
+    method public int getSaturation();
+    property public final int Absolute;
+    property public final int Perceptual;
+    property public final int Relative;
+    property public final int Saturation;
+  }
+
+  public final class Rgb extends androidx.compose.ui.graphics.colorspace.ColorSpace {
+    ctor public Rgb(String name, float[] toXYZ, androidx.compose.ui.graphics.colorspace.TransferParameters function);
+    ctor public Rgb(String name, float[] primaries, androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint, androidx.compose.ui.graphics.colorspace.TransferParameters function);
+    ctor public Rgb(String name, float[] primaries, androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint, double gamma);
+    ctor public Rgb(String name, float[] primaries, androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint, kotlin.jvm.functions.Function1<? super java.lang.Double,java.lang.Double> oetf, kotlin.jvm.functions.Function1<? super java.lang.Double,java.lang.Double> eotf, float min, float max);
+    ctor public Rgb(String name, float[] toXYZ, double gamma);
+    ctor public Rgb(String name, float[] toXYZ, kotlin.jvm.functions.Function1<? super java.lang.Double,java.lang.Double> oetf, kotlin.jvm.functions.Function1<? super java.lang.Double,java.lang.Double> eotf);
+    method public float[] fromLinear(float r, float g, float b);
+    method public float[] fromLinear(float[] v);
+    method public float[] fromXyz(float[] v);
+    method public kotlin.jvm.functions.Function1<java.lang.Double,java.lang.Double> getEotf();
+    method public float[] getInverseTransform();
+    method public float[] getInverseTransform(float[] inverseTransform);
+    method public float getMaxValue(int component);
+    method public float getMinValue(int component);
+    method public kotlin.jvm.functions.Function1<java.lang.Double,java.lang.Double> getOetf();
+    method public float[] getPrimaries();
+    method public float[] getPrimaries(float[] primaries);
+    method public androidx.compose.ui.graphics.colorspace.TransferParameters? getTransferParameters();
+    method public float[] getTransform();
+    method public float[] getTransform(float[] transform);
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint getWhitePoint();
+    method public boolean isWideGamut();
+    method public float[] toLinear(float r, float g, float b);
+    method public float[] toLinear(float[] v);
+    method public float[] toXyz(float[] v);
+    property public final kotlin.jvm.functions.Function1<java.lang.Double,java.lang.Double> eotf;
+    property public boolean isSrgb;
+    property public boolean isWideGamut;
+    property public final kotlin.jvm.functions.Function1<java.lang.Double,java.lang.Double> oetf;
+    property public final androidx.compose.ui.graphics.colorspace.TransferParameters? transferParameters;
+    property public final androidx.compose.ui.graphics.colorspace.WhitePoint whitePoint;
+  }
+
+  public final class TransferParameters {
+    ctor public TransferParameters(double gamma, double a, double b, double c, double d, optional double e, optional double f);
+    method public double component1();
+    method public double component2();
+    method public double component3();
+    method public double component4();
+    method public double component5();
+    method public double component6();
+    method public double component7();
+    method public androidx.compose.ui.graphics.colorspace.TransferParameters copy(double gamma, double a, double b, double c, double d, double e, double f);
+    method public double getA();
+    method public double getB();
+    method public double getC();
+    method public double getD();
+    method public double getE();
+    method public double getF();
+    method public double getGamma();
+    property public final double a;
+    property public final double b;
+    property public final double c;
+    property public final double d;
+    property public final double e;
+    property public final double f;
+    property public final double gamma;
+  }
+
+  public final class WhitePoint {
+    ctor public WhitePoint(float x, float y);
+    ctor public WhitePoint(float x, float y, float z);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.colorspace.WhitePoint copy(float x, float y);
+    method public float getX();
+    method public float getY();
+    property public final float x;
+    property public final float y;
+  }
+
+}
+
+package androidx.compose.ui.graphics.drawscope {
+
+  public final class CanvasDrawScope implements androidx.compose.ui.graphics.drawscope.DrawScope {
+    ctor public CanvasDrawScope();
+    method public inline void draw(androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.graphics.Canvas canvas, long size, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public void drawArc(androidx.compose.ui.graphics.Brush brush, float startAngle, float sweepAngle, boolean useCenter, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawArc(long color, float startAngle, float sweepAngle, boolean useCenter, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawCircle(androidx.compose.ui.graphics.Brush brush, float radius, long center, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawCircle(long color, float radius, long center, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawImage(androidx.compose.ui.graphics.ImageBitmap image, long topLeft, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method @Deprecated public void drawImage(androidx.compose.ui.graphics.ImageBitmap image, long srcOffset, long srcSize, long dstOffset, long dstSize, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawLine(androidx.compose.ui.graphics.Brush brush, long start, long end, float strokeWidth, int cap, androidx.compose.ui.graphics.PathEffect? pathEffect, float alpha, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawLine(long color, long start, long end, float strokeWidth, int cap, androidx.compose.ui.graphics.PathEffect? pathEffect, float alpha, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawOval(androidx.compose.ui.graphics.Brush brush, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawOval(long color, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawPath(androidx.compose.ui.graphics.Path path, androidx.compose.ui.graphics.Brush brush, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawPath(androidx.compose.ui.graphics.Path path, long color, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawPoints(java.util.List<androidx.compose.ui.geometry.Offset> points, int pointMode, androidx.compose.ui.graphics.Brush brush, float strokeWidth, int cap, androidx.compose.ui.graphics.PathEffect? pathEffect, float alpha, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawPoints(java.util.List<androidx.compose.ui.geometry.Offset> points, int pointMode, long color, float strokeWidth, int cap, androidx.compose.ui.graphics.PathEffect? pathEffect, float alpha, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawRect(androidx.compose.ui.graphics.Brush brush, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawRect(long color, long topLeft, long size, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawRoundRect(androidx.compose.ui.graphics.Brush brush, long topLeft, long size, long cornerRadius, float alpha, androidx.compose.ui.graphics.drawscope.DrawStyle style, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public void drawRoundRect(long color, long topLeft, long size, long cornerRadius, androidx.compose.ui.graphics.drawscope.DrawStyle style, float alpha, androidx.compose.ui.graphics.ColorFilter? colorFilter, int blendMode);
+    method public float getDensity();
+    method public androidx.compose.ui.graphics.drawscope.DrawContext getDrawContext();
+    method public float getFontScale();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    property public float density;
+    property public androidx.compose.ui.graphics.drawscope.DrawContext drawContext;
+    property public float fontScale;
+    property public androidx.compose.ui.unit.LayoutDirection layoutDirection;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ContentDrawScope extends androidx.compose.ui.graphics.drawscope.DrawScope {
+    method public void drawContent();
+  }
+
+  public interface DrawContext {
+    method public androidx.compose.ui.graphics.Canvas getCanvas();
+    method public long getSize();
+    method public androidx.compose.ui.graphics.drawscope.DrawTransform getTransform();
+    method public void setSize(long);
+    property public abstract androidx.compose.ui.graphics.Canvas canvas;
+    property public abstract long size;
+    property public abstract androidx.compose.ui.graphics.drawscope.DrawTransform transform;
+  }
+
+  @androidx.compose.ui.graphics.drawscope.DrawScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface DrawScope extends androidx.compose.ui.unit.Density {
+    method public void drawArc(androidx.compose.ui.graphics.Brush brush, float startAngle, float sweepAngle, boolean useCenter, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawArc(long color, float startAngle, float sweepAngle, boolean useCenter, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawCircle(androidx.compose.ui.graphics.Brush brush, optional float radius, optional long center, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawCircle(long color, optional float radius, optional long center, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawImage(androidx.compose.ui.graphics.ImageBitmap image, optional long topLeft, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method @Deprecated public void drawImage(androidx.compose.ui.graphics.ImageBitmap image, optional long srcOffset, optional long srcSize, optional long dstOffset, optional long dstSize, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public default void drawImage(androidx.compose.ui.graphics.ImageBitmap image, optional long srcOffset, optional long srcSize, optional long dstOffset, optional long dstSize, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode, optional int filterQuality);
+    method public void drawLine(androidx.compose.ui.graphics.Brush brush, long start, long end, optional float strokeWidth, optional int cap, optional androidx.compose.ui.graphics.PathEffect? pathEffect, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawLine(long color, long start, long end, optional float strokeWidth, optional int cap, optional androidx.compose.ui.graphics.PathEffect? pathEffect, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawOval(androidx.compose.ui.graphics.Brush brush, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawOval(long color, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawPath(androidx.compose.ui.graphics.Path path, androidx.compose.ui.graphics.Brush brush, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawPath(androidx.compose.ui.graphics.Path path, long color, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawPoints(java.util.List<androidx.compose.ui.geometry.Offset> points, int pointMode, androidx.compose.ui.graphics.Brush brush, optional float strokeWidth, optional int cap, optional androidx.compose.ui.graphics.PathEffect? pathEffect, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawPoints(java.util.List<androidx.compose.ui.geometry.Offset> points, int pointMode, long color, optional float strokeWidth, optional int cap, optional androidx.compose.ui.graphics.PathEffect? pathEffect, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawRect(androidx.compose.ui.graphics.Brush brush, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawRect(long color, optional long topLeft, optional long size, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawRoundRect(androidx.compose.ui.graphics.Brush brush, optional long topLeft, optional long size, optional long cornerRadius, optional float alpha, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public void drawRoundRect(long color, optional long topLeft, optional long size, optional long cornerRadius, optional androidx.compose.ui.graphics.drawscope.DrawStyle style, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter, optional int blendMode);
+    method public default long getCenter();
+    method public androidx.compose.ui.graphics.drawscope.DrawContext getDrawContext();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method public default long getSize();
+    property public default long center;
+    property public abstract androidx.compose.ui.graphics.drawscope.DrawContext drawContext;
+    property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
+    property public default long size;
+    field public static final androidx.compose.ui.graphics.drawscope.DrawScope.Companion Companion;
+  }
+
+  public static final class DrawScope.Companion {
+    method public int getDefaultBlendMode();
+    method public int getDefaultFilterQuality();
+    property public final int DefaultBlendMode;
+    property public final int DefaultFilterQuality;
+  }
+
+  public final class DrawScopeKt {
+    method public static inline void clipPath(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.graphics.Path path, optional int clipOp, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void clipRect(androidx.compose.ui.graphics.drawscope.DrawScope, optional float left, optional float top, optional float right, optional float bottom, optional int clipOp, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void drawIntoCanvas(androidx.compose.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.Canvas,kotlin.Unit> block);
+    method public static inline void inset(androidx.compose.ui.graphics.drawscope.DrawScope, float left, float top, float right, float bottom, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void inset(androidx.compose.ui.graphics.drawscope.DrawScope, optional float horizontal, optional float vertical, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void inset(androidx.compose.ui.graphics.drawscope.DrawScope, float inset, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void rotate(androidx.compose.ui.graphics.drawscope.DrawScope, float degrees, optional long pivot, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void rotateRad(androidx.compose.ui.graphics.drawscope.DrawScope, float radians, optional long pivot, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void scale(androidx.compose.ui.graphics.drawscope.DrawScope, float scaleX, float scaleY, optional long pivot, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void scale(androidx.compose.ui.graphics.drawscope.DrawScope, float scale, optional long pivot, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void translate(androidx.compose.ui.graphics.drawscope.DrawScope, optional float left, optional float top, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public static inline void withTransform(androidx.compose.ui.graphics.drawscope.DrawScope, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawTransform,kotlin.Unit> transformBlock, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> drawBlock);
+  }
+
+  @kotlin.DslMarker public @interface DrawScopeMarker {
+  }
+
+  public abstract sealed class DrawStyle {
+  }
+
+  @androidx.compose.ui.graphics.drawscope.DrawScopeMarker @kotlin.jvm.JvmDefaultWithCompatibility public interface DrawTransform {
+    method public void clipPath(androidx.compose.ui.graphics.Path path, optional int clipOp);
+    method public void clipRect(optional float left, optional float top, optional float right, optional float bottom, optional int clipOp);
+    method public default long getCenter();
+    method public long getSize();
+    method public void inset(float left, float top, float right, float bottom);
+    method public void rotate(float degrees, optional long pivot);
+    method public void scale(float scaleX, float scaleY, optional long pivot);
+    method public void transform(float[] matrix);
+    method public void translate(optional float left, optional float top);
+    property public default long center;
+    property public abstract long size;
+  }
+
+  public final class DrawTransformKt {
+    method public static inline void inset(androidx.compose.ui.graphics.drawscope.DrawTransform, float inset);
+    method public static inline void inset(androidx.compose.ui.graphics.drawscope.DrawTransform, optional float horizontal, optional float vertical);
+    method public static inline void rotateRad(androidx.compose.ui.graphics.drawscope.DrawTransform, float radians, optional long pivot);
+    method public static inline void scale(androidx.compose.ui.graphics.drawscope.DrawTransform, float scale, optional long pivot);
+  }
+
+  public final class Fill extends androidx.compose.ui.graphics.drawscope.DrawStyle {
+    field public static final androidx.compose.ui.graphics.drawscope.Fill INSTANCE;
+  }
+
+  public final class Stroke extends androidx.compose.ui.graphics.drawscope.DrawStyle {
+    ctor public Stroke(optional float width, optional float miter, optional int cap, optional int join, optional androidx.compose.ui.graphics.PathEffect? pathEffect);
+    method public int getCap();
+    method public int getJoin();
+    method public float getMiter();
+    method public androidx.compose.ui.graphics.PathEffect? getPathEffect();
+    method public float getWidth();
+    property public final int cap;
+    property public final int join;
+    property public final float miter;
+    property public final androidx.compose.ui.graphics.PathEffect? pathEffect;
+    property public final float width;
+    field public static final androidx.compose.ui.graphics.drawscope.Stroke.Companion Companion;
+    field public static final float DefaultMiter = 4.0f;
+    field public static final float HairlineWidth = 0.0f;
+  }
+
+  public static final class Stroke.Companion {
+    method public int getDefaultCap();
+    method public int getDefaultJoin();
+    property public final int DefaultCap;
+    property public final int DefaultJoin;
+  }
+
+}
+
+package androidx.compose.ui.graphics.painter {
+
+  public final class BitmapPainter extends androidx.compose.ui.graphics.painter.Painter {
+    ctor public BitmapPainter(androidx.compose.ui.graphics.ImageBitmap image, optional long srcOffset, optional long srcSize);
+    method public long getIntrinsicSize();
+    method protected void onDraw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    property public long intrinsicSize;
+  }
+
+  public final class BitmapPainterKt {
+    method public static androidx.compose.ui.graphics.painter.BitmapPainter BitmapPainter(androidx.compose.ui.graphics.ImageBitmap image, optional long srcOffset, optional long srcSize, optional int filterQuality);
+  }
+
+  public final class BrushPainter extends androidx.compose.ui.graphics.painter.Painter {
+    ctor public BrushPainter(androidx.compose.ui.graphics.Brush brush);
+    method public androidx.compose.ui.graphics.Brush getBrush();
+    method public long getIntrinsicSize();
+    method protected void onDraw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    property public final androidx.compose.ui.graphics.Brush brush;
+    property public long intrinsicSize;
+  }
+
+  public final class ColorPainter extends androidx.compose.ui.graphics.painter.Painter {
+    ctor public ColorPainter(long color);
+    method public long getColor();
+    method public long getIntrinsicSize();
+    method protected void onDraw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    property public final long color;
+    property public long intrinsicSize;
+  }
+
+  public abstract class Painter {
+    ctor public Painter();
+    method protected boolean applyAlpha(float alpha);
+    method protected boolean applyColorFilter(androidx.compose.ui.graphics.ColorFilter? colorFilter);
+    method protected boolean applyLayoutDirection(androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public final void draw(androidx.compose.ui.graphics.drawscope.DrawScope, long size, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter);
+    method public abstract long getIntrinsicSize();
+    method protected abstract void onDraw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    property public abstract long intrinsicSize;
+  }
+
+}
+
+package androidx.compose.ui.graphics.vector {
+
+  public final class PathBuilder {
+    ctor public PathBuilder();
+    method public androidx.compose.ui.graphics.vector.PathBuilder arcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float x1, float y1);
+    method public androidx.compose.ui.graphics.vector.PathBuilder arcToRelative(float a, float b, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float dx1, float dy1);
+    method public androidx.compose.ui.graphics.vector.PathBuilder close();
+    method public androidx.compose.ui.graphics.vector.PathBuilder curveTo(float x1, float y1, float x2, float y2, float x3, float y3);
+    method public androidx.compose.ui.graphics.vector.PathBuilder curveToRelative(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3);
+    method public java.util.List<androidx.compose.ui.graphics.vector.PathNode> getNodes();
+    method public androidx.compose.ui.graphics.vector.PathBuilder horizontalLineTo(float x);
+    method public androidx.compose.ui.graphics.vector.PathBuilder horizontalLineToRelative(float dx);
+    method public androidx.compose.ui.graphics.vector.PathBuilder lineTo(float x, float y);
+    method public androidx.compose.ui.graphics.vector.PathBuilder lineToRelative(float dx, float dy);
+    method public androidx.compose.ui.graphics.vector.PathBuilder moveTo(float x, float y);
+    method public androidx.compose.ui.graphics.vector.PathBuilder moveToRelative(float dx, float dy);
+    method public androidx.compose.ui.graphics.vector.PathBuilder quadTo(float x1, float y1, float x2, float y2);
+    method public androidx.compose.ui.graphics.vector.PathBuilder quadToRelative(float dx1, float dy1, float dx2, float dy2);
+    method public androidx.compose.ui.graphics.vector.PathBuilder reflectiveCurveTo(float x1, float y1, float x2, float y2);
+    method public androidx.compose.ui.graphics.vector.PathBuilder reflectiveCurveToRelative(float dx1, float dy1, float dx2, float dy2);
+    method public androidx.compose.ui.graphics.vector.PathBuilder reflectiveQuadTo(float x1, float y1);
+    method public androidx.compose.ui.graphics.vector.PathBuilder reflectiveQuadToRelative(float dx1, float dy1);
+    method public androidx.compose.ui.graphics.vector.PathBuilder verticalLineTo(float y);
+    method public androidx.compose.ui.graphics.vector.PathBuilder verticalLineToRelative(float dy);
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class PathNode {
+    method public final boolean isCurve();
+    method public final boolean isQuad();
+    property public final boolean isCurve;
+    property public final boolean isQuad;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.ArcTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.ArcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float arcStartX, float arcStartY);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public boolean component4();
+    method public boolean component5();
+    method public float component6();
+    method public float component7();
+    method public androidx.compose.ui.graphics.vector.PathNode.ArcTo copy(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float arcStartX, float arcStartY);
+    method public float getArcStartX();
+    method public float getArcStartY();
+    method public float getHorizontalEllipseRadius();
+    method public float getTheta();
+    method public float getVerticalEllipseRadius();
+    method public boolean isMoreThanHalf();
+    method public boolean isPositiveArc();
+    property public final float arcStartX;
+    property public final float arcStartY;
+    property public final float horizontalEllipseRadius;
+    property public final boolean isMoreThanHalf;
+    property public final boolean isPositiveArc;
+    property public final float theta;
+    property public final float verticalEllipseRadius;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.Close extends androidx.compose.ui.graphics.vector.PathNode {
+    field public static final androidx.compose.ui.graphics.vector.PathNode.Close INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.CurveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.CurveTo(float x1, float y1, float x2, float y2, float x3, float y3);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public float component5();
+    method public float component6();
+    method public androidx.compose.ui.graphics.vector.PathNode.CurveTo copy(float x1, float y1, float x2, float y2, float x3, float y3);
+    method public float getX1();
+    method public float getX2();
+    method public float getX3();
+    method public float getY1();
+    method public float getY2();
+    method public float getY3();
+    property public final float x1;
+    property public final float x2;
+    property public final float x3;
+    property public final float y1;
+    property public final float y2;
+    property public final float y3;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.HorizontalTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.HorizontalTo(float x);
+    method public float component1();
+    method public androidx.compose.ui.graphics.vector.PathNode.HorizontalTo copy(float x);
+    method public float getX();
+    property public final float x;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.LineTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.LineTo(float x, float y);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.LineTo copy(float x, float y);
+    method public float getX();
+    method public float getY();
+    property public final float x;
+    property public final float y;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.MoveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.MoveTo(float x, float y);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.MoveTo copy(float x, float y);
+    method public float getX();
+    method public float getY();
+    property public final float x;
+    property public final float y;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.QuadTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.QuadTo(float x1, float y1, float x2, float y2);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public androidx.compose.ui.graphics.vector.PathNode.QuadTo copy(float x1, float y1, float x2, float y2);
+    method public float getX1();
+    method public float getX2();
+    method public float getY1();
+    method public float getY2();
+    property public final float x1;
+    property public final float x2;
+    property public final float y1;
+    property public final float y2;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.ReflectiveCurveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.ReflectiveCurveTo(float x1, float y1, float x2, float y2);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public androidx.compose.ui.graphics.vector.PathNode.ReflectiveCurveTo copy(float x1, float y1, float x2, float y2);
+    method public float getX1();
+    method public float getX2();
+    method public float getY1();
+    method public float getY2();
+    property public final float x1;
+    property public final float x2;
+    property public final float y1;
+    property public final float y2;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.ReflectiveQuadTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.ReflectiveQuadTo(float x, float y);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.ReflectiveQuadTo copy(float x, float y);
+    method public float getX();
+    method public float getY();
+    property public final float x;
+    property public final float y;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeArcTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeArcTo(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float arcStartDx, float arcStartDy);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public boolean component4();
+    method public boolean component5();
+    method public float component6();
+    method public float component7();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeArcTo copy(float horizontalEllipseRadius, float verticalEllipseRadius, float theta, boolean isMoreThanHalf, boolean isPositiveArc, float arcStartDx, float arcStartDy);
+    method public float getArcStartDx();
+    method public float getArcStartDy();
+    method public float getHorizontalEllipseRadius();
+    method public float getTheta();
+    method public float getVerticalEllipseRadius();
+    method public boolean isMoreThanHalf();
+    method public boolean isPositiveArc();
+    property public final float arcStartDx;
+    property public final float arcStartDy;
+    property public final float horizontalEllipseRadius;
+    property public final boolean isMoreThanHalf;
+    property public final boolean isPositiveArc;
+    property public final float theta;
+    property public final float verticalEllipseRadius;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeCurveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeCurveTo(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public float component5();
+    method public float component6();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeCurveTo copy(float dx1, float dy1, float dx2, float dy2, float dx3, float dy3);
+    method public float getDx1();
+    method public float getDx2();
+    method public float getDx3();
+    method public float getDy1();
+    method public float getDy2();
+    method public float getDy3();
+    property public final float dx1;
+    property public final float dx2;
+    property public final float dx3;
+    property public final float dy1;
+    property public final float dy2;
+    property public final float dy3;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeHorizontalTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeHorizontalTo(float dx);
+    method public float component1();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeHorizontalTo copy(float dx);
+    method public float getDx();
+    property public final float dx;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeLineTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeLineTo(float dx, float dy);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeLineTo copy(float dx, float dy);
+    method public float getDx();
+    method public float getDy();
+    property public final float dx;
+    property public final float dy;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeMoveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeMoveTo(float dx, float dy);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeMoveTo copy(float dx, float dy);
+    method public float getDx();
+    method public float getDy();
+    property public final float dx;
+    property public final float dy;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeQuadTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeQuadTo(float dx1, float dy1, float dx2, float dy2);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeQuadTo copy(float dx1, float dy1, float dx2, float dy2);
+    method public float getDx1();
+    method public float getDx2();
+    method public float getDy1();
+    method public float getDy2();
+    property public final float dx1;
+    property public final float dx2;
+    property public final float dy1;
+    property public final float dy2;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeReflectiveCurveTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeReflectiveCurveTo(float dx1, float dy1, float dx2, float dy2);
+    method public float component1();
+    method public float component2();
+    method public float component3();
+    method public float component4();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeReflectiveCurveTo copy(float dx1, float dy1, float dx2, float dy2);
+    method public float getDx1();
+    method public float getDx2();
+    method public float getDy1();
+    method public float getDy2();
+    property public final float dx1;
+    property public final float dx2;
+    property public final float dy1;
+    property public final float dy2;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeReflectiveQuadTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeReflectiveQuadTo(float dx, float dy);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeReflectiveQuadTo copy(float dx, float dy);
+    method public float getDx();
+    method public float getDy();
+    property public final float dx;
+    property public final float dy;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.RelativeVerticalTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.RelativeVerticalTo(float dy);
+    method public float component1();
+    method public androidx.compose.ui.graphics.vector.PathNode.RelativeVerticalTo copy(float dy);
+    method public float getDy();
+    property public final float dy;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class PathNode.VerticalTo extends androidx.compose.ui.graphics.vector.PathNode {
+    ctor public PathNode.VerticalTo(float y);
+    method public float component1();
+    method public androidx.compose.ui.graphics.vector.PathNode.VerticalTo copy(float y);
+    method public float getY();
+    property public final float y;
+  }
+
+  public final class PathParser {
+    ctor public PathParser();
+    method public androidx.compose.ui.graphics.vector.PathParser addPathNodes(java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> nodes);
+    method public void clear();
+    method public androidx.compose.ui.graphics.vector.PathParser parsePathString(String pathData);
+    method public java.util.List<androidx.compose.ui.graphics.vector.PathNode> toNodes();
+    method public androidx.compose.ui.graphics.Path toPath(optional androidx.compose.ui.graphics.Path target);
+  }
+
+  public final class PathParserKt {
+    method public static androidx.compose.ui.graphics.Path toPath(java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode>, optional androidx.compose.ui.graphics.Path target);
+  }
+
+}
+
diff --git a/compose/ui/ui-graphics/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-graphics/api/restricted_1.5.0-beta01.txt
index 4aa03ab..33e27b1 100644
--- a/compose/ui/ui-graphics/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-graphics/api/restricted_1.5.0-beta01.txt
@@ -439,9 +439,6 @@
     method @kotlin.PublishedApi internal static float degrees(float radians);
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGraphicsApi {
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class FilterQuality {
     method public int getValue();
     property public final int value;
diff --git a/compose/ui/ui-graphics/build.gradle b/compose/ui/ui-graphics/build.gradle
index cb9f0da..3bb74e1 100644
--- a/compose/ui/ui-graphics/build.gradle
+++ b/compose/ui/ui-graphics/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-graphics/lint-baseline.xml b/compose/ui/ui-graphics/lint-baseline.xml
new file mode 100644
index 0000000..7a307a3
--- /dev/null
+++ b/compose/ui/ui-graphics/lint-baseline.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Double, Double> of &apos;getOetf&apos;."
+        errorLine1="    val oetf: (Double) -> Double = { x ->"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Double, Double> of &apos;getEotf&apos;."
+        errorLine1="    val eotf: (Double) -> Double = { x ->"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor Rgb has parameter &apos;oetf&apos; with type Function1&lt;? super Double, Double>."
+        errorLine1="        oetf: (Double) -> Double,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor Rgb has parameter &apos;eotf&apos; with type Function1&lt;? super Double, Double>."
+        errorLine1="        eotf: (Double) -> Double"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor Rgb has parameter &apos;oetf&apos; with type Function1&lt;? super Double, Double>."
+        errorLine1="        oetf: (Double) -> Double,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor Rgb has parameter &apos;eotf&apos; with type Function1&lt;? super Double, Double>."
+        errorLine1="        eotf: (Double) -> Double,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;outOfBounds&apos; with type Function1&lt;? super Integer, ? extends Boolean>."
+        errorLine1="        val outOfBounds: (Int) -> Boolean = { it &lt; 0 || it >= positions.size }"
+        errorLine2="                         ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt
index a86d530..d8f495cc 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Vertices.kt
@@ -34,7 +34,6 @@
     val indices: ShortArray
 
     init {
-        @Suppress("PrimitiveInLambda")
         val outOfBounds: (Int) -> Boolean = { it < 0 || it >= positions.size }
         if (textureCoordinates.size != positions.size)
             throw IllegalArgumentException("positions and textureCoordinates lengths must match.")
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt
index 4630cb9..4ded76b 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/colorspace/Rgb.kt
@@ -233,7 +233,6 @@
      * @see eotf
      * @see Rgb.transferParameters
      */
-    @Suppress("PrimitiveInLambda")
     val oetf: (Double) -> Double = { x ->
         oetfOrig(x).coerceIn(min.toDouble(), max.toDouble())
     }
@@ -263,7 +262,6 @@
      * @see oetf
      * @see Rgb.transferParameters
      */
-    @Suppress("PrimitiveInLambda")
     val eotf: (Double) -> Double = { x ->
         eotfOrig(x.coerceIn(min.toDouble(), max.toDouble()))
     }
@@ -384,9 +382,7 @@
         name: String,
         /*@Size(9)*/
         toXYZ: FloatArray,
-        @Suppress("PrimitiveInLambda")
         oetf: (Double) -> Double,
-        @Suppress("PrimitiveInLambda")
         eotf: (Double) -> Double
     ) : this(
         name,
@@ -440,9 +436,7 @@
         /*@Size(min = 6, max = 9)*/
         primaries: FloatArray,
         whitePoint: WhitePoint,
-        @Suppress("PrimitiveInLambda")
         oetf: (Double) -> Double,
-        @Suppress("PrimitiveInLambda")
         eotf: (Double) -> Double,
         min: Float,
         max: Float
diff --git a/compose/ui/ui-test-junit4/api/1.5.0-beta01.txt b/compose/ui/ui-test-junit4/api/1.5.0-beta01.txt
index 8f10178..2d6528b 100644
--- a/compose/ui/ui-test-junit4/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-test-junit4/api/1.5.0-beta01.txt
@@ -1,63 +1,7 @@
 // Signature format: 4.0
-package androidx.compose.ui.test {
-
-  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface AndroidComposeUiTest<A extends androidx.activity.ComponentActivity> extends androidx.compose.ui.test.ComposeUiTest {
-    method public A? getActivity();
-    property public abstract A? activity;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public abstract class AndroidComposeUiTestEnvironment<A extends androidx.activity.ComponentActivity> {
-    ctor public AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext);
-    method protected abstract A? getActivity();
-    method public final androidx.compose.ui.test.AndroidComposeUiTest<A> getTest();
-    method public final <R> R runTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,? extends R> block);
-    property protected abstract A? activity;
-    property public final androidx.compose.ui.test.AndroidComposeUiTest<A> test;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface ComposeUiTest extends androidx.compose.ui.test.SemanticsNodeInteractionsProvider {
-    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.ui.unit.Density getDensity();
-    method public androidx.compose.ui.test.MainTestClock getMainClock();
-    method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
-    method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
-    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
-    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
-    method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
-    method public void waitForIdle();
-    method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    property public abstract androidx.compose.ui.unit.Density density;
-    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
-  }
-
-  public final class ComposeUiTestKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilAtLeastOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilDoesNotExist(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilExactlyOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilNodeCount(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
-  }
-
-  public final class ComposeUiTest_androidKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.AndroidComposeUiTestEnvironment<A> AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function0<? extends A> activityProvider);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runEmptyComposeUiTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public final class StateRestorationTester {
-    ctor public StateRestorationTester(androidx.compose.ui.test.ComposeUiTest composeTest);
-    method public void emulateSaveAndRestore();
-    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
-  }
-
-}
-
 package androidx.compose.ui.test.junit4 {
 
   public final class AndroidComposeTestRule<R extends org.junit.rules.TestRule, A extends androidx.activity.ComponentActivity> implements androidx.compose.ui.test.junit4.ComposeContentTestRule {
-    ctor @androidx.compose.ui.test.ExperimentalTestApi public AndroidComposeTestRule(R activityRule, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
     ctor public AndroidComposeTestRule(R activityRule, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
     method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -74,10 +18,6 @@
     method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
     method public void waitForIdle();
     method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, long timeoutMillis);
     property public final A activity;
     property public final R activityRule;
     property public androidx.compose.ui.unit.Density density;
@@ -92,12 +32,8 @@
   public final class AndroidComposeTestRule_androidKt {
     method public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule();
     method public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
     method public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule();
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule(kotlin.coroutines.CoroutineContext effectContext);
     method public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule();
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface ComposeContentTestRule extends androidx.compose.ui.test.junit4.ComposeTestRule {
@@ -114,10 +50,6 @@
     method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
     method public void waitForIdle();
     method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
     property public abstract androidx.compose.ui.unit.Density density;
     property public abstract androidx.compose.ui.test.MainTestClock mainClock;
   }
diff --git a/compose/ui/ui-test-junit4/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-test-junit4/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..8f10178
--- /dev/null
+++ b/compose/ui/ui-test-junit4/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,140 @@
+// Signature format: 4.0
+package androidx.compose.ui.test {
+
+  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface AndroidComposeUiTest<A extends androidx.activity.ComponentActivity> extends androidx.compose.ui.test.ComposeUiTest {
+    method public A? getActivity();
+    property public abstract A? activity;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public abstract class AndroidComposeUiTestEnvironment<A extends androidx.activity.ComponentActivity> {
+    ctor public AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext);
+    method protected abstract A? getActivity();
+    method public final androidx.compose.ui.test.AndroidComposeUiTest<A> getTest();
+    method public final <R> R runTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,? extends R> block);
+    property protected abstract A? activity;
+    property public final androidx.compose.ui.test.AndroidComposeUiTest<A> test;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface ComposeUiTest extends androidx.compose.ui.test.SemanticsNodeInteractionsProvider {
+    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.test.MainTestClock getMainClock();
+    method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+    method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public void waitForIdle();
+    method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
+    property public abstract androidx.compose.ui.unit.Density density;
+    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
+  }
+
+  public final class ComposeUiTestKt {
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilAtLeastOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilDoesNotExist(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilExactlyOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilNodeCount(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
+  }
+
+  public final class ComposeUiTest_androidKt {
+    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.AndroidComposeUiTestEnvironment<A> AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function0<? extends A> activityProvider);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void runEmptyComposeUiTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public final class StateRestorationTester {
+    ctor public StateRestorationTester(androidx.compose.ui.test.ComposeUiTest composeTest);
+    method public void emulateSaveAndRestore();
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+  }
+
+}
+
+package androidx.compose.ui.test.junit4 {
+
+  public final class AndroidComposeTestRule<R extends org.junit.rules.TestRule, A extends androidx.activity.ComponentActivity> implements androidx.compose.ui.test.junit4.ComposeContentTestRule {
+    ctor @androidx.compose.ui.test.ExperimentalTestApi public AndroidComposeTestRule(R activityRule, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
+    ctor public AndroidComposeTestRule(R activityRule, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
+    method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
+    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public A getActivity();
+    method public R getActivityRule();
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.test.MainTestClock getMainClock();
+    method public androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodes(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
+    method public androidx.compose.ui.test.SemanticsNodeInteraction onNode(androidx.compose.ui.test.SemanticsMatcher matcher, boolean useUnmergedTree);
+    method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+    method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public void waitForIdle();
+    method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, long timeoutMillis);
+    property public final A activity;
+    property public final R activityRule;
+    property public androidx.compose.ui.unit.Density density;
+    property public androidx.compose.ui.test.MainTestClock mainClock;
+  }
+
+  @Deprecated public final class AndroidComposeTestRule.AndroidComposeStatement extends org.junit.runners.model.Statement {
+    ctor @Deprecated public AndroidComposeTestRule.AndroidComposeStatement(org.junit.runners.model.Statement base);
+    method @Deprecated public void evaluate();
+  }
+
+  public final class AndroidComposeTestRule_androidKt {
+    method public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule();
+    method public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
+    method public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule();
+    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule(kotlin.coroutines.CoroutineContext effectContext);
+    method public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule();
+    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ComposeContentTestRule extends androidx.compose.ui.test.junit4.ComposeTestRule {
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ComposeTestRule extends org.junit.rules.TestRule androidx.compose.ui.test.SemanticsNodeInteractionsProvider {
+    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.test.MainTestClock getMainClock();
+    method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
+    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+    method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
+    method public void waitForIdle();
+    method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
+    property public abstract androidx.compose.ui.unit.Density density;
+    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
+  }
+
+  public final class StateRestorationTester {
+    ctor public StateRestorationTester(androidx.compose.ui.test.junit4.ComposeContentTestRule composeTestRule);
+    method public void emulateSavedInstanceStateRestore();
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+  }
+
+}
+
+package androidx.compose.ui.test.junit4.android {
+
+  public final class ComposeNotIdleException extends java.lang.Exception {
+    ctor public ComposeNotIdleException(String? message, Throwable? cause);
+  }
+
+}
+
diff --git a/compose/ui/ui-test-junit4/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-test-junit4/api/restricted_1.5.0-beta01.txt
index 8f10178..2d6528b 100644
--- a/compose/ui/ui-test-junit4/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-test-junit4/api/restricted_1.5.0-beta01.txt
@@ -1,63 +1,7 @@
 // Signature format: 4.0
-package androidx.compose.ui.test {
-
-  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface AndroidComposeUiTest<A extends androidx.activity.ComponentActivity> extends androidx.compose.ui.test.ComposeUiTest {
-    method public A? getActivity();
-    property public abstract A? activity;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public abstract class AndroidComposeUiTestEnvironment<A extends androidx.activity.ComponentActivity> {
-    ctor public AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext);
-    method protected abstract A? getActivity();
-    method public final androidx.compose.ui.test.AndroidComposeUiTest<A> getTest();
-    method public final <R> R runTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,? extends R> block);
-    property protected abstract A? activity;
-    property public final androidx.compose.ui.test.AndroidComposeUiTest<A> test;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public sealed interface ComposeUiTest extends androidx.compose.ui.test.SemanticsNodeInteractionsProvider {
-    method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public androidx.compose.ui.unit.Density getDensity();
-    method public androidx.compose.ui.test.MainTestClock getMainClock();
-    method public void registerIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
-    method public <T> T runOnIdle(kotlin.jvm.functions.Function0<? extends T> action);
-    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
-    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
-    method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
-    method public void waitForIdle();
-    method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    property public abstract androidx.compose.ui.unit.Density density;
-    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
-  }
-
-  public final class ComposeUiTestKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilAtLeastOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilDoesNotExist(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilExactlyOneExists(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void waitUntilNodeCount(androidx.compose.ui.test.ComposeUiTest, androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
-  }
-
-  public final class ComposeUiTest_androidKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.AndroidComposeUiTestEnvironment<A> AndroidComposeUiTestEnvironment(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function0<? extends A> activityProvider);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> void runAndroidComposeUiTest(optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.AndroidComposeUiTest<A>,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runComposeUiTest(kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void runEmptyComposeUiTest(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.ComposeUiTest,kotlin.Unit> block);
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public final class StateRestorationTester {
-    ctor public StateRestorationTester(androidx.compose.ui.test.ComposeUiTest composeTest);
-    method public void emulateSaveAndRestore();
-    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
-  }
-
-}
-
 package androidx.compose.ui.test.junit4 {
 
   public final class AndroidComposeTestRule<R extends org.junit.rules.TestRule, A extends androidx.activity.ComponentActivity> implements androidx.compose.ui.test.junit4.ComposeContentTestRule {
-    ctor @androidx.compose.ui.test.ExperimentalTestApi public AndroidComposeTestRule(R activityRule, optional kotlin.coroutines.CoroutineContext effectContext, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
     ctor public AndroidComposeTestRule(R activityRule, kotlin.jvm.functions.Function1<? super R,? extends A> activityProvider);
     method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description description);
     method public suspend Object? awaitIdle(kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -74,10 +18,6 @@
     method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
     method public void waitForIdle();
     method public void waitUntil(long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, long timeoutMillis);
     property public final A activity;
     property public final R activityRule;
     property public androidx.compose.ui.unit.Density density;
@@ -92,12 +32,8 @@
   public final class AndroidComposeTestRule_androidKt {
     method public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule();
     method public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static <A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(Class<A> activityClass, optional kotlin.coroutines.CoroutineContext effectContext);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static inline <reified A extends androidx.activity.ComponentActivity> androidx.compose.ui.test.junit4.AndroidComposeTestRule<androidx.test.ext.junit.rules.ActivityScenarioRule<A>,A> createAndroidComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
     method public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule();
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeContentTestRule createComposeRule(kotlin.coroutines.CoroutineContext effectContext);
     method public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule();
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.junit4.ComposeTestRule createEmptyComposeRule(optional kotlin.coroutines.CoroutineContext effectContext);
   }
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface ComposeContentTestRule extends androidx.compose.ui.test.junit4.ComposeTestRule {
@@ -114,10 +50,6 @@
     method public void unregisterIdlingResource(androidx.compose.ui.test.IdlingResource idlingResource);
     method public void waitForIdle();
     method public void waitUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilAtLeastOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilDoesNotExist(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilExactlyOneExists(androidx.compose.ui.test.SemanticsMatcher matcher, optional long timeoutMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void waitUntilNodeCount(androidx.compose.ui.test.SemanticsMatcher matcher, int count, optional long timeoutMillis);
     property public abstract androidx.compose.ui.unit.Density density;
     property public abstract androidx.compose.ui.test.MainTestClock mainClock;
   }
diff --git a/compose/ui/ui-test-junit4/build.gradle b/compose/ui/ui-test-junit4/build.gradle
index d673d80..8bb1fb3 100644
--- a/compose/ui/ui-test-junit4/build.gradle
+++ b/compose/ui/ui-test-junit4/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-test-manifest/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-test-manifest/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/compose/ui/ui-test-manifest/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/compose/ui/ui-test/api/1.5.0-beta01.txt b/compose/ui/ui-test/api/1.5.0-beta01.txt
index 1060ce5..05d9e4e 100644
--- a/compose/ui/ui-test/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-test/api/1.5.0-beta01.txt
@@ -4,10 +4,7 @@
   public final class ActionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performClick(androidx.compose.ui.test.SemanticsNodeInteraction);
     method @Deprecated public static androidx.compose.ui.test.SemanticsNodeInteraction performGesture(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.GestureScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performKeyInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performMouseInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performMultiModalInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MultiModalInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performRotaryScrollInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollTo(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToIndex(androidx.compose.ui.test.SemanticsNodeInteraction, int index);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToKey(androidx.compose.ui.test.SemanticsNodeInteraction, Object key);
@@ -70,9 +67,6 @@
     ctor public ComposeTimeoutException(String? message);
   }
 
-  @kotlin.RequiresOptIn(message="This testing API is experimental and is likely to be changed or removed entirely") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTestApi {
-  }
-
   public final class FiltersKt {
     method public static androidx.compose.ui.test.SemanticsMatcher hasAnyAncestor(androidx.compose.ui.test.SemanticsMatcher matcher);
     method public static androidx.compose.ui.test.SemanticsMatcher hasAnyChild(androidx.compose.ui.test.SemanticsMatcher matcher);
@@ -133,7 +127,6 @@
   }
 
   public final class GestureScopeKt {
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void advanceEventTime(androidx.compose.ui.test.GestureScope, long durationMillis);
     method @Deprecated public static void cancel(androidx.compose.ui.test.GestureScope);
     method @Deprecated public static void click(androidx.compose.ui.test.GestureScope, optional long position);
     method @Deprecated public static void doubleClick(androidx.compose.ui.test.GestureScope, optional long position, optional long delayMillis);
@@ -168,13 +161,9 @@
     method @Deprecated public static void pinch(androidx.compose.ui.test.GestureScope, long start0, long end0, long start1, long end1, optional long durationMillis);
     method @Deprecated public static void swipe(androidx.compose.ui.test.GestureScope, long start, long end, optional long durationMillis);
     method @Deprecated public static void swipeDown(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeDown(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
     method @Deprecated public static void swipeLeft(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeLeft(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
     method @Deprecated public static void swipeRight(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeRight(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
     method @Deprecated public static void swipeUp(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeUp(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
     method @Deprecated public static void swipeWithVelocity(androidx.compose.ui.test.GestureScope, long start, long end, float endVelocity, optional long durationMillis);
     method @Deprecated public static void up(androidx.compose.ui.test.GestureScope, optional int pointerId);
   }
@@ -230,9 +219,6 @@
     property public default int width;
   }
 
-  @kotlin.RequiresOptIn(message="This is internal API for Compose modules that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalTestApi {
-  }
-
   @kotlin.jvm.JvmDefaultWithCompatibility public interface KeyInjectionScope extends androidx.compose.ui.test.InjectionScope {
     method public boolean isCapsLockOn();
     method public boolean isKeyDown(long key);
@@ -273,54 +259,7 @@
     property public abstract long currentTime;
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class MouseButton {
-    ctor public MouseButton(int buttonId);
-    method public int getButtonId();
-    property public final int buttonId;
-    field public static final androidx.compose.ui.test.MouseButton.Companion Companion;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public static final class MouseButton.Companion {
-    method public int getPrimary();
-    method public int getSecondary();
-    method public int getTertiary();
-    property public final int Primary;
-    property public final int Secondary;
-    property public final int Tertiary;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public interface MouseInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method public void cancel(optional long delayMillis);
-    method public void enter(optional long position, optional long delayMillis);
-    method public void exit(optional long position, optional long delayMillis);
-    method public long getCurrentPosition();
-    method public default void moveBy(long delta, optional long delayMillis);
-    method public void moveTo(long position, optional long delayMillis);
-    method public void press(optional int button);
-    method public void release(optional int button);
-    method public void scroll(float delta, optional int scrollWheel);
-    method public default void updatePointerBy(long delta);
-    method public void updatePointerTo(long position);
-    property public abstract long currentPosition;
-  }
-
-  public final class MouseInjectionScopeKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateAlong(androidx.compose.ui.test.MouseInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateBy(androidx.compose.ui.test.MouseInjectionScope, long delta, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateTo(androidx.compose.ui.test.MouseInjectionScope, long position, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void click(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void doubleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void dragAndDrop(androidx.compose.ui.test.MouseInjectionScope, long start, long end, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void longClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void rightClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void smoothScroll(androidx.compose.ui.test.MouseInjectionScope, float scrollAmount, optional long durationMillis, optional int scrollWheel);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void tripleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-  }
-
   public sealed interface MultiModalInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method @androidx.compose.ui.test.ExperimentalTestApi public void key(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void mouse(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void rotary(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
     method public void touch(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.TouchInjectionScope,kotlin.Unit> block);
   }
 
@@ -331,24 +270,6 @@
     method public static String printToString(androidx.compose.ui.test.SemanticsNodeInteractionCollection, optional int maxDepth);
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi public interface RotaryInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method public void rotateToScrollHorizontally(float horizontalScrollPixels);
-    method public void rotateToScrollVertically(float verticalScrollPixels);
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class ScrollWheel {
-    method public int getValue();
-    property public final int value;
-    field public static final androidx.compose.ui.test.ScrollWheel.Companion Companion;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public static final class ScrollWheel.Companion {
-    method public int getHorizontal();
-    method public int getVertical();
-    property public final int Horizontal;
-    property public final int Vertical;
-  }
-
   public final class SelectionResult {
     ctor public SelectionResult(java.util.List<androidx.compose.ui.semantics.SemanticsNode> selectedNodes, optional String? customErrorOnNoMatch);
     method public String? getCustomErrorOnNoMatch();
@@ -419,37 +340,10 @@
   public final class TestContext {
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlinx.coroutines.ExperimentalCoroutinesApi public final class TestMonotonicFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
-    ctor public TestMonotonicFrameClock(kotlinx.coroutines.CoroutineScope coroutineScope, optional long frameDelayNanos, optional kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> onPerformTraversals);
-    method @androidx.compose.ui.test.ExperimentalTestApi public kotlin.coroutines.ContinuationInterceptor getContinuationInterceptor();
-    method public long getFrameDelayNanos();
-    method public boolean getHasAwaiters();
-    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
-    property @androidx.compose.ui.test.ExperimentalTestApi public final kotlin.coroutines.ContinuationInterceptor continuationInterceptor;
-    property public final long frameDelayNanos;
-    property public final boolean hasAwaiters;
-  }
-
-  public final class TestMonotonicFrameClock_jvmKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static long getFrameDelayMillis(androidx.compose.ui.test.TestMonotonicFrameClock);
-  }
-
-  @androidx.compose.ui.test.InternalTestApi public interface TestOwner {
-    method public androidx.compose.ui.test.MainTestClock getMainClock();
-    method public java.util.Set<androidx.compose.ui.node.RootForTest> getRoots(boolean atLeastOneRootExpected);
-    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
-    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
-  }
-
-  public final class TestOwnerKt {
-    method @androidx.compose.ui.test.InternalTestApi public static androidx.compose.ui.test.TestContext createTestContext(androidx.compose.ui.test.TestOwner owner);
-  }
-
   public final class TextActionsKt {
     method public static void performImeAction(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static void performTextClearance(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static void performTextInput(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void performTextInputSelection(androidx.compose.ui.test.SemanticsNodeInteraction, long selection);
     method public static void performTextReplacement(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
   }
 
@@ -463,8 +357,6 @@
     method public default void moveBy(long delta, optional long delayMillis);
     method public default void moveTo(int pointerId, long position, optional long delayMillis);
     method public default void moveTo(long position, optional long delayMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public default void moveWithHistory(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<androidx.compose.ui.geometry.Offset> historicalCoordinates, optional long delayMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void moveWithHistoryMultiPointer(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<? extends java.util.List<androidx.compose.ui.geometry.Offset>> historicalCoordinates, optional long delayMillis);
     method public void up(optional int pointerId);
     method public default void updatePointerBy(int pointerId, long delta);
     method public void updatePointerTo(int pointerId, long position);
@@ -474,7 +366,6 @@
     method public static void click(androidx.compose.ui.test.TouchInjectionScope, optional long position);
     method public static void doubleClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long delayMillis);
     method public static void longClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void multiTouchSwipe(androidx.compose.ui.test.TouchInjectionScope, java.util.List<? extends kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset>> curves, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
     method public static void pinch(androidx.compose.ui.test.TouchInjectionScope, long start0, long end0, long start1, long end1, optional long durationMillis);
     method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
     method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, long start, long end, optional long durationMillis);
@@ -487,11 +378,3 @@
 
 }
 
-package androidx.compose.ui.test.internal {
-
-  @androidx.compose.ui.test.InternalTestApi public abstract class DelayPropagatingContinuationInterceptorWrapper extends kotlin.coroutines.AbstractCoroutineContextElement implements kotlin.coroutines.ContinuationInterceptor kotlinx.coroutines.Delay {
-    ctor public DelayPropagatingContinuationInterceptorWrapper(kotlin.coroutines.ContinuationInterceptor? wrappedInterceptor);
-  }
-
-}
-
diff --git a/compose/ui/ui-test/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-test/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..1060ce5
--- /dev/null
+++ b/compose/ui/ui-test/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,497 @@
+// Signature format: 4.0
+package androidx.compose.ui.test {
+
+  public final class ActionsKt {
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performClick(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method @Deprecated public static androidx.compose.ui.test.SemanticsNodeInteraction performGesture(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.GestureScope,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performKeyInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performMouseInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performMultiModalInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MultiModalInjectionScope,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performRotaryScrollInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollTo(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToIndex(androidx.compose.ui.test.SemanticsNodeInteraction, int index);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToKey(androidx.compose.ui.test.SemanticsNodeInteraction, Object key);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToNode(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performSemanticsAction(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> key);
+    method @Deprecated public static void performSemanticsAction(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> key);
+    method public static <T extends kotlin.Function<? extends java.lang.Boolean>> androidx.compose.ui.test.SemanticsNodeInteraction performSemanticsAction(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>> key, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> invocation);
+    method @Deprecated public static <T extends kotlin.Function<? extends java.lang.Boolean>> void performSemanticsAction(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<T>> key, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> invocation);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction performTouchInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.TouchInjectionScope,kotlin.Unit> block);
+  }
+
+  public final class AndroidImageHelpers_androidKt {
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static androidx.compose.ui.graphics.ImageBitmap captureToImage(androidx.compose.ui.test.SemanticsNodeInteraction);
+  }
+
+  public final class AssertionsKt {
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assert(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.test.SemanticsMatcher matcher, optional kotlin.jvm.functions.Function0<java.lang.String>? messagePrefixOnError);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection assertAll(androidx.compose.ui.test.SemanticsNodeInteractionCollection, androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection assertAny(androidx.compose.ui.test.SemanticsNodeInteractionCollection, androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertContentDescriptionContains(androidx.compose.ui.test.SemanticsNodeInteraction, String value, optional boolean substring, optional boolean ignoreCase);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertContentDescriptionEquals(androidx.compose.ui.test.SemanticsNodeInteraction, java.lang.String... values);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection assertCountEquals(androidx.compose.ui.test.SemanticsNodeInteractionCollection, int expectedSize);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHasClickAction(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHasNoClickAction(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsDisplayed(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsEnabled(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsFocused(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsNotDisplayed(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsNotEnabled(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsNotFocused(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsNotSelected(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsOff(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsOn(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsSelectable(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsSelected(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertIsToggleable(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertRangeInfoEquals(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.semantics.ProgressBarRangeInfo value);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTextContains(androidx.compose.ui.test.SemanticsNodeInteraction, String value, optional boolean substring, optional boolean ignoreCase);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTextEquals(androidx.compose.ui.test.SemanticsNodeInteraction, String![] values, optional boolean includeEditableText);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertValueEquals(androidx.compose.ui.test.SemanticsNodeInteraction, String value);
+  }
+
+  public final class BoundsAssertionsKt {
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsAtLeast(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinHeight);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertHeightIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedHeight);
+    method public static void assertIsEqualTo(float, float expected, String subject, optional float tolerance);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertLeftPositionInRootIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertPositionInRootIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedLeft, float expectedTop);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTopPositionInRootIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedTop);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTouchHeightIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedHeight);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertTouchWidthIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsAtLeast(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedMinWidth);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction assertWidthIsEqualTo(androidx.compose.ui.test.SemanticsNodeInteraction, float expectedWidth);
+    method public static float getAlignmentLinePosition(androidx.compose.ui.test.SemanticsNodeInteraction, androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public static androidx.compose.ui.unit.DpRect getBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.unit.DpRect getUnclippedBoundsInRoot(androidx.compose.ui.test.SemanticsNodeInteraction);
+  }
+
+  public final class ComposeTimeoutException extends java.lang.Throwable {
+    ctor public ComposeTimeoutException(String? message);
+  }
+
+  @kotlin.RequiresOptIn(message="This testing API is experimental and is likely to be changed or removed entirely") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTestApi {
+  }
+
+  public final class FiltersKt {
+    method public static androidx.compose.ui.test.SemanticsMatcher hasAnyAncestor(androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasAnyChild(androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasAnyDescendant(androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasAnySibling(androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasClickAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasContentDescription(String value, optional boolean substring, optional boolean ignoreCase);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasContentDescriptionExactly(java.lang.String... values);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasImeAction(int actionType);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasInsertTextAtCursorAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasNoClickAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasNoScrollAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasParent(androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasPerformImeAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasProgressBarRangeInfo(androidx.compose.ui.semantics.ProgressBarRangeInfo rangeInfo);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasRequestFocusAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasScrollAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasScrollToIndexAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasScrollToKeyAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasScrollToNodeAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasSetTextAction();
+    method public static androidx.compose.ui.test.SemanticsMatcher hasStateDescription(String value);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasTestTag(String testTag);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasText(String text, optional boolean substring, optional boolean ignoreCase);
+    method public static androidx.compose.ui.test.SemanticsMatcher hasTextExactly(String![] textValues, optional boolean includeEditableText);
+    method public static androidx.compose.ui.test.SemanticsMatcher isDialog();
+    method public static androidx.compose.ui.test.SemanticsMatcher isEnabled();
+    method public static androidx.compose.ui.test.SemanticsMatcher isFocusable();
+    method public static androidx.compose.ui.test.SemanticsMatcher isFocused();
+    method public static androidx.compose.ui.test.SemanticsMatcher isHeading();
+    method public static androidx.compose.ui.test.SemanticsMatcher isNotEnabled();
+    method public static androidx.compose.ui.test.SemanticsMatcher isNotFocusable();
+    method public static androidx.compose.ui.test.SemanticsMatcher isNotFocused();
+    method public static androidx.compose.ui.test.SemanticsMatcher isNotSelected();
+    method public static androidx.compose.ui.test.SemanticsMatcher isOff();
+    method public static androidx.compose.ui.test.SemanticsMatcher isOn();
+    method public static androidx.compose.ui.test.SemanticsMatcher isPopup();
+    method public static androidx.compose.ui.test.SemanticsMatcher isRoot();
+    method public static androidx.compose.ui.test.SemanticsMatcher isSelectable();
+    method public static androidx.compose.ui.test.SemanticsMatcher isSelected();
+    method public static androidx.compose.ui.test.SemanticsMatcher isToggleable();
+  }
+
+  public final class FindersKt {
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodesWithContentDescription(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String label, optional boolean substring, optional boolean ignoreCase, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodesWithTag(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String testTag, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodesWithText(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String text, optional boolean substring, optional boolean ignoreCase, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onNodeWithContentDescription(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String label, optional boolean substring, optional boolean ignoreCase, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onNodeWithTag(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String testTag, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onNodeWithText(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, String text, optional boolean substring, optional boolean ignoreCase, optional boolean useUnmergedTree);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onRoot(androidx.compose.ui.test.SemanticsNodeInteractionsProvider, optional boolean useUnmergedTree);
+  }
+
+  @Deprecated public final class GestureScope {
+    ctor @Deprecated public GestureScope(androidx.compose.ui.semantics.SemanticsNode node, androidx.compose.ui.test.TestContext testContext);
+    method @Deprecated public long getVisibleSize();
+    property @Deprecated public final long visibleSize;
+  }
+
+  public final class GestureScopeKt {
+    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void advanceEventTime(androidx.compose.ui.test.GestureScope, long durationMillis);
+    method @Deprecated public static void cancel(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static void click(androidx.compose.ui.test.GestureScope, optional long position);
+    method @Deprecated public static void doubleClick(androidx.compose.ui.test.GestureScope, optional long position, optional long delayMillis);
+    method @Deprecated public static void down(androidx.compose.ui.test.GestureScope, int pointerId, long position);
+    method @Deprecated public static void down(androidx.compose.ui.test.GestureScope, long position);
+    method @Deprecated public static inline float getBottom(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getBottomCenter(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getBottomLeft(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getBottomRight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getCenter(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getCenterLeft(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getCenterRight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline float getCenterX(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline float getCenterY(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline int getHeight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline float getLeft(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline float getRight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline float getTop(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getTopCenter(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getTopLeft(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static long getTopRight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static inline int getWidth(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static void longClick(androidx.compose.ui.test.GestureScope, optional long position, optional long durationMillis);
+    method @Deprecated public static void move(androidx.compose.ui.test.GestureScope);
+    method @Deprecated public static void moveBy(androidx.compose.ui.test.GestureScope, int pointerId, long delta);
+    method @Deprecated public static void moveBy(androidx.compose.ui.test.GestureScope, long delta);
+    method @Deprecated public static void movePointerBy(androidx.compose.ui.test.GestureScope, int pointerId, long delta);
+    method @Deprecated public static void movePointerTo(androidx.compose.ui.test.GestureScope, int pointerId, long position);
+    method @Deprecated public static void moveTo(androidx.compose.ui.test.GestureScope, int pointerId, long position);
+    method @Deprecated public static void moveTo(androidx.compose.ui.test.GestureScope, long position);
+    method @Deprecated public static long percentOffset(androidx.compose.ui.test.GestureScope, optional float x, optional float y);
+    method @Deprecated public static void pinch(androidx.compose.ui.test.GestureScope, long start0, long end0, long start1, long end1, optional long durationMillis);
+    method @Deprecated public static void swipe(androidx.compose.ui.test.GestureScope, long start, long end, optional long durationMillis);
+    method @Deprecated public static void swipeDown(androidx.compose.ui.test.GestureScope);
+    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeDown(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
+    method @Deprecated public static void swipeLeft(androidx.compose.ui.test.GestureScope);
+    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeLeft(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
+    method @Deprecated public static void swipeRight(androidx.compose.ui.test.GestureScope);
+    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeRight(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
+    method @Deprecated public static void swipeUp(androidx.compose.ui.test.GestureScope);
+    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeUp(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
+    method @Deprecated public static void swipeWithVelocity(androidx.compose.ui.test.GestureScope, long start, long end, float endVelocity, optional long durationMillis);
+    method @Deprecated public static void up(androidx.compose.ui.test.GestureScope, optional int pointerId);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface IdlingResource {
+    method public default String? getDiagnosticMessageIfBusy();
+    method public boolean isIdleNow();
+    property public abstract boolean isIdleNow;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface InjectionScope extends androidx.compose.ui.unit.Density {
+    method public void advanceEventTime(optional long durationMillis);
+    method public default float getBottom();
+    method public default long getBottomCenter();
+    method public default long getBottomLeft();
+    method public default long getBottomRight();
+    method public default long getCenter();
+    method public default long getCenterLeft();
+    method public default long getCenterRight();
+    method public default float getCenterX();
+    method public default float getCenterY();
+    method public default long getEventPeriodMillis();
+    method public default int getHeight();
+    method public default float getLeft();
+    method public default float getRight();
+    method public default float getTop();
+    method public default long getTopCenter();
+    method public default long getTopLeft();
+    method public default long getTopRight();
+    method public androidx.compose.ui.platform.ViewConfiguration getViewConfiguration();
+    method public long getVisibleSize();
+    method public default int getWidth();
+    method public default long percentOffset(optional float x, optional float y);
+    property public default float bottom;
+    property public default long bottomCenter;
+    property public default long bottomLeft;
+    property public default long bottomRight;
+    property public default long center;
+    property public default long centerLeft;
+    property public default long centerRight;
+    property public default float centerX;
+    property public default float centerY;
+    property public default long eventPeriodMillis;
+    property public default int height;
+    property public default float left;
+    property public default float right;
+    property public default float top;
+    property public default long topCenter;
+    property public default long topLeft;
+    property public default long topRight;
+    property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
+    property public abstract long visibleSize;
+    property public default int width;
+  }
+
+  @kotlin.RequiresOptIn(message="This is internal API for Compose modules that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalTestApi {
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface KeyInjectionScope extends androidx.compose.ui.test.InjectionScope {
+    method public boolean isCapsLockOn();
+    method public boolean isKeyDown(long key);
+    method public boolean isNumLockOn();
+    method public boolean isScrollLockOn();
+    method public void keyDown(long key);
+    method public void keyUp(long key);
+    property public abstract boolean isCapsLockOn;
+    property public abstract boolean isNumLockOn;
+    property public abstract boolean isScrollLockOn;
+  }
+
+  public final class KeyInjectionScopeKt {
+    method public static boolean isAltDown(androidx.compose.ui.test.KeyInjectionScope);
+    method public static boolean isCtrlDown(androidx.compose.ui.test.KeyInjectionScope);
+    method public static boolean isFnDown(androidx.compose.ui.test.KeyInjectionScope);
+    method public static boolean isMetaDown(androidx.compose.ui.test.KeyInjectionScope);
+    method public static boolean isShiftDown(androidx.compose.ui.test.KeyInjectionScope);
+    method public static void pressKey(androidx.compose.ui.test.KeyInjectionScope, long key, optional long pressDurationMillis);
+    method public static void withKeyDown(androidx.compose.ui.test.KeyInjectionScope, long key, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+    method public static void withKeyToggled(androidx.compose.ui.test.KeyInjectionScope, long key, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+    method public static void withKeysDown(androidx.compose.ui.test.KeyInjectionScope, java.util.List<androidx.compose.ui.input.key.Key> keys, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+    method public static void withKeysToggled(androidx.compose.ui.test.KeyInjectionScope, java.util.List<androidx.compose.ui.input.key.Key> keys, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+  }
+
+  public final class KeyInputHelpersKt {
+    method public static boolean performKeyPress(androidx.compose.ui.test.SemanticsNodeInteraction, android.view.KeyEvent keyEvent);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface MainTestClock {
+    method public void advanceTimeBy(long milliseconds, optional boolean ignoreFrameDuration);
+    method public void advanceTimeByFrame();
+    method public void advanceTimeUntil(optional long timeoutMillis, kotlin.jvm.functions.Function0<java.lang.Boolean> condition);
+    method public boolean getAutoAdvance();
+    method public long getCurrentTime();
+    method public void setAutoAdvance(boolean);
+    property public abstract boolean autoAdvance;
+    property public abstract long currentTime;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class MouseButton {
+    ctor public MouseButton(int buttonId);
+    method public int getButtonId();
+    property public final int buttonId;
+    field public static final androidx.compose.ui.test.MouseButton.Companion Companion;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public static final class MouseButton.Companion {
+    method public int getPrimary();
+    method public int getSecondary();
+    method public int getTertiary();
+    property public final int Primary;
+    property public final int Secondary;
+    property public final int Tertiary;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public interface MouseInjectionScope extends androidx.compose.ui.test.InjectionScope {
+    method public void cancel(optional long delayMillis);
+    method public void enter(optional long position, optional long delayMillis);
+    method public void exit(optional long position, optional long delayMillis);
+    method public long getCurrentPosition();
+    method public default void moveBy(long delta, optional long delayMillis);
+    method public void moveTo(long position, optional long delayMillis);
+    method public void press(optional int button);
+    method public void release(optional int button);
+    method public void scroll(float delta, optional int scrollWheel);
+    method public default void updatePointerBy(long delta);
+    method public void updatePointerTo(long position);
+    property public abstract long currentPosition;
+  }
+
+  public final class MouseInjectionScopeKt {
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateAlong(androidx.compose.ui.test.MouseInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, optional long durationMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateBy(androidx.compose.ui.test.MouseInjectionScope, long delta, optional long durationMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateTo(androidx.compose.ui.test.MouseInjectionScope, long position, optional long durationMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void click(androidx.compose.ui.test.MouseInjectionScope, optional long position);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void doubleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void dragAndDrop(androidx.compose.ui.test.MouseInjectionScope, long start, long end, optional long durationMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void longClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void rightClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void smoothScroll(androidx.compose.ui.test.MouseInjectionScope, float scrollAmount, optional long durationMillis, optional int scrollWheel);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void tripleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
+  }
+
+  public sealed interface MultiModalInjectionScope extends androidx.compose.ui.test.InjectionScope {
+    method @androidx.compose.ui.test.ExperimentalTestApi public void key(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void mouse(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void rotary(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
+    method public void touch(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.TouchInjectionScope,kotlin.Unit> block);
+  }
+
+  public final class OutputKt {
+    method public static void printToLog(androidx.compose.ui.test.SemanticsNodeInteraction, String tag, optional int maxDepth);
+    method public static void printToLog(androidx.compose.ui.test.SemanticsNodeInteractionCollection, String tag, optional int maxDepth);
+    method public static String printToString(androidx.compose.ui.test.SemanticsNodeInteraction, optional int maxDepth);
+    method public static String printToString(androidx.compose.ui.test.SemanticsNodeInteractionCollection, optional int maxDepth);
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public interface RotaryInjectionScope extends androidx.compose.ui.test.InjectionScope {
+    method public void rotateToScrollHorizontally(float horizontalScrollPixels);
+    method public void rotateToScrollVertically(float verticalScrollPixels);
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class ScrollWheel {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.compose.ui.test.ScrollWheel.Companion Companion;
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi public static final class ScrollWheel.Companion {
+    method public int getHorizontal();
+    method public int getVertical();
+    property public final int Horizontal;
+    property public final int Vertical;
+  }
+
+  public final class SelectionResult {
+    ctor public SelectionResult(java.util.List<androidx.compose.ui.semantics.SemanticsNode> selectedNodes, optional String? customErrorOnNoMatch);
+    method public String? getCustomErrorOnNoMatch();
+    method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> getSelectedNodes();
+    property public final String? customErrorOnNoMatch;
+    property public final java.util.List<androidx.compose.ui.semantics.SemanticsNode> selectedNodes;
+  }
+
+  public final class SelectorsKt {
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection filter(androidx.compose.ui.test.SemanticsNodeInteractionCollection, androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction filterToOne(androidx.compose.ui.test.SemanticsNodeInteractionCollection, androidx.compose.ui.test.SemanticsMatcher matcher);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onAncestors(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onChild(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onChildAt(androidx.compose.ui.test.SemanticsNodeInteraction, int index);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onChildren(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onFirst(androidx.compose.ui.test.SemanticsNodeInteractionCollection);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onLast(androidx.compose.ui.test.SemanticsNodeInteractionCollection);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onParent(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteraction onSibling(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static androidx.compose.ui.test.SemanticsNodeInteractionCollection onSiblings(androidx.compose.ui.test.SemanticsNodeInteraction);
+  }
+
+  public final class SemanticsMatcher {
+    ctor public SemanticsMatcher(String description, kotlin.jvm.functions.Function1<? super androidx.compose.ui.semantics.SemanticsNode,java.lang.Boolean> matcher);
+    method public infix androidx.compose.ui.test.SemanticsMatcher and(androidx.compose.ui.test.SemanticsMatcher other);
+    method public String getDescription();
+    method public boolean matches(androidx.compose.ui.semantics.SemanticsNode node);
+    method public boolean matchesAny(Iterable<androidx.compose.ui.semantics.SemanticsNode> nodes);
+    method public operator androidx.compose.ui.test.SemanticsMatcher not();
+    method public infix androidx.compose.ui.test.SemanticsMatcher or(androidx.compose.ui.test.SemanticsMatcher other);
+    property public final String description;
+    field public static final androidx.compose.ui.test.SemanticsMatcher.Companion Companion;
+  }
+
+  public static final class SemanticsMatcher.Companion {
+    method public <T> androidx.compose.ui.test.SemanticsMatcher expectValue(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T expectedValue);
+    method public <T> androidx.compose.ui.test.SemanticsMatcher keyIsDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+    method public <T> androidx.compose.ui.test.SemanticsMatcher keyNotDefined(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+  }
+
+  public final class SemanticsNodeInteraction {
+    ctor public SemanticsNodeInteraction(androidx.compose.ui.test.TestContext testContext, boolean useUnmergedTree, androidx.compose.ui.test.SemanticsMatcher matcher);
+    ctor public SemanticsNodeInteraction(androidx.compose.ui.test.TestContext testContext, boolean useUnmergedTree, androidx.compose.ui.test.SemanticsSelector selector);
+    method public void assertDoesNotExist();
+    method public androidx.compose.ui.test.SemanticsNodeInteraction assertExists(optional String? errorMessageOnFail);
+    method public androidx.compose.ui.semantics.SemanticsNode fetchSemanticsNode(optional String? errorMessageOnFail);
+  }
+
+  public final class SemanticsNodeInteractionCollection {
+    ctor public SemanticsNodeInteractionCollection(androidx.compose.ui.test.TestContext testContext, boolean useUnmergedTree, androidx.compose.ui.test.SemanticsMatcher matcher);
+    ctor public SemanticsNodeInteractionCollection(androidx.compose.ui.test.TestContext testContext, boolean useUnmergedTree, androidx.compose.ui.test.SemanticsSelector selector);
+    method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> fetchSemanticsNodes(optional boolean atLeastOneRootRequired, optional String? errorMessageOnFail);
+    method public operator androidx.compose.ui.test.SemanticsNodeInteraction get(int index);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface SemanticsNodeInteractionsProvider {
+    method public androidx.compose.ui.test.SemanticsNodeInteractionCollection onAllNodes(androidx.compose.ui.test.SemanticsMatcher matcher, optional boolean useUnmergedTree);
+    method public androidx.compose.ui.test.SemanticsNodeInteraction onNode(androidx.compose.ui.test.SemanticsMatcher matcher, optional boolean useUnmergedTree);
+  }
+
+  public final class SemanticsSelector {
+    ctor public SemanticsSelector(String description, boolean requiresExactlyOneNode, optional androidx.compose.ui.test.SemanticsSelector? chainedInputSelector, kotlin.jvm.functions.Function1<? super java.lang.Iterable<androidx.compose.ui.semantics.SemanticsNode>,androidx.compose.ui.test.SelectionResult> selector);
+    method public String getDescription();
+    method public androidx.compose.ui.test.SelectionResult map(Iterable<androidx.compose.ui.semantics.SemanticsNode> nodes, String errorOnFail);
+    property public final String description;
+  }
+
+  public final class TestContext {
+  }
+
+  @androidx.compose.ui.test.ExperimentalTestApi @kotlinx.coroutines.ExperimentalCoroutinesApi public final class TestMonotonicFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
+    ctor public TestMonotonicFrameClock(kotlinx.coroutines.CoroutineScope coroutineScope, optional long frameDelayNanos, optional kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> onPerformTraversals);
+    method @androidx.compose.ui.test.ExperimentalTestApi public kotlin.coroutines.ContinuationInterceptor getContinuationInterceptor();
+    method public long getFrameDelayNanos();
+    method public boolean getHasAwaiters();
+    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    property @androidx.compose.ui.test.ExperimentalTestApi public final kotlin.coroutines.ContinuationInterceptor continuationInterceptor;
+    property public final long frameDelayNanos;
+    property public final boolean hasAwaiters;
+  }
+
+  public final class TestMonotonicFrameClock_jvmKt {
+    method @androidx.compose.ui.test.ExperimentalTestApi public static long getFrameDelayMillis(androidx.compose.ui.test.TestMonotonicFrameClock);
+  }
+
+  @androidx.compose.ui.test.InternalTestApi public interface TestOwner {
+    method public androidx.compose.ui.test.MainTestClock getMainClock();
+    method public java.util.Set<androidx.compose.ui.node.RootForTest> getRoots(boolean atLeastOneRootExpected);
+    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
+    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
+  }
+
+  public final class TestOwnerKt {
+    method @androidx.compose.ui.test.InternalTestApi public static androidx.compose.ui.test.TestContext createTestContext(androidx.compose.ui.test.TestOwner owner);
+  }
+
+  public final class TextActionsKt {
+    method public static void performImeAction(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static void performTextClearance(androidx.compose.ui.test.SemanticsNodeInteraction);
+    method public static void performTextInput(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void performTextInputSelection(androidx.compose.ui.test.SemanticsNodeInteraction, long selection);
+    method public static void performTextReplacement(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface TouchInjectionScope extends androidx.compose.ui.test.InjectionScope {
+    method public void cancel(optional long delayMillis);
+    method public androidx.compose.ui.geometry.Offset? currentPosition(optional int pointerId);
+    method public void down(int pointerId, long position);
+    method public default void down(long position);
+    method public void move(optional long delayMillis);
+    method public default void moveBy(int pointerId, long delta, optional long delayMillis);
+    method public default void moveBy(long delta, optional long delayMillis);
+    method public default void moveTo(int pointerId, long position, optional long delayMillis);
+    method public default void moveTo(long position, optional long delayMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public default void moveWithHistory(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<androidx.compose.ui.geometry.Offset> historicalCoordinates, optional long delayMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public void moveWithHistoryMultiPointer(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<? extends java.util.List<androidx.compose.ui.geometry.Offset>> historicalCoordinates, optional long delayMillis);
+    method public void up(optional int pointerId);
+    method public default void updatePointerBy(int pointerId, long delta);
+    method public void updatePointerTo(int pointerId, long position);
+  }
+
+  public final class TouchInjectionScopeKt {
+    method public static void click(androidx.compose.ui.test.TouchInjectionScope, optional long position);
+    method public static void doubleClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long delayMillis);
+    method public static void longClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long durationMillis);
+    method @androidx.compose.ui.test.ExperimentalTestApi public static void multiTouchSwipe(androidx.compose.ui.test.TouchInjectionScope, java.util.List<? extends kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset>> curves, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
+    method public static void pinch(androidx.compose.ui.test.TouchInjectionScope, long start0, long end0, long start1, long end1, optional long durationMillis);
+    method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
+    method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, long start, long end, optional long durationMillis);
+    method public static void swipeDown(androidx.compose.ui.test.TouchInjectionScope, optional float startY, optional float endY, optional long durationMillis);
+    method public static void swipeLeft(androidx.compose.ui.test.TouchInjectionScope, optional float startX, optional float endX, optional long durationMillis);
+    method public static void swipeRight(androidx.compose.ui.test.TouchInjectionScope, optional float startX, optional float endX, optional long durationMillis);
+    method public static void swipeUp(androidx.compose.ui.test.TouchInjectionScope, optional float startY, optional float endY, optional long durationMillis);
+    method public static void swipeWithVelocity(androidx.compose.ui.test.TouchInjectionScope, long start, long end, float endVelocity, optional long durationMillis);
+  }
+
+}
+
+package androidx.compose.ui.test.internal {
+
+  @androidx.compose.ui.test.InternalTestApi public abstract class DelayPropagatingContinuationInterceptorWrapper extends kotlin.coroutines.AbstractCoroutineContextElement implements kotlin.coroutines.ContinuationInterceptor kotlinx.coroutines.Delay {
+    ctor public DelayPropagatingContinuationInterceptorWrapper(kotlin.coroutines.ContinuationInterceptor? wrappedInterceptor);
+  }
+
+}
+
diff --git a/compose/ui/ui-test/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-test/api/restricted_1.5.0-beta01.txt
index 73b5bac..f338e1a 100644
--- a/compose/ui/ui-test/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-test/api/restricted_1.5.0-beta01.txt
@@ -4,10 +4,7 @@
   public final class ActionsKt {
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performClick(androidx.compose.ui.test.SemanticsNodeInteraction);
     method @Deprecated public static androidx.compose.ui.test.SemanticsNodeInteraction performGesture(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.GestureScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performKeyInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performMouseInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performMultiModalInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MultiModalInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static androidx.compose.ui.test.SemanticsNodeInteraction performRotaryScrollInput(androidx.compose.ui.test.SemanticsNodeInteraction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollTo(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToIndex(androidx.compose.ui.test.SemanticsNodeInteraction, int index);
     method public static androidx.compose.ui.test.SemanticsNodeInteraction performScrollToKey(androidx.compose.ui.test.SemanticsNodeInteraction, Object key);
@@ -70,9 +67,6 @@
     ctor public ComposeTimeoutException(String? message);
   }
 
-  @kotlin.RequiresOptIn(message="This testing API is experimental and is likely to be changed or removed entirely") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTestApi {
-  }
-
   public final class FiltersKt {
     method public static androidx.compose.ui.test.SemanticsMatcher hasAnyAncestor(androidx.compose.ui.test.SemanticsMatcher matcher);
     method public static androidx.compose.ui.test.SemanticsMatcher hasAnyChild(androidx.compose.ui.test.SemanticsMatcher matcher);
@@ -134,7 +128,6 @@
   }
 
   public final class GestureScopeKt {
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void advanceEventTime(androidx.compose.ui.test.GestureScope, long durationMillis);
     method @Deprecated public static void cancel(androidx.compose.ui.test.GestureScope);
     method @Deprecated public static void click(androidx.compose.ui.test.GestureScope, optional long position);
     method @Deprecated public static void doubleClick(androidx.compose.ui.test.GestureScope, optional long position, optional long delayMillis);
@@ -169,13 +162,9 @@
     method @Deprecated public static void pinch(androidx.compose.ui.test.GestureScope, long start0, long end0, long start1, long end1, optional long durationMillis);
     method @Deprecated public static void swipe(androidx.compose.ui.test.GestureScope, long start, long end, optional long durationMillis);
     method @Deprecated public static void swipeDown(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeDown(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
     method @Deprecated public static void swipeLeft(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeLeft(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
     method @Deprecated public static void swipeRight(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeRight(androidx.compose.ui.test.GestureScope, optional float startX, optional float endX, optional long durationMillis);
     method @Deprecated public static void swipeUp(androidx.compose.ui.test.GestureScope);
-    method @Deprecated @androidx.compose.ui.test.ExperimentalTestApi public static void swipeUp(androidx.compose.ui.test.GestureScope, optional float startY, optional float endY, optional long durationMillis);
     method @Deprecated public static void swipeWithVelocity(androidx.compose.ui.test.GestureScope, long start, long end, float endVelocity, optional long durationMillis);
     method @Deprecated public static void up(androidx.compose.ui.test.GestureScope, optional int pointerId);
   }
@@ -231,9 +220,6 @@
     property public default int width;
   }
 
-  @kotlin.RequiresOptIn(message="This is internal API for Compose modules that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalTestApi {
-  }
-
   @kotlin.jvm.JvmDefaultWithCompatibility public interface KeyInjectionScope extends androidx.compose.ui.test.InjectionScope {
     method public boolean isCapsLockOn();
     method public boolean isKeyDown(long key);
@@ -274,54 +260,7 @@
     property public abstract long currentTime;
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class MouseButton {
-    ctor public MouseButton(int buttonId);
-    method public int getButtonId();
-    property public final int buttonId;
-    field public static final androidx.compose.ui.test.MouseButton.Companion Companion;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public static final class MouseButton.Companion {
-    method public int getPrimary();
-    method public int getSecondary();
-    method public int getTertiary();
-    property public final int Primary;
-    property public final int Secondary;
-    property public final int Tertiary;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public interface MouseInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method public void cancel(optional long delayMillis);
-    method public void enter(optional long position, optional long delayMillis);
-    method public void exit(optional long position, optional long delayMillis);
-    method public long getCurrentPosition();
-    method public default void moveBy(long delta, optional long delayMillis);
-    method public void moveTo(long position, optional long delayMillis);
-    method public void press(optional int button);
-    method public void release(optional int button);
-    method public void scroll(float delta, optional int scrollWheel);
-    method public default void updatePointerBy(long delta);
-    method public void updatePointerTo(long position);
-    property public abstract long currentPosition;
-  }
-
-  public final class MouseInjectionScopeKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateAlong(androidx.compose.ui.test.MouseInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateBy(androidx.compose.ui.test.MouseInjectionScope, long delta, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void animateTo(androidx.compose.ui.test.MouseInjectionScope, long position, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void click(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void doubleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void dragAndDrop(androidx.compose.ui.test.MouseInjectionScope, long start, long end, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void longClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void rightClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void smoothScroll(androidx.compose.ui.test.MouseInjectionScope, float scrollAmount, optional long durationMillis, optional int scrollWheel);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void tripleClick(androidx.compose.ui.test.MouseInjectionScope, optional long position);
-  }
-
   public sealed interface MultiModalInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method @androidx.compose.ui.test.ExperimentalTestApi public void key(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.KeyInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void mouse(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.MouseInjectionScope,kotlin.Unit> block);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void rotary(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.RotaryInjectionScope,kotlin.Unit> block);
     method public void touch(kotlin.jvm.functions.Function1<? super androidx.compose.ui.test.TouchInjectionScope,kotlin.Unit> block);
   }
 
@@ -332,24 +271,6 @@
     method public static String printToString(androidx.compose.ui.test.SemanticsNodeInteractionCollection, optional int maxDepth);
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi public interface RotaryInjectionScope extends androidx.compose.ui.test.InjectionScope {
-    method public void rotateToScrollHorizontally(float horizontalScrollPixels);
-    method public void rotateToScrollVertically(float verticalScrollPixels);
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlin.jvm.JvmInline public final value class ScrollWheel {
-    method public int getValue();
-    property public final int value;
-    field public static final androidx.compose.ui.test.ScrollWheel.Companion Companion;
-  }
-
-  @androidx.compose.ui.test.ExperimentalTestApi public static final class ScrollWheel.Companion {
-    method public int getHorizontal();
-    method public int getVertical();
-    property public final int Horizontal;
-    property public final int Vertical;
-  }
-
   public final class SelectionResult {
     ctor public SelectionResult(java.util.List<androidx.compose.ui.semantics.SemanticsNode> selectedNodes, optional String? customErrorOnNoMatch);
     method public String? getCustomErrorOnNoMatch();
@@ -420,37 +341,10 @@
   public final class TestContext {
   }
 
-  @androidx.compose.ui.test.ExperimentalTestApi @kotlinx.coroutines.ExperimentalCoroutinesApi public final class TestMonotonicFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
-    ctor public TestMonotonicFrameClock(kotlinx.coroutines.CoroutineScope coroutineScope, optional long frameDelayNanos, optional kotlin.jvm.functions.Function1<? super java.lang.Long,kotlin.Unit> onPerformTraversals);
-    method @androidx.compose.ui.test.ExperimentalTestApi public kotlin.coroutines.ContinuationInterceptor getContinuationInterceptor();
-    method public long getFrameDelayNanos();
-    method public boolean getHasAwaiters();
-    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
-    property @androidx.compose.ui.test.ExperimentalTestApi public final kotlin.coroutines.ContinuationInterceptor continuationInterceptor;
-    property public final long frameDelayNanos;
-    property public final boolean hasAwaiters;
-  }
-
-  public final class TestMonotonicFrameClock_jvmKt {
-    method @androidx.compose.ui.test.ExperimentalTestApi public static long getFrameDelayMillis(androidx.compose.ui.test.TestMonotonicFrameClock);
-  }
-
-  @androidx.compose.ui.test.InternalTestApi public interface TestOwner {
-    method public androidx.compose.ui.test.MainTestClock getMainClock();
-    method public java.util.Set<androidx.compose.ui.node.RootForTest> getRoots(boolean atLeastOneRootExpected);
-    method public <T> T runOnUiThread(kotlin.jvm.functions.Function0<? extends T> action);
-    property public abstract androidx.compose.ui.test.MainTestClock mainClock;
-  }
-
-  public final class TestOwnerKt {
-    method @androidx.compose.ui.test.InternalTestApi public static androidx.compose.ui.test.TestContext createTestContext(androidx.compose.ui.test.TestOwner owner);
-  }
-
   public final class TextActionsKt {
     method public static void performImeAction(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static void performTextClearance(androidx.compose.ui.test.SemanticsNodeInteraction);
     method public static void performTextInput(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void performTextInputSelection(androidx.compose.ui.test.SemanticsNodeInteraction, long selection);
     method public static void performTextReplacement(androidx.compose.ui.test.SemanticsNodeInteraction, String text);
   }
 
@@ -464,8 +358,6 @@
     method public default void moveBy(long delta, optional long delayMillis);
     method public default void moveTo(int pointerId, long position, optional long delayMillis);
     method public default void moveTo(long position, optional long delayMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public default void moveWithHistory(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<androidx.compose.ui.geometry.Offset> historicalCoordinates, optional long delayMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public void moveWithHistoryMultiPointer(java.util.List<java.lang.Long> relativeHistoricalTimes, java.util.List<? extends java.util.List<androidx.compose.ui.geometry.Offset>> historicalCoordinates, optional long delayMillis);
     method public void up(optional int pointerId);
     method public default void updatePointerBy(int pointerId, long delta);
     method public void updatePointerTo(int pointerId, long position);
@@ -475,7 +367,6 @@
     method public static void click(androidx.compose.ui.test.TouchInjectionScope, optional long position);
     method public static void doubleClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long delayMillis);
     method public static void longClick(androidx.compose.ui.test.TouchInjectionScope, optional long position, optional long durationMillis);
-    method @androidx.compose.ui.test.ExperimentalTestApi public static void multiTouchSwipe(androidx.compose.ui.test.TouchInjectionScope, java.util.List<? extends kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset>> curves, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
     method public static void pinch(androidx.compose.ui.test.TouchInjectionScope, long start0, long end0, long start1, long end1, optional long durationMillis);
     method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, kotlin.jvm.functions.Function1<? super java.lang.Long,androidx.compose.ui.geometry.Offset> curve, long durationMillis, optional java.util.List<java.lang.Long> keyTimes);
     method public static void swipe(androidx.compose.ui.test.TouchInjectionScope, long start, long end, optional long durationMillis);
@@ -488,11 +379,3 @@
 
 }
 
-package androidx.compose.ui.test.internal {
-
-  @androidx.compose.ui.test.InternalTestApi public abstract class DelayPropagatingContinuationInterceptorWrapper extends kotlin.coroutines.AbstractCoroutineContextElement implements kotlin.coroutines.ContinuationInterceptor kotlinx.coroutines.Delay {
-    ctor public DelayPropagatingContinuationInterceptorWrapper(kotlin.coroutines.ContinuationInterceptor? wrappedInterceptor);
-  }
-
-}
-
diff --git a/compose/ui/ui-test/build.gradle b/compose/ui/ui-test/build.gradle
index 49ee771..fa5ac5f 100644
--- a/compose/ui/ui-test/build.gradle
+++ b/compose/ui/ui-test/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-test/lint-baseline.xml b/compose/ui/ui-test/lint-baseline.xml
index f610545..93403e3 100644
--- a/compose/ui/ui-test/lint-baseline.xml
+++ b/compose/ui/ui-test/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -10,4 +10,85 @@
             file="src/androidMain/kotlin/androidx/compose/ui/test/android/WindowCapture.android.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method animateAlong has parameter &apos;curve&apos; with type Function1&lt;? super Long, Offset>."
+        errorLine1="    curve: (Long) -> Offset,"
+        errorLine2="           ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/MouseInjectionScope.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor TestMonotonicFrameClock has parameter &apos;onPerformTraversals&apos; with type Function1&lt;? super Long, Unit>."
+        errorLine1="    private val onPerformTraversals: (Long) -> Unit = {}"
+        errorLine2="                                     ~~~~~~~~~~~~~~">
+        <location
+            file="src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;toRun&apos; with type List&lt;Function1&lt;? super Long, ? extends Unit>>."
+        errorLine1="            val toRun = synchronized(lock) {"
+        errorLine2="            ^">
+        <location
+            file="src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method swipe has parameter &apos;curve&apos; with type Function1&lt;? super Long, Offset>."
+        errorLine1="    curve: (Long) -> Offset,"
+        errorLine2="           ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, Offset> of &apos;generateFunction&apos;."
+        errorLine1="    fun generateFunction(): (Long) -> Offset {"
+        errorLine2="                            ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;fx&apos; with type Function1&lt;? super Long, ? extends Float>."
+        errorLine1="        val fx = createFunctionForVelocity(vx, Offset::x)"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;fy&apos; with type Function1&lt;? super Long, ? extends Float>."
+        errorLine1="        val fy = createFunctionForVelocity(vy, Offset::y)"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method createFunctionForVelocity has parameter &apos;value&apos; with type Function1&lt;? super Offset, Float>."
+        errorLine1="        value: Offset.() -> Float"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Long, Float> of &apos;createFunctionForVelocity&apos;."
+        errorLine1="    ): (Long) -> Float {"
+        errorLine2="       ~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MouseInjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MouseInjectionScope.kt
index 9c1fb62..df6dc232 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MouseInjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/MouseInjectionScope.kt
@@ -428,7 +428,6 @@
  */
 @ExperimentalTestApi
 fun MouseInjectionScope.animateAlong(
-    @Suppress("PrimitiveInLambda")
     curve: (Long) -> Offset,
     durationMillis: Long = DefaultMouseGestureDurationMillis
 ) {
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TextActions.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TextActions.kt
index dcc6467..53c81a7 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TextActions.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TextActions.kt
@@ -53,7 +53,6 @@
 @ExperimentalTestApi
 fun SemanticsNodeInteraction.performTextInputSelection(selection: TextRange) {
     getNodeAndFocus()
-    @Suppress("PrimitiveInLambda")
     performSemanticsAction(SemanticsActions.SetSelection) {
         // Pass true as the last parameter since this range is relative to the text before any
         // VisualTransformation is applied.
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
index e905e27..d1f5822 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
@@ -455,7 +455,6 @@
  * be sampled
  */
 fun TouchInjectionScope.swipe(
-    @Suppress("PrimitiveInLambda")
     curve: (Long) -> Offset,
     durationMillis: Long,
     keyTimes: List<Long> = emptyList()
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt
index dde87d7..404d5cd 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/VelocityPathFinder.kt
@@ -50,7 +50,6 @@
         vy = sin(theta) * endVelocity / 1000
     }
 
-    @Suppress("PrimitiveInLambda")
     fun generateFunction(): (Long) -> Offset {
         val fx = createFunctionForVelocity(vx, Offset::x)
         val fy = createFunctionForVelocity(vy, Offset::y)
@@ -88,10 +87,8 @@
      *
      * @param velocity The desired velocity in the x or y direction at the end position
      */
-    @Suppress("PrimitiveInLambda")
     private fun createFunctionForVelocity(
         velocity: Double,
-        @Suppress("PrimitiveInLambda")
         value: Offset.() -> Float
     ): (Long) -> Float {
         val T = durationMillis
diff --git a/compose/ui/ui-test/src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt b/compose/ui/ui-test/src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt
index 8ec7d39..275d234 100644
--- a/compose/ui/ui-test/src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt
+++ b/compose/ui/ui-test/src/jvmMain/kotlin/androidx/compose/ui/test/TestMonotonicFrameClock.jvm.kt
@@ -56,7 +56,6 @@
     private val coroutineScope: CoroutineScope,
     @get:Suppress("MethodNameUnits") // Nanos for high-precision animation clocks
     val frameDelayNanos: Long = DefaultFrameDelay,
-    @Suppress("PrimitiveInLambda")
     private val onPerformTraversals: (Long) -> Unit = {}
 ) : MonotonicFrameClock {
     private val delayController =
@@ -134,7 +133,6 @@
             // This is set after acquiring the lock in case the virtual time was advanced while
             // waiting for it.
             val frameTime: Long
-            @Suppress("PrimitiveInLambda")
             val toRun = synchronized(lock) {
                 check(scheduledFrameDispatch) { "frame dispatch not scheduled" }
 
diff --git a/compose/ui/ui-text-google-fonts/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-text-google-fonts/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..0321970
--- /dev/null
+++ b/compose/ui/ui-text-google-fonts/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.compose.ui.text.googlefonts {
+
+  public final class GoogleFont {
+    ctor public GoogleFont(String name, optional boolean bestEffort);
+    method public boolean getBestEffort();
+    method public String getName();
+    property public final boolean bestEffort;
+    property public final String name;
+  }
+
+  public static final class GoogleFont.Provider {
+    ctor public GoogleFont.Provider(String providerAuthority, String providerPackage, @ArrayRes int certificates);
+    ctor public GoogleFont.Provider(String providerAuthority, String providerPackage, java.util.List<? extends java.util.List<byte[]>> certificates);
+  }
+
+  public final class GoogleFontKt {
+    method public static androidx.compose.ui.text.font.Font Font(androidx.compose.ui.text.googlefonts.GoogleFont googleFont, androidx.compose.ui.text.googlefonts.GoogleFont.Provider fontProvider, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
+    method @WorkerThread public static boolean isAvailableOnDevice(androidx.compose.ui.text.googlefonts.GoogleFont.Provider, android.content.Context context);
+  }
+
+}
+
diff --git a/compose/ui/ui-text-google-fonts/lint-baseline.xml b/compose/ui/ui-text-google-fonts/lint-baseline.xml
deleted file mode 100644
index 0915d8d..0000000
--- a/compose/ui/ui-text-google-fonts/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-alpha05" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha05)" variant="all" version="8.0.0-alpha05">
-
-    <issue
-        id="ExperimentalPropertyAnnotation"
-        message="This property does not have all required annotations to correctly mark it as experimental."
-        errorLine1="            @ExperimentalTextApi"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/compose/ui/text/googlefonts/GoogleFont.kt"/>
-    </issue>
-
-</issues>
diff --git a/compose/ui/ui-text/api/1.5.0-beta01.txt b/compose/ui/ui-text/api/1.5.0-beta01.txt
index b203bb5..4a40acd 100644
--- a/compose/ui/ui-text/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-text/api/1.5.0-beta01.txt
@@ -16,7 +16,6 @@
     method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<java.lang.String>> getStringAnnotations(String tag, int start, int end);
     method public String getText();
     method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.TtsAnnotation>> getTtsAnnotations(int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.UrlAnnotation>> getUrlAnnotations(int start, int end);
     method public boolean hasStringAnnotations(String tag, int start, int end);
     method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.AnnotatedString plus(androidx.compose.ui.text.AnnotatedString other);
     method public androidx.compose.ui.text.AnnotatedString subSequence(int startIndex, int endIndex);
@@ -34,8 +33,6 @@
     method public void addStringAnnotation(String tag, String annotation, int start, int end);
     method public void addStyle(androidx.compose.ui.text.ParagraphStyle style, int start, int end);
     method public void addStyle(androidx.compose.ui.text.SpanStyle style, int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public void addTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation, int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public void addUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation, int start, int end);
     method public void append(androidx.compose.ui.text.AnnotatedString text);
     method public void append(androidx.compose.ui.text.AnnotatedString text, int start, int end);
     method public androidx.compose.ui.text.AnnotatedString.Builder append(char char);
@@ -50,7 +47,6 @@
     method public int pushStyle(androidx.compose.ui.text.ParagraphStyle style);
     method public int pushStyle(androidx.compose.ui.text.SpanStyle style);
     method public int pushTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation);
-    method @androidx.compose.ui.text.ExperimentalTextApi public int pushUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
     method public androidx.compose.ui.text.AnnotatedString toAnnotatedString();
     property public final int length;
   }
@@ -81,9 +77,6 @@
     method public static androidx.compose.ui.text.AnnotatedString decapitalize(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
     method public static androidx.compose.ui.text.AnnotatedString toLowerCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
     method public static androidx.compose.ui.text.AnnotatedString toUpperCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.TtsAnnotation ttsAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.UrlAnnotation urlAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, String tag, String annotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
     method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.ParagraphStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
     method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.SpanStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
   }
@@ -99,12 +92,6 @@
     property public final int None;
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTextApi {
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalTextApi {
-  }
-
   public final class MultiParagraph {
     ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
     ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
@@ -616,12 +603,6 @@
   public abstract sealed class TtsAnnotation {
   }
 
-  @androidx.compose.ui.text.ExperimentalTextApi public final class UrlAnnotation {
-    ctor public UrlAnnotation(String url);
-    method public String getUrl();
-    property public final String url;
-  }
-
   public final class VerbatimTtsAnnotation extends androidx.compose.ui.text.TtsAnnotation {
     ctor public VerbatimTtsAnnotation(String verbatim);
     method public String getVerbatim();
@@ -630,13 +611,6 @@
 
 }
 
-package androidx.compose.ui.text.android {
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalPlatformTextApi {
-  }
-
-}
-
 package androidx.compose.ui.text.font {
 
   public abstract class AndroidFont implements androidx.compose.ui.text.font.Font {
@@ -742,7 +716,6 @@
   public final class FontKt {
     method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily toFontFamily(androidx.compose.ui.text.font.Font);
   }
 
@@ -885,15 +858,11 @@
 
   public final class ResourceFont implements androidx.compose.ui.text.font.Font {
     method public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
     method public int getResId();
     method public int getStyle();
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.FontVariation.Settings getVariationSettings();
     method public androidx.compose.ui.text.font.FontWeight getWeight();
-    property @androidx.compose.ui.text.ExperimentalTextApi public int loadingStrategy;
     property public final int resId;
     property public int style;
-    property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.text.font.FontVariation.Settings variationSettings;
     property public androidx.compose.ui.text.font.FontWeight weight;
   }
 
@@ -1083,39 +1052,6 @@
     property public final char mask;
   }
 
-  @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInput {
-    method public void releaseInputFocus();
-    method public void requestInputFocus();
-  }
-
-  @androidx.compose.ui.text.ExperimentalTextApi public interface PlatformTextInputAdapter {
-    method public android.view.inputmethod.InputConnection? createInputConnection(android.view.inputmethod.EditorInfo outAttrs);
-    method public default void onDisposed();
-  }
-
-  @androidx.compose.runtime.Immutable @androidx.compose.ui.text.ExperimentalTextApi public fun interface PlatformTextInputPlugin<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
-    method public T createAdapter(androidx.compose.ui.text.input.PlatformTextInput platformTextInput, android.view.View view);
-  }
-
-  @androidx.compose.runtime.Stable @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInputPluginRegistry {
-    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-  }
-
-  @androidx.compose.ui.text.InternalTextApi public final class PlatformTextInputPluginRegistryImpl implements androidx.compose.ui.text.input.PlatformTextInputPluginRegistry {
-    ctor public PlatformTextInputPluginRegistryImpl(kotlin.jvm.functions.Function2<? super androidx.compose.ui.text.input.PlatformTextInputPlugin<?>,? super androidx.compose.ui.text.input.PlatformTextInput,? extends androidx.compose.ui.text.input.PlatformTextInputAdapter> factory);
-    method public androidx.compose.ui.text.input.PlatformTextInputAdapter? getFocusedAdapter();
-    method @androidx.compose.ui.text.InternalTextApi public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> androidx.compose.ui.text.input.PlatformTextInputPluginRegistryImpl.AdapterHandle<T> getOrCreateAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-    property public final androidx.compose.ui.text.input.PlatformTextInputAdapter? focusedAdapter;
-  }
-
-  @androidx.compose.ui.text.InternalTextApi public static final class PlatformTextInputPluginRegistryImpl.AdapterHandle<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
-    ctor public PlatformTextInputPluginRegistryImpl.AdapterHandle(T adapter, kotlin.jvm.functions.Function0<java.lang.Boolean> onDispose);
-    method public boolean dispose();
-    method public T getAdapter();
-    property public final T adapter;
-  }
-
   public interface PlatformTextInputService {
     method public void hideSoftwareKeyboard();
     method public default void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
@@ -1263,15 +1199,6 @@
 
 }
 
-package androidx.compose.ui.text.platform {
-
-  @androidx.compose.ui.text.InternalTextApi public final class URLSpanCache {
-    ctor public URLSpanCache();
-    method public android.text.style.URLSpan toURLSpan(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
-  }
-
-}
-
 package androidx.compose.ui.text.platform.extensions {
 
   public final class TtsAnnotationExtensions_androidKt {
diff --git a/compose/ui/ui-text/api/current.txt b/compose/ui/ui-text/api/current.txt
index e93dd1d..ba3232f 100644
--- a/compose/ui/ui-text/api/current.txt
+++ b/compose/ui/ui-text/api/current.txt
@@ -1125,6 +1125,7 @@
     method public void startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
     method public void stopInput();
     method public void updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public default void updateTextLayoutResult(androidx.compose.ui.text.input.TextFieldValue textFieldValue, androidx.compose.ui.text.TextLayoutResult textLayoutResult, long textLayoutPositionInWindow, androidx.compose.ui.geometry.Rect innerTextFieldBounds, androidx.compose.ui.geometry.Rect decorationBoxBounds);
   }
 
   public final class SetComposingRegionCommand implements androidx.compose.ui.text.input.EditCommand {
@@ -1200,6 +1201,7 @@
     method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
     method public boolean showSoftwareKeyboard();
     method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public boolean updateTextLayoutResult(androidx.compose.ui.text.input.TextFieldValue textFieldValue, androidx.compose.ui.text.TextLayoutResult textLayoutResult, long textLayoutPositionInWindow, androidx.compose.ui.geometry.Rect innerTextFieldBounds, androidx.compose.ui.geometry.Rect decorationBoxBounds);
     property public final boolean isOpen;
   }
 
diff --git a/compose/ui/ui-text/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-text/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..b203bb5
--- /dev/null
+++ b/compose/ui/ui-text/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,1545 @@
+// Signature format: 4.0
+package androidx.compose.ui.text {
+
+  public final class AndroidTextStyle_androidKt {
+    method public static androidx.compose.ui.text.PlatformParagraphStyle lerp(androidx.compose.ui.text.PlatformParagraphStyle start, androidx.compose.ui.text.PlatformParagraphStyle stop, float fraction);
+    method public static androidx.compose.ui.text.PlatformSpanStyle lerp(androidx.compose.ui.text.PlatformSpanStyle start, androidx.compose.ui.text.PlatformSpanStyle stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class AnnotatedString implements java.lang.CharSequence {
+    ctor public AnnotatedString(String text, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> paragraphStyles);
+    method public operator char get(int index);
+    method public int getLength();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> getParagraphStyles();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> getSpanStyles();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<java.lang.String>> getStringAnnotations(int start, int end);
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<java.lang.String>> getStringAnnotations(String tag, int start, int end);
+    method public String getText();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.TtsAnnotation>> getTtsAnnotations(int start, int end);
+    method @androidx.compose.ui.text.ExperimentalTextApi public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.UrlAnnotation>> getUrlAnnotations(int start, int end);
+    method public boolean hasStringAnnotations(String tag, int start, int end);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.AnnotatedString plus(androidx.compose.ui.text.AnnotatedString other);
+    method public androidx.compose.ui.text.AnnotatedString subSequence(int startIndex, int endIndex);
+    method public androidx.compose.ui.text.AnnotatedString subSequence(long range);
+    property public int length;
+    property public final java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.ParagraphStyle>> paragraphStyles;
+    property public final java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles;
+    property public final String text;
+  }
+
+  public static final class AnnotatedString.Builder implements java.lang.Appendable {
+    ctor public AnnotatedString.Builder(androidx.compose.ui.text.AnnotatedString text);
+    ctor public AnnotatedString.Builder(optional int capacity);
+    ctor public AnnotatedString.Builder(String text);
+    method public void addStringAnnotation(String tag, String annotation, int start, int end);
+    method public void addStyle(androidx.compose.ui.text.ParagraphStyle style, int start, int end);
+    method public void addStyle(androidx.compose.ui.text.SpanStyle style, int start, int end);
+    method @androidx.compose.ui.text.ExperimentalTextApi public void addTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation, int start, int end);
+    method @androidx.compose.ui.text.ExperimentalTextApi public void addUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation, int start, int end);
+    method public void append(androidx.compose.ui.text.AnnotatedString text);
+    method public void append(androidx.compose.ui.text.AnnotatedString text, int start, int end);
+    method public androidx.compose.ui.text.AnnotatedString.Builder append(char char);
+    method @Deprecated public void append(char char);
+    method public androidx.compose.ui.text.AnnotatedString.Builder append(CharSequence? text);
+    method public androidx.compose.ui.text.AnnotatedString.Builder append(CharSequence? text, int start, int end);
+    method public void append(String text);
+    method public int getLength();
+    method public void pop();
+    method public void pop(int index);
+    method public int pushStringAnnotation(String tag, String annotation);
+    method public int pushStyle(androidx.compose.ui.text.ParagraphStyle style);
+    method public int pushStyle(androidx.compose.ui.text.SpanStyle style);
+    method public int pushTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation);
+    method @androidx.compose.ui.text.ExperimentalTextApi public int pushUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
+    method public androidx.compose.ui.text.AnnotatedString toAnnotatedString();
+    property public final int length;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class AnnotatedString.Range<T> {
+    ctor public AnnotatedString.Range(T item, int start, int end);
+    ctor public AnnotatedString.Range(T item, int start, int end, String tag);
+    method public T component1();
+    method public int component2();
+    method public int component3();
+    method public String component4();
+    method public androidx.compose.ui.text.AnnotatedString.Range<T> copy(T! item, int start, int end, String tag);
+    method public int getEnd();
+    method public T getItem();
+    method public int getStart();
+    method public String getTag();
+    property public final int end;
+    property public final T item;
+    property public final int start;
+    property public final String tag;
+  }
+
+  public final class AnnotatedStringKt {
+    method public static androidx.compose.ui.text.AnnotatedString AnnotatedString(String text, androidx.compose.ui.text.ParagraphStyle paragraphStyle);
+    method public static androidx.compose.ui.text.AnnotatedString AnnotatedString(String text, androidx.compose.ui.text.SpanStyle spanStyle, optional androidx.compose.ui.text.ParagraphStyle? paragraphStyle);
+    method public static inline androidx.compose.ui.text.AnnotatedString buildAnnotatedString(kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,kotlin.Unit> builder);
+    method public static androidx.compose.ui.text.AnnotatedString capitalize(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static androidx.compose.ui.text.AnnotatedString decapitalize(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static androidx.compose.ui.text.AnnotatedString toLowerCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static androidx.compose.ui.text.AnnotatedString toUpperCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
+    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.TtsAnnotation ttsAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
+    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.UrlAnnotation urlAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
+    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, String tag, String annotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
+    method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.ParagraphStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
+    method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.SpanStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
+  }
+
+  @kotlin.jvm.JvmInline public final value class EmojiSupportMatch {
+    field public static final androidx.compose.ui.text.EmojiSupportMatch.Companion Companion;
+  }
+
+  public static final class EmojiSupportMatch.Companion {
+    method public int getDefault();
+    method public int getNone();
+    property public final int Default;
+    property public final int None;
+  }
+
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTextApi {
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalTextApi {
+  }
+
+  public final class MultiParagraph {
+    ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
+    ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
+    ctor public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, long constraints, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
+    ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.MultiParagraphIntrinsics intrinsics, optional int maxLines, optional boolean ellipsis, float width);
+    ctor public MultiParagraph(androidx.compose.ui.text.MultiParagraphIntrinsics intrinsics, long constraints, optional int maxLines, optional boolean ellipsis);
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
+    method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
+    method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
+    method public boolean getDidExceedMaxLines();
+    method public float getFirstBaseline();
+    method public float getHeight();
+    method public float getHorizontalPosition(int offset, boolean usePrimaryDirection);
+    method public androidx.compose.ui.text.MultiParagraphIntrinsics getIntrinsics();
+    method public float getLastBaseline();
+    method public float getLineBottom(int lineIndex);
+    method public int getLineCount();
+    method public int getLineEnd(int lineIndex, optional boolean visibleEnd);
+    method public int getLineForOffset(int offset);
+    method public int getLineForVerticalPosition(float vertical);
+    method public float getLineHeight(int lineIndex);
+    method public float getLineLeft(int lineIndex);
+    method public float getLineRight(int lineIndex);
+    method public int getLineStart(int lineIndex);
+    method public float getLineTop(int lineIndex);
+    method public float getLineWidth(int lineIndex);
+    method public float getMaxIntrinsicWidth();
+    method public int getMaxLines();
+    method public float getMinIntrinsicWidth();
+    method public int getOffsetForPosition(long position);
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getParagraphDirection(int offset);
+    method public androidx.compose.ui.graphics.Path getPathForRange(int start, int end);
+    method public java.util.List<androidx.compose.ui.geometry.Rect> getPlaceholderRects();
+    method public float getWidth();
+    method public long getWordBoundary(int offset);
+    method public boolean isLineEllipsized(int lineIndex);
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, androidx.compose.ui.graphics.Brush brush, optional float alpha, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional int blendMode);
+    method @Deprecated public void paint(androidx.compose.ui.graphics.Canvas canvas, optional long color, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration);
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, optional long color, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? decoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional int blendMode);
+    property public final boolean didExceedMaxLines;
+    property public final float firstBaseline;
+    property public final float height;
+    property public final androidx.compose.ui.text.MultiParagraphIntrinsics intrinsics;
+    property public final float lastBaseline;
+    property public final int lineCount;
+    property public final float maxIntrinsicWidth;
+    property public final int maxLines;
+    property public final float minIntrinsicWidth;
+    property public final java.util.List<androidx.compose.ui.geometry.Rect> placeholderRects;
+    property public final float width;
+  }
+
+  public final class MultiParagraphIntrinsics implements androidx.compose.ui.text.ParagraphIntrinsics {
+    ctor @Deprecated public MultiParagraphIntrinsics(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
+    ctor public MultiParagraphIntrinsics(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver);
+    method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
+    method public float getMaxIntrinsicWidth();
+    method public float getMinIntrinsicWidth();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> getPlaceholders();
+    property public final androidx.compose.ui.text.AnnotatedString annotatedString;
+    property public boolean hasStaleResolvedFonts;
+    property public float maxIntrinsicWidth;
+    property public float minIntrinsicWidth;
+    property public final java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders;
+  }
+
+  public sealed interface Paragraph {
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
+    method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
+    method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
+    method public boolean getDidExceedMaxLines();
+    method public float getFirstBaseline();
+    method public float getHeight();
+    method public float getHorizontalPosition(int offset, boolean usePrimaryDirection);
+    method public float getLastBaseline();
+    method public float getLineBottom(int lineIndex);
+    method public int getLineCount();
+    method public int getLineEnd(int lineIndex, boolean visibleEnd);
+    method public int getLineForOffset(int offset);
+    method public int getLineForVerticalPosition(float vertical);
+    method public float getLineHeight(int lineIndex);
+    method public float getLineLeft(int lineIndex);
+    method public float getLineRight(int lineIndex);
+    method public int getLineStart(int lineIndex);
+    method public float getLineTop(int lineIndex);
+    method public float getLineWidth(int lineIndex);
+    method public float getMaxIntrinsicWidth();
+    method public float getMinIntrinsicWidth();
+    method public int getOffsetForPosition(long position);
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getParagraphDirection(int offset);
+    method public androidx.compose.ui.graphics.Path getPathForRange(int start, int end);
+    method public java.util.List<androidx.compose.ui.geometry.Rect> getPlaceholderRects();
+    method public float getWidth();
+    method public long getWordBoundary(int offset);
+    method public boolean isLineEllipsized(int lineIndex);
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, androidx.compose.ui.graphics.Brush brush, float alpha, androidx.compose.ui.graphics.Shadow? shadow, androidx.compose.ui.text.style.TextDecoration? textDecoration, androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, int blendMode);
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, long color, androidx.compose.ui.graphics.Shadow? shadow, androidx.compose.ui.text.style.TextDecoration? textDecoration);
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, long color, androidx.compose.ui.graphics.Shadow? shadow, androidx.compose.ui.text.style.TextDecoration? textDecoration, androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, int blendMode);
+    property public abstract boolean didExceedMaxLines;
+    property public abstract float firstBaseline;
+    property public abstract float height;
+    property public abstract float lastBaseline;
+    property public abstract int lineCount;
+    property public abstract float maxIntrinsicWidth;
+    property public abstract float minIntrinsicWidth;
+    property public abstract java.util.List<androidx.compose.ui.geometry.Rect> placeholderRects;
+    property public abstract float width;
+  }
+
+  public interface ParagraphIntrinsics {
+    method public default boolean getHasStaleResolvedFonts();
+    method public float getMaxIntrinsicWidth();
+    method public float getMinIntrinsicWidth();
+    property public default boolean hasStaleResolvedFonts;
+    property public abstract float maxIntrinsicWidth;
+    property public abstract float minIntrinsicWidth;
+  }
+
+  public final class ParagraphIntrinsicsKt {
+    method @Deprecated public static androidx.compose.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.compose.ui.text.ParagraphIntrinsics ParagraphIntrinsics(String text, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver);
+  }
+
+  public final class ParagraphKt {
+    method @Deprecated public static androidx.compose.ui.text.Paragraph Paragraph(androidx.compose.ui.text.ParagraphIntrinsics paragraphIntrinsics, optional int maxLines, optional boolean ellipsis, float width);
+    method public static androidx.compose.ui.text.Paragraph Paragraph(androidx.compose.ui.text.ParagraphIntrinsics paragraphIntrinsics, long constraints, optional int maxLines, optional boolean ellipsis);
+    method @Deprecated public static androidx.compose.ui.text.Paragraph Paragraph(String text, androidx.compose.ui.text.TextStyle style, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
+    method @Deprecated public static androidx.compose.ui.text.Paragraph Paragraph(String text, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
+    method public static androidx.compose.ui.text.Paragraph Paragraph(String text, androidx.compose.ui.text.TextStyle style, long constraints, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.SpanStyle>> spanStyles, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
+  }
+
+  @androidx.compose.runtime.Immutable public final class ParagraphStyle {
+    ctor @Deprecated public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
+    ctor @Deprecated public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
+    ctor @Deprecated public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    ctor public ParagraphStyle(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    method @Deprecated public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
+    method @Deprecated public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
+    method @Deprecated public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    method public androidx.compose.ui.text.ParagraphStyle copy(optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformParagraphStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    method public androidx.compose.ui.text.style.Hyphens? getHyphens();
+    method public androidx.compose.ui.text.style.LineBreak? getLineBreak();
+    method public long getLineHeight();
+    method public androidx.compose.ui.text.style.LineHeightStyle? getLineHeightStyle();
+    method public androidx.compose.ui.text.PlatformParagraphStyle? getPlatformStyle();
+    method public androidx.compose.ui.text.style.TextAlign? getTextAlign();
+    method public androidx.compose.ui.text.style.TextDirection? getTextDirection();
+    method public androidx.compose.ui.text.style.TextIndent? getTextIndent();
+    method public androidx.compose.ui.text.style.TextMotion? getTextMotion();
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.ParagraphStyle merge(optional androidx.compose.ui.text.ParagraphStyle? other);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.ParagraphStyle plus(androidx.compose.ui.text.ParagraphStyle other);
+    property public final androidx.compose.ui.text.style.Hyphens? hyphens;
+    property public final androidx.compose.ui.text.style.LineBreak? lineBreak;
+    property public final long lineHeight;
+    property public final androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle;
+    property public final androidx.compose.ui.text.PlatformParagraphStyle? platformStyle;
+    property public final androidx.compose.ui.text.style.TextAlign? textAlign;
+    property public final androidx.compose.ui.text.style.TextDirection? textDirection;
+    property public final androidx.compose.ui.text.style.TextIndent? textIndent;
+    property public final androidx.compose.ui.text.style.TextMotion? textMotion;
+  }
+
+  public final class ParagraphStyleKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.ParagraphStyle lerp(androidx.compose.ui.text.ParagraphStyle start, androidx.compose.ui.text.ParagraphStyle stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class Placeholder {
+    ctor public Placeholder(long width, long height, int placeholderVerticalAlign);
+    method public androidx.compose.ui.text.Placeholder copy(optional long width, optional long height, optional int placeholderVerticalAlign);
+    method public long getHeight();
+    method public int getPlaceholderVerticalAlign();
+    method public long getWidth();
+    property public final long height;
+    property public final int placeholderVerticalAlign;
+    property public final long width;
+  }
+
+  @kotlin.jvm.JvmInline public final value class PlaceholderVerticalAlign {
+    field public static final androidx.compose.ui.text.PlaceholderVerticalAlign.Companion Companion;
+  }
+
+  public static final class PlaceholderVerticalAlign.Companion {
+    method public int getAboveBaseline();
+    method public int getBottom();
+    method public int getCenter();
+    method public int getTextBottom();
+    method public int getTextCenter();
+    method public int getTextTop();
+    method public int getTop();
+    property public final int AboveBaseline;
+    property public final int Bottom;
+    property public final int Center;
+    property public final int TextBottom;
+    property public final int TextCenter;
+    property public final int TextTop;
+    property public final int Top;
+  }
+
+  public final class PlatformParagraphStyle {
+    ctor public PlatformParagraphStyle(optional boolean includeFontPadding);
+    ctor public PlatformParagraphStyle(optional int emojiSupportMatch);
+    ctor public PlatformParagraphStyle(optional int emojiSupportMatch, optional boolean includeFontPadding);
+    method public int getEmojiSupportMatch();
+    method public boolean getIncludeFontPadding();
+    method public androidx.compose.ui.text.PlatformParagraphStyle merge(androidx.compose.ui.text.PlatformParagraphStyle? other);
+    property public final int emojiSupportMatch;
+    property public final boolean includeFontPadding;
+    field public static final androidx.compose.ui.text.PlatformParagraphStyle.Companion Companion;
+  }
+
+  public static final class PlatformParagraphStyle.Companion {
+    method public androidx.compose.ui.text.PlatformParagraphStyle getDefault();
+    property public final androidx.compose.ui.text.PlatformParagraphStyle Default;
+  }
+
+  public final class PlatformSpanStyle {
+    ctor public PlatformSpanStyle();
+    method public androidx.compose.ui.text.PlatformSpanStyle merge(androidx.compose.ui.text.PlatformSpanStyle? other);
+    field public static final androidx.compose.ui.text.PlatformSpanStyle.Companion Companion;
+  }
+
+  public static final class PlatformSpanStyle.Companion {
+    method public androidx.compose.ui.text.PlatformSpanStyle getDefault();
+    property public final androidx.compose.ui.text.PlatformSpanStyle Default;
+  }
+
+  public final class PlatformTextStyle {
+    ctor public PlatformTextStyle(androidx.compose.ui.text.PlatformSpanStyle? spanStyle, androidx.compose.ui.text.PlatformParagraphStyle? paragraphStyle);
+    ctor public PlatformTextStyle(optional boolean includeFontPadding);
+    ctor public PlatformTextStyle(int emojiSupportMatch);
+    method public androidx.compose.ui.text.PlatformParagraphStyle? getParagraphStyle();
+    method public androidx.compose.ui.text.PlatformSpanStyle? getSpanStyle();
+    property public final androidx.compose.ui.text.PlatformParagraphStyle? paragraphStyle;
+    property public final androidx.compose.ui.text.PlatformSpanStyle? spanStyle;
+  }
+
+  @androidx.compose.runtime.Immutable public final class SpanStyle {
+    ctor public SpanStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    ctor @Deprecated public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
+    ctor @Deprecated public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
+    ctor public SpanStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    method public androidx.compose.ui.text.SpanStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    method @Deprecated public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow);
+    method @Deprecated public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle);
+    method public androidx.compose.ui.text.SpanStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.PlatformSpanStyle? platformStyle, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle);
+    method public float getAlpha();
+    method public long getBackground();
+    method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
+    method public androidx.compose.ui.graphics.Brush? getBrush();
+    method public long getColor();
+    method public androidx.compose.ui.graphics.drawscope.DrawStyle? getDrawStyle();
+    method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
+    method public String? getFontFeatureSettings();
+    method public long getFontSize();
+    method public androidx.compose.ui.text.font.FontStyle? getFontStyle();
+    method public androidx.compose.ui.text.font.FontSynthesis? getFontSynthesis();
+    method public androidx.compose.ui.text.font.FontWeight? getFontWeight();
+    method public long getLetterSpacing();
+    method public androidx.compose.ui.text.intl.LocaleList? getLocaleList();
+    method public androidx.compose.ui.text.PlatformSpanStyle? getPlatformStyle();
+    method public androidx.compose.ui.graphics.Shadow? getShadow();
+    method public androidx.compose.ui.text.style.TextDecoration? getTextDecoration();
+    method public androidx.compose.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.SpanStyle merge(optional androidx.compose.ui.text.SpanStyle? other);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.SpanStyle plus(androidx.compose.ui.text.SpanStyle other);
+    property public final float alpha;
+    property public final long background;
+    property public final androidx.compose.ui.text.style.BaselineShift? baselineShift;
+    property public final androidx.compose.ui.graphics.Brush? brush;
+    property public final long color;
+    property public final androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle;
+    property public final androidx.compose.ui.text.font.FontFamily? fontFamily;
+    property public final String? fontFeatureSettings;
+    property public final long fontSize;
+    property public final androidx.compose.ui.text.font.FontStyle? fontStyle;
+    property public final androidx.compose.ui.text.font.FontSynthesis? fontSynthesis;
+    property public final androidx.compose.ui.text.font.FontWeight? fontWeight;
+    property public final long letterSpacing;
+    property public final androidx.compose.ui.text.intl.LocaleList? localeList;
+    property public final androidx.compose.ui.text.PlatformSpanStyle? platformStyle;
+    property public final androidx.compose.ui.graphics.Shadow? shadow;
+    property public final androidx.compose.ui.text.style.TextDecoration? textDecoration;
+    property public final androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform;
+  }
+
+  public final class SpanStyleKt {
+    method public static androidx.compose.ui.text.SpanStyle lerp(androidx.compose.ui.text.SpanStyle start, androidx.compose.ui.text.SpanStyle stop, float fraction);
+  }
+
+  public final class StringKt {
+    method public static String capitalize(String, androidx.compose.ui.text.intl.Locale locale);
+    method public static String capitalize(String, androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static String decapitalize(String, androidx.compose.ui.text.intl.Locale locale);
+    method public static String decapitalize(String, androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static String toLowerCase(String, androidx.compose.ui.text.intl.Locale locale);
+    method public static String toLowerCase(String, androidx.compose.ui.text.intl.LocaleList localeList);
+    method public static String toUpperCase(String, androidx.compose.ui.text.intl.Locale locale);
+    method public static String toUpperCase(String, androidx.compose.ui.text.intl.LocaleList localeList);
+  }
+
+  public final class TextLayoutInput {
+    ctor @Deprecated public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, long constraints);
+    ctor public TextLayoutInput(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.TextStyle style, java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, int maxLines, boolean softWrap, int overflow, androidx.compose.ui.unit.Density density, androidx.compose.ui.unit.LayoutDirection layoutDirection, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, long constraints);
+    method @Deprecated public androidx.compose.ui.text.TextLayoutInput copy(optional androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean softWrap, optional int overflow, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader, optional long constraints);
+    method public long getConstraints();
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.text.font.FontFamily.Resolver getFontFamilyResolver();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method public int getMaxLines();
+    method public int getOverflow();
+    method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> getPlaceholders();
+    method @Deprecated public androidx.compose.ui.text.font.Font.ResourceLoader getResourceLoader();
+    method public boolean getSoftWrap();
+    method public androidx.compose.ui.text.TextStyle getStyle();
+    method public androidx.compose.ui.text.AnnotatedString getText();
+    property public final long constraints;
+    property public final androidx.compose.ui.unit.Density density;
+    property public final androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver;
+    property public final androidx.compose.ui.unit.LayoutDirection layoutDirection;
+    property public final int maxLines;
+    property public final int overflow;
+    property public final java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders;
+    property @Deprecated public final androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader;
+    property public final boolean softWrap;
+    property public final androidx.compose.ui.text.TextStyle style;
+    property public final androidx.compose.ui.text.AnnotatedString text;
+  }
+
+  public final class TextLayoutResult {
+    ctor public TextLayoutResult(androidx.compose.ui.text.TextLayoutInput layoutInput, androidx.compose.ui.text.MultiParagraph multiParagraph, long size);
+    method public androidx.compose.ui.text.TextLayoutResult copy(optional androidx.compose.ui.text.TextLayoutInput layoutInput, optional long size);
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getBidiRunDirection(int offset);
+    method public androidx.compose.ui.geometry.Rect getBoundingBox(int offset);
+    method public androidx.compose.ui.geometry.Rect getCursorRect(int offset);
+    method public boolean getDidOverflowHeight();
+    method public boolean getDidOverflowWidth();
+    method public float getFirstBaseline();
+    method public boolean getHasVisualOverflow();
+    method public float getHorizontalPosition(int offset, boolean usePrimaryDirection);
+    method public float getLastBaseline();
+    method public androidx.compose.ui.text.TextLayoutInput getLayoutInput();
+    method public float getLineBottom(int lineIndex);
+    method public int getLineCount();
+    method public int getLineEnd(int lineIndex, optional boolean visibleEnd);
+    method public int getLineForOffset(int offset);
+    method public int getLineForVerticalPosition(float vertical);
+    method public float getLineLeft(int lineIndex);
+    method public float getLineRight(int lineIndex);
+    method public int getLineStart(int lineIndex);
+    method public float getLineTop(int lineIndex);
+    method public androidx.compose.ui.text.MultiParagraph getMultiParagraph();
+    method public int getOffsetForPosition(long position);
+    method public androidx.compose.ui.text.style.ResolvedTextDirection getParagraphDirection(int offset);
+    method public androidx.compose.ui.graphics.Path getPathForRange(int start, int end);
+    method public java.util.List<androidx.compose.ui.geometry.Rect> getPlaceholderRects();
+    method public long getSize();
+    method public long getWordBoundary(int offset);
+    method public boolean isLineEllipsized(int lineIndex);
+    property public final boolean didOverflowHeight;
+    property public final boolean didOverflowWidth;
+    property public final float firstBaseline;
+    property public final boolean hasVisualOverflow;
+    property public final float lastBaseline;
+    property public final androidx.compose.ui.text.TextLayoutInput layoutInput;
+    property public final int lineCount;
+    property public final androidx.compose.ui.text.MultiParagraph multiParagraph;
+    property public final java.util.List<androidx.compose.ui.geometry.Rect> placeholderRects;
+    property public final long size;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextMeasurer {
+    ctor public TextMeasurer(androidx.compose.ui.text.font.FontFamily.Resolver fallbackFontFamilyResolver, androidx.compose.ui.unit.Density fallbackDensity, androidx.compose.ui.unit.LayoutDirection fallbackLayoutDirection, optional int cacheSize);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextLayoutResult measure(androidx.compose.ui.text.AnnotatedString text, optional androidx.compose.ui.text.TextStyle style, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional long constraints, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional boolean skipCache);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextLayoutResult measure(String text, optional androidx.compose.ui.text.TextStyle style, optional int overflow, optional boolean softWrap, optional int maxLines, optional long constraints, optional androidx.compose.ui.unit.LayoutDirection layoutDirection, optional androidx.compose.ui.unit.Density density, optional androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional boolean skipCache);
+  }
+
+  public final class TextPainter {
+    method public void paint(androidx.compose.ui.graphics.Canvas canvas, androidx.compose.ui.text.TextLayoutResult textLayoutResult);
+    field public static final androidx.compose.ui.text.TextPainter INSTANCE;
+  }
+
+  public final class TextPainterKt {
+    method public static void drawText(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.text.TextLayoutResult textLayoutResult, androidx.compose.ui.graphics.Brush brush, optional long topLeft, optional float alpha, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional int blendMode);
+    method public static void drawText(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.text.TextLayoutResult textLayoutResult, optional long color, optional long topLeft, optional float alpha, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional int blendMode);
+    method public static void drawText(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.text.TextMeasurer textMeasurer, androidx.compose.ui.text.AnnotatedString text, optional long topLeft, optional androidx.compose.ui.text.TextStyle style, optional int overflow, optional boolean softWrap, optional int maxLines, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional long size, optional int blendMode);
+    method public static void drawText(androidx.compose.ui.graphics.drawscope.DrawScope, androidx.compose.ui.text.TextMeasurer textMeasurer, String text, optional long topLeft, optional androidx.compose.ui.text.TextStyle style, optional int overflow, optional boolean softWrap, optional int maxLines, optional long size, optional int blendMode);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TextRange {
+    method public operator boolean contains(int offset);
+    method public operator boolean contains(long other);
+    method public boolean getCollapsed();
+    method public int getEnd();
+    method public int getLength();
+    method public int getMax();
+    method public int getMin();
+    method public boolean getReversed();
+    method public int getStart();
+    method public boolean intersects(long other);
+    property public final boolean collapsed;
+    property public final int end;
+    property public final int length;
+    property public final int max;
+    property public final int min;
+    property public final boolean reversed;
+    property public final int start;
+    field public static final androidx.compose.ui.text.TextRange.Companion Companion;
+  }
+
+  public static final class TextRange.Companion {
+    method public long getZero();
+    property public final long Zero;
+  }
+
+  public final class TextRangeKt {
+    method public static long TextRange(int index);
+    method public static long TextRange(int start, int end);
+    method public static long coerceIn(long, int minimumValue, int maximumValue);
+    method public static String substring(CharSequence, long range);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextStyle {
+    ctor public TextStyle(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    ctor public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    ctor @Deprecated public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
+    ctor @Deprecated public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
+    ctor @Deprecated public TextStyle(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    method public androidx.compose.ui.text.TextStyle copy(androidx.compose.ui.graphics.Brush? brush, optional float alpha, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    method public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    method @Deprecated public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent);
+    method @Deprecated public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle);
+    method @Deprecated public androidx.compose.ui.text.TextStyle copy(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens);
+    method public float getAlpha();
+    method public long getBackground();
+    method public androidx.compose.ui.text.style.BaselineShift? getBaselineShift();
+    method public androidx.compose.ui.graphics.Brush? getBrush();
+    method public long getColor();
+    method public androidx.compose.ui.graphics.drawscope.DrawStyle? getDrawStyle();
+    method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
+    method public String? getFontFeatureSettings();
+    method public long getFontSize();
+    method public androidx.compose.ui.text.font.FontStyle? getFontStyle();
+    method public androidx.compose.ui.text.font.FontSynthesis? getFontSynthesis();
+    method public androidx.compose.ui.text.font.FontWeight? getFontWeight();
+    method public androidx.compose.ui.text.style.Hyphens? getHyphens();
+    method public long getLetterSpacing();
+    method public androidx.compose.ui.text.style.LineBreak? getLineBreak();
+    method public long getLineHeight();
+    method public androidx.compose.ui.text.style.LineHeightStyle? getLineHeightStyle();
+    method public androidx.compose.ui.text.intl.LocaleList? getLocaleList();
+    method public androidx.compose.ui.text.PlatformTextStyle? getPlatformStyle();
+    method public androidx.compose.ui.graphics.Shadow? getShadow();
+    method public androidx.compose.ui.text.style.TextAlign? getTextAlign();
+    method public androidx.compose.ui.text.style.TextDecoration? getTextDecoration();
+    method public androidx.compose.ui.text.style.TextDirection? getTextDirection();
+    method public androidx.compose.ui.text.style.TextGeometricTransform? getTextGeometricTransform();
+    method public androidx.compose.ui.text.style.TextIndent? getTextIndent();
+    method public androidx.compose.ui.text.style.TextMotion? getTextMotion();
+    method public boolean hasSameDrawAffectingAttributes(androidx.compose.ui.text.TextStyle other);
+    method public boolean hasSameLayoutAffectingAttributes(androidx.compose.ui.text.TextStyle other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextStyle merge(androidx.compose.ui.text.ParagraphStyle other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextStyle merge(androidx.compose.ui.text.SpanStyle other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextStyle merge(optional androidx.compose.ui.text.TextStyle? other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.TextStyle merge(optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional String? fontFeatureSettings, optional long letterSpacing, optional androidx.compose.ui.text.style.BaselineShift? baselineShift, optional androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform, optional androidx.compose.ui.text.intl.LocaleList? localeList, optional long background, optional androidx.compose.ui.text.style.TextDecoration? textDecoration, optional androidx.compose.ui.graphics.Shadow? shadow, optional androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle, optional androidx.compose.ui.text.style.TextAlign? textAlign, optional androidx.compose.ui.text.style.TextDirection? textDirection, optional long lineHeight, optional androidx.compose.ui.text.style.TextIndent? textIndent, optional androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle, optional androidx.compose.ui.text.style.LineBreak? lineBreak, optional androidx.compose.ui.text.style.Hyphens? hyphens, optional androidx.compose.ui.text.PlatformTextStyle? platformStyle, optional androidx.compose.ui.text.style.TextMotion? textMotion);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.TextStyle plus(androidx.compose.ui.text.ParagraphStyle other);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.TextStyle plus(androidx.compose.ui.text.SpanStyle other);
+    method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.TextStyle plus(androidx.compose.ui.text.TextStyle other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.ParagraphStyle toParagraphStyle();
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.text.SpanStyle toSpanStyle();
+    property public final float alpha;
+    property public final long background;
+    property public final androidx.compose.ui.text.style.BaselineShift? baselineShift;
+    property public final androidx.compose.ui.graphics.Brush? brush;
+    property public final long color;
+    property public final androidx.compose.ui.graphics.drawscope.DrawStyle? drawStyle;
+    property public final androidx.compose.ui.text.font.FontFamily? fontFamily;
+    property public final String? fontFeatureSettings;
+    property public final long fontSize;
+    property public final androidx.compose.ui.text.font.FontStyle? fontStyle;
+    property public final androidx.compose.ui.text.font.FontSynthesis? fontSynthesis;
+    property public final androidx.compose.ui.text.font.FontWeight? fontWeight;
+    property public final androidx.compose.ui.text.style.Hyphens? hyphens;
+    property public final long letterSpacing;
+    property public final androidx.compose.ui.text.style.LineBreak? lineBreak;
+    property public final long lineHeight;
+    property public final androidx.compose.ui.text.style.LineHeightStyle? lineHeightStyle;
+    property public final androidx.compose.ui.text.intl.LocaleList? localeList;
+    property public final androidx.compose.ui.text.PlatformTextStyle? platformStyle;
+    property public final androidx.compose.ui.graphics.Shadow? shadow;
+    property public final androidx.compose.ui.text.style.TextAlign? textAlign;
+    property public final androidx.compose.ui.text.style.TextDecoration? textDecoration;
+    property public final androidx.compose.ui.text.style.TextDirection? textDirection;
+    property public final androidx.compose.ui.text.style.TextGeometricTransform? textGeometricTransform;
+    property public final androidx.compose.ui.text.style.TextIndent? textIndent;
+    property public final androidx.compose.ui.text.style.TextMotion? textMotion;
+    field public static final androidx.compose.ui.text.TextStyle.Companion Companion;
+  }
+
+  public static final class TextStyle.Companion {
+    method public androidx.compose.ui.text.TextStyle getDefault();
+    property public final androidx.compose.ui.text.TextStyle Default;
+  }
+
+  public final class TextStyleKt {
+    method public static androidx.compose.ui.text.TextStyle lerp(androidx.compose.ui.text.TextStyle start, androidx.compose.ui.text.TextStyle stop, float fraction);
+    method public static androidx.compose.ui.text.TextStyle resolveDefaults(androidx.compose.ui.text.TextStyle style, androidx.compose.ui.unit.LayoutDirection direction);
+  }
+
+  public abstract sealed class TtsAnnotation {
+  }
+
+  @androidx.compose.ui.text.ExperimentalTextApi public final class UrlAnnotation {
+    ctor public UrlAnnotation(String url);
+    method public String getUrl();
+    property public final String url;
+  }
+
+  public final class VerbatimTtsAnnotation extends androidx.compose.ui.text.TtsAnnotation {
+    ctor public VerbatimTtsAnnotation(String verbatim);
+    method public String getVerbatim();
+    property public final String verbatim;
+  }
+
+}
+
+package androidx.compose.ui.text.android {
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalPlatformTextApi {
+  }
+
+}
+
+package androidx.compose.ui.text.font {
+
+  public abstract class AndroidFont implements androidx.compose.ui.text.font.Font {
+    ctor @Deprecated public AndroidFont(int loadingStrategy, androidx.compose.ui.text.font.AndroidFont.TypefaceLoader typefaceLoader);
+    ctor public AndroidFont(int loadingStrategy, androidx.compose.ui.text.font.AndroidFont.TypefaceLoader typefaceLoader, androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+    method public final int getLoadingStrategy();
+    method public final androidx.compose.ui.text.font.AndroidFont.TypefaceLoader getTypefaceLoader();
+    method public final androidx.compose.ui.text.font.FontVariation.Settings getVariationSettings();
+    property public final int loadingStrategy;
+    property public final androidx.compose.ui.text.font.AndroidFont.TypefaceLoader typefaceLoader;
+    property public final androidx.compose.ui.text.font.FontVariation.Settings variationSettings;
+  }
+
+  public static interface AndroidFont.TypefaceLoader {
+    method public suspend Object? awaitLoad(android.content.Context context, androidx.compose.ui.text.font.AndroidFont font, kotlin.coroutines.Continuation<? super android.graphics.Typeface>);
+    method public android.graphics.Typeface? loadBlocking(android.content.Context context, androidx.compose.ui.text.font.AndroidFont font);
+  }
+
+  public final class AndroidFontKt {
+    method @RequiresApi(26) @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(android.os.ParcelFileDescriptor fileDescriptor, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(java.io.File file, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(String path, android.content.res.AssetManager assetManager, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+  }
+
+  public final class AndroidTypeface_androidKt {
+    method public static androidx.compose.ui.text.font.FontFamily FontFamily(android.graphics.Typeface typeface);
+    method @Deprecated public static androidx.compose.ui.text.font.Typeface Typeface(android.content.Context context, androidx.compose.ui.text.font.FontFamily fontFamily, optional java.util.List<kotlin.Pair<androidx.compose.ui.text.font.FontWeight,androidx.compose.ui.text.font.FontStyle>>? styles);
+    method public static androidx.compose.ui.text.font.Typeface Typeface(android.graphics.Typeface typeface);
+  }
+
+  public final class DelegatingFontLoaderForDeprecatedUsage_androidKt {
+    method @Deprecated public static androidx.compose.ui.text.font.FontFamily.Resolver createFontFamilyResolver(androidx.compose.ui.text.font.Font.ResourceLoader fontResourceLoader, android.content.Context context);
+  }
+
+  @kotlin.jvm.JvmInline public final value class DeviceFontFamilyName {
+    ctor public DeviceFontFamilyName(String name);
+    method public String getName();
+    property public final String name;
+  }
+
+  public final class DeviceFontFamilyNameFontKt {
+    method public static androidx.compose.ui.text.font.Font Font(String familyName, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+  }
+
+  public abstract sealed class FileBasedFontFamily extends androidx.compose.ui.text.font.FontFamily {
+  }
+
+  @androidx.compose.runtime.Immutable public interface Font {
+    method public default int getLoadingStrategy();
+    method public int getStyle();
+    method public androidx.compose.ui.text.font.FontWeight getWeight();
+    property public default int loadingStrategy;
+    property public abstract int style;
+    property public abstract androidx.compose.ui.text.font.FontWeight weight;
+    field public static final androidx.compose.ui.text.font.Font.Companion Companion;
+    field public static final long MaximumAsyncTimeoutMillis = 15000L; // 0x3a98L
+  }
+
+  public static final class Font.Companion {
+    field public static final long MaximumAsyncTimeoutMillis = 15000L; // 0x3a98L
+  }
+
+  @Deprecated public static interface Font.ResourceLoader {
+    method @Deprecated public Object load(androidx.compose.ui.text.font.Font font);
+  }
+
+  @androidx.compose.runtime.Immutable public abstract sealed class FontFamily {
+    method @Deprecated public final boolean getCanLoadSynchronously();
+    property @Deprecated public final boolean canLoadSynchronously;
+    field public static final androidx.compose.ui.text.font.FontFamily.Companion Companion;
+  }
+
+  public static final class FontFamily.Companion {
+    method public androidx.compose.ui.text.font.GenericFontFamily getCursive();
+    method public androidx.compose.ui.text.font.SystemFontFamily getDefault();
+    method public androidx.compose.ui.text.font.GenericFontFamily getMonospace();
+    method public androidx.compose.ui.text.font.GenericFontFamily getSansSerif();
+    method public androidx.compose.ui.text.font.GenericFontFamily getSerif();
+    property public final androidx.compose.ui.text.font.GenericFontFamily Cursive;
+    property public final androidx.compose.ui.text.font.SystemFontFamily Default;
+    property public final androidx.compose.ui.text.font.GenericFontFamily Monospace;
+    property public final androidx.compose.ui.text.font.GenericFontFamily SansSerif;
+    property public final androidx.compose.ui.text.font.GenericFontFamily Serif;
+  }
+
+  public static sealed interface FontFamily.Resolver {
+    method public suspend Object? preload(androidx.compose.ui.text.font.FontFamily fontFamily, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public androidx.compose.runtime.State<java.lang.Object> resolve(optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional androidx.compose.ui.text.font.FontWeight fontWeight, optional int fontStyle, optional int fontSynthesis);
+  }
+
+  public final class FontFamilyKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily FontFamily(androidx.compose.ui.text.font.Font... fonts);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily FontFamily(androidx.compose.ui.text.font.Typeface typeface);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily FontFamily(java.util.List<? extends androidx.compose.ui.text.font.Font> fonts);
+  }
+
+  public final class FontFamilyResolver_androidKt {
+    method public static androidx.compose.ui.text.font.FontFamily.Resolver createFontFamilyResolver(android.content.Context context);
+    method public static androidx.compose.ui.text.font.FontFamily.Resolver createFontFamilyResolver(android.content.Context context, kotlin.coroutines.CoroutineContext coroutineContext);
+    method public static androidx.compose.runtime.State<android.graphics.Typeface> resolveAsTypeface(androidx.compose.ui.text.font.FontFamily.Resolver, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional androidx.compose.ui.text.font.FontWeight fontWeight, optional int fontStyle, optional int fontSynthesis);
+  }
+
+  public final class FontKt {
+    method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy);
+    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily toFontFamily(androidx.compose.ui.text.font.Font);
+  }
+
+  @androidx.compose.runtime.Immutable public final class FontListFontFamily extends androidx.compose.ui.text.font.FileBasedFontFamily implements kotlin.jvm.internal.markers.KMappedMarker java.util.List<androidx.compose.ui.text.font.Font> {
+    method public java.util.List<androidx.compose.ui.text.font.Font> getFonts();
+    property public final java.util.List<androidx.compose.ui.text.font.Font> fonts;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontLoadingStrategy {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.compose.ui.text.font.FontLoadingStrategy.Companion Companion;
+  }
+
+  public static final class FontLoadingStrategy.Companion {
+    method public int getAsync();
+    method public int getBlocking();
+    method public int getOptionalLocal();
+    property public final int Async;
+    property public final int Blocking;
+    property public final int OptionalLocal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontStyle {
+    ctor public FontStyle(int value);
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.compose.ui.text.font.FontStyle.Companion Companion;
+  }
+
+  public static final class FontStyle.Companion {
+    method public int getItalic();
+    method public int getNormal();
+    method public java.util.List<androidx.compose.ui.text.font.FontStyle> values();
+    property public final int Italic;
+    property public final int Normal;
+  }
+
+  @kotlin.jvm.JvmInline public final value class FontSynthesis {
+    field public static final androidx.compose.ui.text.font.FontSynthesis.Companion Companion;
+  }
+
+  public static final class FontSynthesis.Companion {
+    method public int getAll();
+    method public int getNone();
+    method public int getStyle();
+    method public int getWeight();
+    property public final int All;
+    property public final int None;
+    property public final int Style;
+    property public final int Weight;
+  }
+
+  public final class FontVariation {
+    method public androidx.compose.ui.text.font.FontVariation.Setting Setting(String name, float value);
+    method public androidx.compose.ui.text.font.FontVariation.Settings Settings(androidx.compose.ui.text.font.FontWeight weight, int style, androidx.compose.ui.text.font.FontVariation.Setting... settings);
+    method public androidx.compose.ui.text.font.FontVariation.Setting grade(int value);
+    method public androidx.compose.ui.text.font.FontVariation.Setting italic(float value);
+    method public androidx.compose.ui.text.font.FontVariation.Setting opticalSizing(long textSize);
+    method public androidx.compose.ui.text.font.FontVariation.Setting slant(float value);
+    method public androidx.compose.ui.text.font.FontVariation.Setting weight(int value);
+    method public androidx.compose.ui.text.font.FontVariation.Setting width(float value);
+    field public static final androidx.compose.ui.text.font.FontVariation INSTANCE;
+  }
+
+  @androidx.compose.runtime.Immutable public static sealed interface FontVariation.Setting {
+    method public String getAxisName();
+    method public boolean getNeedsDensity();
+    method public float toVariationValue(androidx.compose.ui.unit.Density? density);
+    property public abstract String axisName;
+    property public abstract boolean needsDensity;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class FontVariation.Settings {
+    ctor public FontVariation.Settings(androidx.compose.ui.text.font.FontVariation.Setting... settings);
+    method public java.util.List<androidx.compose.ui.text.font.FontVariation.Setting> getSettings();
+    property public final java.util.List<androidx.compose.ui.text.font.FontVariation.Setting> settings;
+  }
+
+  @androidx.compose.runtime.Immutable public final class FontWeight implements java.lang.Comparable<androidx.compose.ui.text.font.FontWeight> {
+    ctor public FontWeight(int weight);
+    method public operator int compareTo(androidx.compose.ui.text.font.FontWeight other);
+    method public int getWeight();
+    property public final int weight;
+    field public static final androidx.compose.ui.text.font.FontWeight.Companion Companion;
+  }
+
+  public static final class FontWeight.Companion {
+    method public androidx.compose.ui.text.font.FontWeight getBlack();
+    method public androidx.compose.ui.text.font.FontWeight getBold();
+    method public androidx.compose.ui.text.font.FontWeight getExtraBold();
+    method public androidx.compose.ui.text.font.FontWeight getExtraLight();
+    method public androidx.compose.ui.text.font.FontWeight getLight();
+    method public androidx.compose.ui.text.font.FontWeight getMedium();
+    method public androidx.compose.ui.text.font.FontWeight getNormal();
+    method public androidx.compose.ui.text.font.FontWeight getSemiBold();
+    method public androidx.compose.ui.text.font.FontWeight getThin();
+    method public androidx.compose.ui.text.font.FontWeight getW100();
+    method public androidx.compose.ui.text.font.FontWeight getW200();
+    method public androidx.compose.ui.text.font.FontWeight getW300();
+    method public androidx.compose.ui.text.font.FontWeight getW400();
+    method public androidx.compose.ui.text.font.FontWeight getW500();
+    method public androidx.compose.ui.text.font.FontWeight getW600();
+    method public androidx.compose.ui.text.font.FontWeight getW700();
+    method public androidx.compose.ui.text.font.FontWeight getW800();
+    method public androidx.compose.ui.text.font.FontWeight getW900();
+    property public final androidx.compose.ui.text.font.FontWeight Black;
+    property public final androidx.compose.ui.text.font.FontWeight Bold;
+    property public final androidx.compose.ui.text.font.FontWeight ExtraBold;
+    property public final androidx.compose.ui.text.font.FontWeight ExtraLight;
+    property public final androidx.compose.ui.text.font.FontWeight Light;
+    property public final androidx.compose.ui.text.font.FontWeight Medium;
+    property public final androidx.compose.ui.text.font.FontWeight Normal;
+    property public final androidx.compose.ui.text.font.FontWeight SemiBold;
+    property public final androidx.compose.ui.text.font.FontWeight Thin;
+    property public final androidx.compose.ui.text.font.FontWeight W100;
+    property public final androidx.compose.ui.text.font.FontWeight W200;
+    property public final androidx.compose.ui.text.font.FontWeight W300;
+    property public final androidx.compose.ui.text.font.FontWeight W400;
+    property public final androidx.compose.ui.text.font.FontWeight W500;
+    property public final androidx.compose.ui.text.font.FontWeight W600;
+    property public final androidx.compose.ui.text.font.FontWeight W700;
+    property public final androidx.compose.ui.text.font.FontWeight W800;
+    property public final androidx.compose.ui.text.font.FontWeight W900;
+  }
+
+  public final class FontWeightKt {
+    method public static androidx.compose.ui.text.font.FontWeight lerp(androidx.compose.ui.text.font.FontWeight start, androidx.compose.ui.text.font.FontWeight stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class GenericFontFamily extends androidx.compose.ui.text.font.SystemFontFamily {
+    method public String getName();
+    property public final String name;
+  }
+
+  public final class LoadedFontFamily extends androidx.compose.ui.text.font.FontFamily {
+    method public androidx.compose.ui.text.font.Typeface getTypeface();
+    property public final androidx.compose.ui.text.font.Typeface typeface;
+  }
+
+  public final class ResourceFont implements androidx.compose.ui.text.font.Font {
+    method public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
+    method public int getResId();
+    method public int getStyle();
+    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.FontVariation.Settings getVariationSettings();
+    method public androidx.compose.ui.text.font.FontWeight getWeight();
+    property @androidx.compose.ui.text.ExperimentalTextApi public int loadingStrategy;
+    property public final int resId;
+    property public int style;
+    property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.text.font.FontVariation.Settings variationSettings;
+    property public androidx.compose.ui.text.font.FontWeight weight;
+  }
+
+  public abstract sealed class SystemFontFamily extends androidx.compose.ui.text.font.FontFamily {
+  }
+
+  public interface Typeface {
+    method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
+    property public abstract androidx.compose.ui.text.font.FontFamily? fontFamily;
+  }
+
+}
+
+package androidx.compose.ui.text.input {
+
+  public final class BackspaceCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public BackspaceCommand();
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+  }
+
+  public final class CommitTextCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public CommitTextCommand(androidx.compose.ui.text.AnnotatedString annotatedString, int newCursorPosition);
+    ctor public CommitTextCommand(String text, int newCursorPosition);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
+    method public int getNewCursorPosition();
+    method public String getText();
+    property public final androidx.compose.ui.text.AnnotatedString annotatedString;
+    property public final int newCursorPosition;
+    property public final String text;
+  }
+
+  public final class DeleteAllCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public DeleteAllCommand();
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+  }
+
+  public final class DeleteSurroundingTextCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public DeleteSurroundingTextCommand(int lengthBeforeCursor, int lengthAfterCursor);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public int getLengthAfterCursor();
+    method public int getLengthBeforeCursor();
+    property public final int lengthAfterCursor;
+    property public final int lengthBeforeCursor;
+  }
+
+  public final class DeleteSurroundingTextInCodePointsCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public DeleteSurroundingTextInCodePointsCommand(int lengthBeforeCursor, int lengthAfterCursor);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public int getLengthAfterCursor();
+    method public int getLengthBeforeCursor();
+    property public final int lengthAfterCursor;
+    property public final int lengthBeforeCursor;
+  }
+
+  public interface EditCommand {
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+  }
+
+  public final class EditProcessor {
+    ctor public EditProcessor();
+    method public androidx.compose.ui.text.input.TextFieldValue apply(java.util.List<? extends androidx.compose.ui.text.input.EditCommand> editCommands);
+    method public void reset(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.TextInputSession? textInputSession);
+    method public androidx.compose.ui.text.input.TextFieldValue toTextFieldValue();
+  }
+
+  public final class EditingBuffer {
+    ctor public EditingBuffer(androidx.compose.ui.text.AnnotatedString text, long selection);
+  }
+
+  public final class FinishComposingTextCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public FinishComposingTextCommand();
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+  }
+
+  @kotlin.jvm.JvmInline public final value class ImeAction {
+    field public static final androidx.compose.ui.text.input.ImeAction.Companion Companion;
+  }
+
+  public static final class ImeAction.Companion {
+    method public int getDefault();
+    method public int getDone();
+    method public int getGo();
+    method public int getNext();
+    method public int getNone();
+    method public int getPrevious();
+    method public int getSearch();
+    method public int getSend();
+    property public final int Default;
+    property public final int Done;
+    property public final int Go;
+    property public final int Next;
+    property public final int None;
+    property public final int Previous;
+    property public final int Search;
+    property public final int Send;
+  }
+
+  @androidx.compose.runtime.Immutable public final class ImeOptions {
+    ctor public ImeOptions(optional boolean singleLine, optional int capitalization, optional boolean autoCorrect, optional int keyboardType, optional int imeAction);
+    method public androidx.compose.ui.text.input.ImeOptions copy(optional boolean singleLine, optional int capitalization, optional boolean autoCorrect, optional int keyboardType, optional int imeAction);
+    method public boolean getAutoCorrect();
+    method public int getCapitalization();
+    method public int getImeAction();
+    method public int getKeyboardType();
+    method public boolean getSingleLine();
+    property public final boolean autoCorrect;
+    property public final int capitalization;
+    property public final int imeAction;
+    property public final int keyboardType;
+    property public final boolean singleLine;
+    field public static final androidx.compose.ui.text.input.ImeOptions.Companion Companion;
+  }
+
+  public static final class ImeOptions.Companion {
+    method public androidx.compose.ui.text.input.ImeOptions getDefault();
+    property public final androidx.compose.ui.text.input.ImeOptions Default;
+  }
+
+  @Deprecated public interface InputEventCallback {
+    method @Deprecated public void onEditCommands(java.util.List<? extends androidx.compose.ui.text.input.EditCommand> editCommands);
+    method @Deprecated public void onImeAction(int imeAction);
+  }
+
+  @kotlin.jvm.JvmInline public final value class KeyboardCapitalization {
+    field public static final androidx.compose.ui.text.input.KeyboardCapitalization.Companion Companion;
+  }
+
+  public static final class KeyboardCapitalization.Companion {
+    method public int getCharacters();
+    method public int getNone();
+    method public int getSentences();
+    method public int getWords();
+    property public final int Characters;
+    property public final int None;
+    property public final int Sentences;
+    property public final int Words;
+  }
+
+  @kotlin.jvm.JvmInline public final value class KeyboardType {
+    field public static final androidx.compose.ui.text.input.KeyboardType.Companion Companion;
+  }
+
+  public static final class KeyboardType.Companion {
+    method public int getAscii();
+    method public int getDecimal();
+    method public int getEmail();
+    method public int getNumber();
+    method public int getNumberPassword();
+    method public int getPassword();
+    method public int getPhone();
+    method public int getText();
+    method public int getUri();
+    property public final int Ascii;
+    property public final int Decimal;
+    property public final int Email;
+    property public final int Number;
+    property public final int NumberPassword;
+    property public final int Password;
+    property public final int Phone;
+    property public final int Text;
+    property public final int Uri;
+  }
+
+  public final class MoveCursorCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public MoveCursorCommand(int amount);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public int getAmount();
+    property public final int amount;
+  }
+
+  public interface OffsetMapping {
+    method public int originalToTransformed(int offset);
+    method public int transformedToOriginal(int offset);
+    field public static final androidx.compose.ui.text.input.OffsetMapping.Companion Companion;
+  }
+
+  public static final class OffsetMapping.Companion {
+    method public androidx.compose.ui.text.input.OffsetMapping getIdentity();
+    property public final androidx.compose.ui.text.input.OffsetMapping Identity;
+  }
+
+  public final class PasswordVisualTransformation implements androidx.compose.ui.text.input.VisualTransformation {
+    ctor public PasswordVisualTransformation(optional char mask);
+    method public androidx.compose.ui.text.input.TransformedText filter(androidx.compose.ui.text.AnnotatedString text);
+    method public char getMask();
+    property public final char mask;
+  }
+
+  @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInput {
+    method public void releaseInputFocus();
+    method public void requestInputFocus();
+  }
+
+  @androidx.compose.ui.text.ExperimentalTextApi public interface PlatformTextInputAdapter {
+    method public android.view.inputmethod.InputConnection? createInputConnection(android.view.inputmethod.EditorInfo outAttrs);
+    method public default void onDisposed();
+  }
+
+  @androidx.compose.runtime.Immutable @androidx.compose.ui.text.ExperimentalTextApi public fun interface PlatformTextInputPlugin<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
+    method public T createAdapter(androidx.compose.ui.text.input.PlatformTextInput platformTextInput, android.view.View view);
+  }
+
+  @androidx.compose.runtime.Stable @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInputPluginRegistry {
+    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
+  }
+
+  @androidx.compose.ui.text.InternalTextApi public final class PlatformTextInputPluginRegistryImpl implements androidx.compose.ui.text.input.PlatformTextInputPluginRegistry {
+    ctor public PlatformTextInputPluginRegistryImpl(kotlin.jvm.functions.Function2<? super androidx.compose.ui.text.input.PlatformTextInputPlugin<?>,? super androidx.compose.ui.text.input.PlatformTextInput,? extends androidx.compose.ui.text.input.PlatformTextInputAdapter> factory);
+    method public androidx.compose.ui.text.input.PlatformTextInputAdapter? getFocusedAdapter();
+    method @androidx.compose.ui.text.InternalTextApi public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> androidx.compose.ui.text.input.PlatformTextInputPluginRegistryImpl.AdapterHandle<T> getOrCreateAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
+    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
+    property public final androidx.compose.ui.text.input.PlatformTextInputAdapter? focusedAdapter;
+  }
+
+  @androidx.compose.ui.text.InternalTextApi public static final class PlatformTextInputPluginRegistryImpl.AdapterHandle<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
+    ctor public PlatformTextInputPluginRegistryImpl.AdapterHandle(T adapter, kotlin.jvm.functions.Function0<java.lang.Boolean> onDispose);
+    method public boolean dispose();
+    method public T getAdapter();
+    property public final T adapter;
+  }
+
+  public interface PlatformTextInputService {
+    method public void hideSoftwareKeyboard();
+    method public default void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
+    method public void showSoftwareKeyboard();
+    method public void startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
+    method public void stopInput();
+    method public void updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+  }
+
+  public final class SetComposingRegionCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public SetComposingRegionCommand(int start, int end);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public int getEnd();
+    method public int getStart();
+    property public final int end;
+    property public final int start;
+  }
+
+  public final class SetComposingTextCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public SetComposingTextCommand(androidx.compose.ui.text.AnnotatedString annotatedString, int newCursorPosition);
+    ctor public SetComposingTextCommand(String text, int newCursorPosition);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
+    method public int getNewCursorPosition();
+    method public String getText();
+    property public final androidx.compose.ui.text.AnnotatedString annotatedString;
+    property public final int newCursorPosition;
+    property public final String text;
+  }
+
+  public final class SetSelectionCommand implements androidx.compose.ui.text.input.EditCommand {
+    ctor public SetSelectionCommand(int start, int end);
+    method public void applyTo(androidx.compose.ui.text.input.EditingBuffer buffer);
+    method public int getEnd();
+    method public int getStart();
+    property public final int end;
+    property public final int start;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextFieldValue {
+    ctor public TextFieldValue(androidx.compose.ui.text.AnnotatedString annotatedString, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
+    ctor public TextFieldValue(optional String text, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
+    method public androidx.compose.ui.text.input.TextFieldValue copy(optional androidx.compose.ui.text.AnnotatedString annotatedString, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
+    method public androidx.compose.ui.text.input.TextFieldValue copy(String text, optional long selection, optional androidx.compose.ui.text.TextRange? composition);
+    method public androidx.compose.ui.text.AnnotatedString getAnnotatedString();
+    method public androidx.compose.ui.text.TextRange? getComposition();
+    method public long getSelection();
+    method public String getText();
+    property public final androidx.compose.ui.text.AnnotatedString annotatedString;
+    property public final androidx.compose.ui.text.TextRange? composition;
+    property public final long selection;
+    property public final String text;
+    field public static final androidx.compose.ui.text.input.TextFieldValue.Companion Companion;
+  }
+
+  public static final class TextFieldValue.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.input.TextFieldValue,java.lang.Object> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.compose.ui.text.input.TextFieldValue,java.lang.Object> Saver;
+  }
+
+  public final class TextFieldValueKt {
+    method public static androidx.compose.ui.text.AnnotatedString getSelectedText(androidx.compose.ui.text.input.TextFieldValue);
+    method public static androidx.compose.ui.text.AnnotatedString getTextAfterSelection(androidx.compose.ui.text.input.TextFieldValue, int maxChars);
+    method public static androidx.compose.ui.text.AnnotatedString getTextBeforeSelection(androidx.compose.ui.text.input.TextFieldValue, int maxChars);
+  }
+
+  public class TextInputService {
+    ctor public TextInputService(androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
+    method @Deprecated public final void hideSoftwareKeyboard();
+    method @Deprecated public final void showSoftwareKeyboard();
+    method public androidx.compose.ui.text.input.TextInputSession startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
+    method public void stopInput(androidx.compose.ui.text.input.TextInputSession session);
+  }
+
+  public final class TextInputSession {
+    ctor public TextInputSession(androidx.compose.ui.text.input.TextInputService textInputService, androidx.compose.ui.text.input.PlatformTextInputService platformTextInputService);
+    method public void dispose();
+    method public boolean hideSoftwareKeyboard();
+    method public boolean isOpen();
+    method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
+    method public boolean showSoftwareKeyboard();
+    method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    property public final boolean isOpen;
+  }
+
+  public final class TransformedText {
+    ctor public TransformedText(androidx.compose.ui.text.AnnotatedString text, androidx.compose.ui.text.input.OffsetMapping offsetMapping);
+    method public androidx.compose.ui.text.input.OffsetMapping getOffsetMapping();
+    method public androidx.compose.ui.text.AnnotatedString getText();
+    property public final androidx.compose.ui.text.input.OffsetMapping offsetMapping;
+    property public final androidx.compose.ui.text.AnnotatedString text;
+  }
+
+  @androidx.compose.runtime.Immutable public fun interface VisualTransformation {
+    method public androidx.compose.ui.text.input.TransformedText filter(androidx.compose.ui.text.AnnotatedString text);
+    field public static final androidx.compose.ui.text.input.VisualTransformation.Companion Companion;
+  }
+
+  public static final class VisualTransformation.Companion {
+    method public androidx.compose.ui.text.input.VisualTransformation getNone();
+    property public final androidx.compose.ui.text.input.VisualTransformation None;
+  }
+
+}
+
+package androidx.compose.ui.text.intl {
+
+  @androidx.compose.runtime.Immutable public final class Locale {
+    ctor public Locale(String languageTag);
+    method public String getLanguage();
+    method public String getRegion();
+    method public String getScript();
+    method public String toLanguageTag();
+    property public final String language;
+    property public final String region;
+    property public final String script;
+    field public static final androidx.compose.ui.text.intl.Locale.Companion Companion;
+  }
+
+  public static final class Locale.Companion {
+    method public androidx.compose.ui.text.intl.Locale getCurrent();
+    property public final androidx.compose.ui.text.intl.Locale current;
+  }
+
+  @androidx.compose.runtime.Immutable public final class LocaleList implements java.util.Collection<androidx.compose.ui.text.intl.Locale> kotlin.jvm.internal.markers.KMappedMarker {
+    ctor public LocaleList(androidx.compose.ui.text.intl.Locale... locales);
+    ctor public LocaleList(String languageTags);
+    ctor public LocaleList(java.util.List<androidx.compose.ui.text.intl.Locale> localeList);
+    method public operator boolean contains(androidx.compose.ui.text.intl.Locale element);
+    method public boolean containsAll(java.util.Collection<E!> elements);
+    method public operator androidx.compose.ui.text.intl.Locale get(int i);
+    method public java.util.List<androidx.compose.ui.text.intl.Locale> getLocaleList();
+    method public int getSize();
+    method public boolean isEmpty();
+    method public java.util.Iterator<androidx.compose.ui.text.intl.Locale> iterator();
+    property public final java.util.List<androidx.compose.ui.text.intl.Locale> localeList;
+    property public int size;
+    field public static final androidx.compose.ui.text.intl.LocaleList.Companion Companion;
+  }
+
+  public static final class LocaleList.Companion {
+    method public androidx.compose.ui.text.intl.LocaleList getCurrent();
+    property public final androidx.compose.ui.text.intl.LocaleList current;
+  }
+
+}
+
+package androidx.compose.ui.text.platform {
+
+  @androidx.compose.ui.text.InternalTextApi public final class URLSpanCache {
+    ctor public URLSpanCache();
+    method public android.text.style.URLSpan toURLSpan(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
+  }
+
+}
+
+package androidx.compose.ui.text.platform.extensions {
+
+  public final class TtsAnnotationExtensions_androidKt {
+    method public static android.text.style.TtsSpan toSpan(androidx.compose.ui.text.TtsAnnotation);
+    method public static android.text.style.TtsSpan toSpan(androidx.compose.ui.text.VerbatimTtsAnnotation);
+  }
+
+}
+
+package androidx.compose.ui.text.style {
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class BaselineShift {
+    ctor public BaselineShift(float multiplier);
+    method public float getMultiplier();
+    property public final float multiplier;
+    field public static final androidx.compose.ui.text.style.BaselineShift.Companion Companion;
+  }
+
+  public static final class BaselineShift.Companion {
+    method public float getNone();
+    method public float getSubscript();
+    method public float getSuperscript();
+    property public final float None;
+    property public final float Subscript;
+    property public final float Superscript;
+  }
+
+  public final class BaselineShiftKt {
+    method @androidx.compose.runtime.Stable public static float lerp(float start, float stop, float fraction);
+  }
+
+  @kotlin.jvm.JvmInline public final value class Hyphens {
+    field public static final androidx.compose.ui.text.style.Hyphens.Companion Companion;
+  }
+
+  public static final class Hyphens.Companion {
+    method public int getAuto();
+    method public int getNone();
+    property public final int Auto;
+    property public final int None;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class LineBreak {
+    ctor public LineBreak(int strategy, int strictness, int wordBreak);
+    method public int copy(optional int strategy, optional int strictness, optional int wordBreak);
+    method public int getStrategy();
+    method public int getStrictness();
+    method public int getWordBreak();
+    property public final int strategy;
+    property public final int strictness;
+    property public final int wordBreak;
+    field public static final androidx.compose.ui.text.style.LineBreak.Companion Companion;
+  }
+
+  public static final class LineBreak.Companion {
+    method public int getHeading();
+    method public int getParagraph();
+    method public int getSimple();
+    property public final int Heading;
+    property public final int Paragraph;
+    property public final int Simple;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class LineBreak.Strategy {
+    field public static final androidx.compose.ui.text.style.LineBreak.Strategy.Companion Companion;
+  }
+
+  public static final class LineBreak.Strategy.Companion {
+    method public int getBalanced();
+    method public int getHighQuality();
+    method public int getSimple();
+    property public final int Balanced;
+    property public final int HighQuality;
+    property public final int Simple;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class LineBreak.Strictness {
+    field public static final androidx.compose.ui.text.style.LineBreak.Strictness.Companion Companion;
+  }
+
+  public static final class LineBreak.Strictness.Companion {
+    method public int getDefault();
+    method public int getLoose();
+    method public int getNormal();
+    method public int getStrict();
+    property public final int Default;
+    property public final int Loose;
+    property public final int Normal;
+    property public final int Strict;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class LineBreak.WordBreak {
+    field public static final androidx.compose.ui.text.style.LineBreak.WordBreak.Companion Companion;
+  }
+
+  public static final class LineBreak.WordBreak.Companion {
+    method public int getDefault();
+    method public int getPhrase();
+    property public final int Default;
+    property public final int Phrase;
+  }
+
+  public final class LineHeightStyle {
+    ctor public LineHeightStyle(float alignment, int trim);
+    method public float getAlignment();
+    method public int getTrim();
+    property public final float alignment;
+    property public final int trim;
+    field public static final androidx.compose.ui.text.style.LineHeightStyle.Companion Companion;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class LineHeightStyle.Alignment {
+    ctor public LineHeightStyle.Alignment(float topRatio);
+    field public static final androidx.compose.ui.text.style.LineHeightStyle.Alignment.Companion Companion;
+  }
+
+  public static final class LineHeightStyle.Alignment.Companion {
+    method public float getBottom();
+    method public float getCenter();
+    method public float getProportional();
+    method public float getTop();
+    property public final float Bottom;
+    property public final float Center;
+    property public final float Proportional;
+    property public final float Top;
+  }
+
+  public static final class LineHeightStyle.Companion {
+    method public androidx.compose.ui.text.style.LineHeightStyle getDefault();
+    property public final androidx.compose.ui.text.style.LineHeightStyle Default;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class LineHeightStyle.Trim {
+    field public static final androidx.compose.ui.text.style.LineHeightStyle.Trim.Companion Companion;
+  }
+
+  public static final class LineHeightStyle.Trim.Companion {
+    method public int getBoth();
+    method public int getFirstLineTop();
+    method public int getLastLineBottom();
+    method public int getNone();
+    property public final int Both;
+    property public final int FirstLineTop;
+    property public final int LastLineBottom;
+    property public final int None;
+  }
+
+  public enum ResolvedTextDirection {
+    method public static androidx.compose.ui.text.style.ResolvedTextDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.text.style.ResolvedTextDirection[] values();
+    enum_constant public static final androidx.compose.ui.text.style.ResolvedTextDirection Ltr;
+    enum_constant public static final androidx.compose.ui.text.style.ResolvedTextDirection Rtl;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextAlign {
+    field public static final androidx.compose.ui.text.style.TextAlign.Companion Companion;
+  }
+
+  public static final class TextAlign.Companion {
+    method public int getCenter();
+    method public int getEnd();
+    method public int getJustify();
+    method public int getLeft();
+    method public int getRight();
+    method public int getStart();
+    method public java.util.List<androidx.compose.ui.text.style.TextAlign> values();
+    property public final int Center;
+    property public final int End;
+    property public final int Justify;
+    property public final int Left;
+    property public final int Right;
+    property public final int Start;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextDecoration {
+    method public operator boolean contains(androidx.compose.ui.text.style.TextDecoration other);
+    method public int getMask();
+    method public operator androidx.compose.ui.text.style.TextDecoration plus(androidx.compose.ui.text.style.TextDecoration decoration);
+    property public final int mask;
+    field public static final androidx.compose.ui.text.style.TextDecoration.Companion Companion;
+  }
+
+  public static final class TextDecoration.Companion {
+    method public androidx.compose.ui.text.style.TextDecoration combine(java.util.List<androidx.compose.ui.text.style.TextDecoration> decorations);
+    method public androidx.compose.ui.text.style.TextDecoration getLineThrough();
+    method public androidx.compose.ui.text.style.TextDecoration getNone();
+    method public androidx.compose.ui.text.style.TextDecoration getUnderline();
+    property public final androidx.compose.ui.text.style.TextDecoration LineThrough;
+    property public final androidx.compose.ui.text.style.TextDecoration None;
+    property public final androidx.compose.ui.text.style.TextDecoration Underline;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextDirection {
+    field public static final androidx.compose.ui.text.style.TextDirection.Companion Companion;
+  }
+
+  public static final class TextDirection.Companion {
+    method public int getContent();
+    method public int getContentOrLtr();
+    method public int getContentOrRtl();
+    method public int getLtr();
+    method public int getRtl();
+    property public final int Content;
+    property public final int ContentOrLtr;
+    property public final int ContentOrRtl;
+    property public final int Ltr;
+    property public final int Rtl;
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextGeometricTransform {
+    ctor public TextGeometricTransform(optional float scaleX, optional float skewX);
+    method public androidx.compose.ui.text.style.TextGeometricTransform copy(optional float scaleX, optional float skewX);
+    method public float getScaleX();
+    method public float getSkewX();
+    property public final float scaleX;
+    property public final float skewX;
+    field public static final androidx.compose.ui.text.style.TextGeometricTransform.Companion Companion;
+  }
+
+  public static final class TextGeometricTransform.Companion {
+  }
+
+  public final class TextGeometricTransformKt {
+    method public static androidx.compose.ui.text.style.TextGeometricTransform lerp(androidx.compose.ui.text.style.TextGeometricTransform start, androidx.compose.ui.text.style.TextGeometricTransform stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextIndent {
+    ctor public TextIndent(optional long firstLine, optional long restLine);
+    method public androidx.compose.ui.text.style.TextIndent copy(optional long firstLine, optional long restLine);
+    method public long getFirstLine();
+    method public long getRestLine();
+    property public final long firstLine;
+    property public final long restLine;
+    field public static final androidx.compose.ui.text.style.TextIndent.Companion Companion;
+  }
+
+  public static final class TextIndent.Companion {
+    method public androidx.compose.ui.text.style.TextIndent getNone();
+    property public final androidx.compose.ui.text.style.TextIndent None;
+  }
+
+  public final class TextIndentKt {
+    method public static androidx.compose.ui.text.style.TextIndent lerp(androidx.compose.ui.text.style.TextIndent start, androidx.compose.ui.text.style.TextIndent stop, float fraction);
+  }
+
+  @androidx.compose.runtime.Immutable public final class TextMotion {
+    field public static final androidx.compose.ui.text.style.TextMotion.Companion Companion;
+  }
+
+  public static final class TextMotion.Companion {
+    method public androidx.compose.ui.text.style.TextMotion getAnimated();
+    method public androidx.compose.ui.text.style.TextMotion getStatic();
+    property public final androidx.compose.ui.text.style.TextMotion Animated;
+    property public final androidx.compose.ui.text.style.TextMotion Static;
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextOverflow {
+    field public static final androidx.compose.ui.text.style.TextOverflow.Companion Companion;
+  }
+
+  public static final class TextOverflow.Companion {
+    method public int getClip();
+    method public int getEllipsis();
+    method public int getVisible();
+    property public final int Clip;
+    property public final int Ellipsis;
+    property public final int Visible;
+  }
+
+}
+
diff --git a/compose/ui/ui-text/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-text/api/restricted_1.5.0-beta01.txt
index b203bb5..4a40acd 100644
--- a/compose/ui/ui-text/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-text/api/restricted_1.5.0-beta01.txt
@@ -16,7 +16,6 @@
     method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<java.lang.String>> getStringAnnotations(String tag, int start, int end);
     method public String getText();
     method public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.TtsAnnotation>> getTtsAnnotations(int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.UrlAnnotation>> getUrlAnnotations(int start, int end);
     method public boolean hasStringAnnotations(String tag, int start, int end);
     method @androidx.compose.runtime.Stable public operator androidx.compose.ui.text.AnnotatedString plus(androidx.compose.ui.text.AnnotatedString other);
     method public androidx.compose.ui.text.AnnotatedString subSequence(int startIndex, int endIndex);
@@ -34,8 +33,6 @@
     method public void addStringAnnotation(String tag, String annotation, int start, int end);
     method public void addStyle(androidx.compose.ui.text.ParagraphStyle style, int start, int end);
     method public void addStyle(androidx.compose.ui.text.SpanStyle style, int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public void addTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation, int start, int end);
-    method @androidx.compose.ui.text.ExperimentalTextApi public void addUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation, int start, int end);
     method public void append(androidx.compose.ui.text.AnnotatedString text);
     method public void append(androidx.compose.ui.text.AnnotatedString text, int start, int end);
     method public androidx.compose.ui.text.AnnotatedString.Builder append(char char);
@@ -50,7 +47,6 @@
     method public int pushStyle(androidx.compose.ui.text.ParagraphStyle style);
     method public int pushStyle(androidx.compose.ui.text.SpanStyle style);
     method public int pushTtsAnnotation(androidx.compose.ui.text.TtsAnnotation ttsAnnotation);
-    method @androidx.compose.ui.text.ExperimentalTextApi public int pushUrlAnnotation(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
     method public androidx.compose.ui.text.AnnotatedString toAnnotatedString();
     property public final int length;
   }
@@ -81,9 +77,6 @@
     method public static androidx.compose.ui.text.AnnotatedString decapitalize(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
     method public static androidx.compose.ui.text.AnnotatedString toLowerCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
     method public static androidx.compose.ui.text.AnnotatedString toUpperCase(androidx.compose.ui.text.AnnotatedString, optional androidx.compose.ui.text.intl.LocaleList localeList);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.TtsAnnotation ttsAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.UrlAnnotation urlAnnotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static inline <R> R withAnnotation(androidx.compose.ui.text.AnnotatedString.Builder, String tag, String annotation, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
     method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.ParagraphStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
     method public static inline <R> R withStyle(androidx.compose.ui.text.AnnotatedString.Builder, androidx.compose.ui.text.SpanStyle style, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString.Builder,? extends R> block);
   }
@@ -99,12 +92,6 @@
     property public final int None;
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalTextApi {
-  }
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalTextApi {
-  }
-
   public final class MultiParagraph {
     ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.FontFamily.Resolver fontFamilyResolver, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis);
     ctor @Deprecated public MultiParagraph(androidx.compose.ui.text.AnnotatedString annotatedString, androidx.compose.ui.text.TextStyle style, optional java.util.List<androidx.compose.ui.text.AnnotatedString.Range<androidx.compose.ui.text.Placeholder>> placeholders, optional int maxLines, optional boolean ellipsis, float width, androidx.compose.ui.unit.Density density, androidx.compose.ui.text.font.Font.ResourceLoader resourceLoader);
@@ -616,12 +603,6 @@
   public abstract sealed class TtsAnnotation {
   }
 
-  @androidx.compose.ui.text.ExperimentalTextApi public final class UrlAnnotation {
-    ctor public UrlAnnotation(String url);
-    method public String getUrl();
-    property public final String url;
-  }
-
   public final class VerbatimTtsAnnotation extends androidx.compose.ui.text.TtsAnnotation {
     ctor public VerbatimTtsAnnotation(String verbatim);
     method public String getVerbatim();
@@ -630,13 +611,6 @@
 
 }
 
-package androidx.compose.ui.text.android {
-
-  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.ERROR, message="This is internal API that may change frequently and without warning.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY}) public @interface InternalPlatformTextApi {
-  }
-
-}
-
 package androidx.compose.ui.text.font {
 
   public abstract class AndroidFont implements androidx.compose.ui.text.font.Font {
@@ -742,7 +716,6 @@
   public final class FontKt {
     method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy);
-    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.ui.text.font.Font Font(int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.text.font.FontFamily toFontFamily(androidx.compose.ui.text.font.Font);
   }
 
@@ -885,15 +858,11 @@
 
   public final class ResourceFont implements androidx.compose.ui.text.font.Font {
     method public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style);
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.ResourceFont copy(optional int resId, optional androidx.compose.ui.text.font.FontWeight weight, optional int style, optional int loadingStrategy, optional androidx.compose.ui.text.font.FontVariation.Settings variationSettings);
     method public int getResId();
     method public int getStyle();
-    method @androidx.compose.ui.text.ExperimentalTextApi public androidx.compose.ui.text.font.FontVariation.Settings getVariationSettings();
     method public androidx.compose.ui.text.font.FontWeight getWeight();
-    property @androidx.compose.ui.text.ExperimentalTextApi public int loadingStrategy;
     property public final int resId;
     property public int style;
-    property @androidx.compose.ui.text.ExperimentalTextApi public final androidx.compose.ui.text.font.FontVariation.Settings variationSettings;
     property public androidx.compose.ui.text.font.FontWeight weight;
   }
 
@@ -1083,39 +1052,6 @@
     property public final char mask;
   }
 
-  @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInput {
-    method public void releaseInputFocus();
-    method public void requestInputFocus();
-  }
-
-  @androidx.compose.ui.text.ExperimentalTextApi public interface PlatformTextInputAdapter {
-    method public android.view.inputmethod.InputConnection? createInputConnection(android.view.inputmethod.EditorInfo outAttrs);
-    method public default void onDisposed();
-  }
-
-  @androidx.compose.runtime.Immutable @androidx.compose.ui.text.ExperimentalTextApi public fun interface PlatformTextInputPlugin<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
-    method public T createAdapter(androidx.compose.ui.text.input.PlatformTextInput platformTextInput, android.view.View view);
-  }
-
-  @androidx.compose.runtime.Stable @androidx.compose.ui.text.ExperimentalTextApi public sealed interface PlatformTextInputPluginRegistry {
-    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-  }
-
-  @androidx.compose.ui.text.InternalTextApi public final class PlatformTextInputPluginRegistryImpl implements androidx.compose.ui.text.input.PlatformTextInputPluginRegistry {
-    ctor public PlatformTextInputPluginRegistryImpl(kotlin.jvm.functions.Function2<? super androidx.compose.ui.text.input.PlatformTextInputPlugin<?>,? super androidx.compose.ui.text.input.PlatformTextInput,? extends androidx.compose.ui.text.input.PlatformTextInputAdapter> factory);
-    method public androidx.compose.ui.text.input.PlatformTextInputAdapter? getFocusedAdapter();
-    method @androidx.compose.ui.text.InternalTextApi public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> androidx.compose.ui.text.input.PlatformTextInputPluginRegistryImpl.AdapterHandle<T> getOrCreateAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-    method @androidx.compose.runtime.Composable public <T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> T rememberAdapter(androidx.compose.ui.text.input.PlatformTextInputPlugin<T> plugin);
-    property public final androidx.compose.ui.text.input.PlatformTextInputAdapter? focusedAdapter;
-  }
-
-  @androidx.compose.ui.text.InternalTextApi public static final class PlatformTextInputPluginRegistryImpl.AdapterHandle<T extends androidx.compose.ui.text.input.PlatformTextInputAdapter> {
-    ctor public PlatformTextInputPluginRegistryImpl.AdapterHandle(T adapter, kotlin.jvm.functions.Function0<java.lang.Boolean> onDispose);
-    method public boolean dispose();
-    method public T getAdapter();
-    property public final T adapter;
-  }
-
   public interface PlatformTextInputService {
     method public void hideSoftwareKeyboard();
     method public default void notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
@@ -1263,15 +1199,6 @@
 
 }
 
-package androidx.compose.ui.text.platform {
-
-  @androidx.compose.ui.text.InternalTextApi public final class URLSpanCache {
-    ctor public URLSpanCache();
-    method public android.text.style.URLSpan toURLSpan(androidx.compose.ui.text.UrlAnnotation urlAnnotation);
-  }
-
-}
-
 package androidx.compose.ui.text.platform.extensions {
 
   public final class TtsAnnotationExtensions_androidKt {
diff --git a/compose/ui/ui-text/api/restricted_current.txt b/compose/ui/ui-text/api/restricted_current.txt
index e93dd1d..ba3232f 100644
--- a/compose/ui/ui-text/api/restricted_current.txt
+++ b/compose/ui/ui-text/api/restricted_current.txt
@@ -1125,6 +1125,7 @@
     method public void startInput(androidx.compose.ui.text.input.TextFieldValue value, androidx.compose.ui.text.input.ImeOptions imeOptions, kotlin.jvm.functions.Function1<? super java.util.List<? extends androidx.compose.ui.text.input.EditCommand>,kotlin.Unit> onEditCommand, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.input.ImeAction,kotlin.Unit> onImeActionPerformed);
     method public void stopInput();
     method public void updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public default void updateTextLayoutResult(androidx.compose.ui.text.input.TextFieldValue textFieldValue, androidx.compose.ui.text.TextLayoutResult textLayoutResult, long textLayoutPositionInWindow, androidx.compose.ui.geometry.Rect innerTextFieldBounds, androidx.compose.ui.geometry.Rect decorationBoxBounds);
   }
 
   public final class SetComposingRegionCommand implements androidx.compose.ui.text.input.EditCommand {
@@ -1200,6 +1201,7 @@
     method public boolean notifyFocusedRect(androidx.compose.ui.geometry.Rect rect);
     method public boolean showSoftwareKeyboard();
     method public boolean updateState(androidx.compose.ui.text.input.TextFieldValue? oldValue, androidx.compose.ui.text.input.TextFieldValue newValue);
+    method public boolean updateTextLayoutResult(androidx.compose.ui.text.input.TextFieldValue textFieldValue, androidx.compose.ui.text.TextLayoutResult textLayoutResult, long textLayoutPositionInWindow, androidx.compose.ui.geometry.Rect innerTextFieldBounds, androidx.compose.ui.geometry.Rect decorationBoxBounds);
     property public final boolean isOpen;
   }
 
diff --git a/compose/ui/ui-text/benchmark/lint-baseline.xml b/compose/ui/ui-text/benchmark/lint-baseline.xml
index 94985f2..6431b9c 100644
--- a/compose/ui/ui-text/benchmark/lint-baseline.xml
+++ b/compose/ui/ui-text/benchmark/lint-baseline.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
 
     <issue
         id="SoonBlockedPrivateApi"
-        message="Reflective access to freeTextLayoutCaches will throw an exception when targeting API 33 and above"
+        message="Reflective access to freeTextLayoutCaches will throw an exception when targeting API 34 and above"
         errorLine1="            val freeCaches = Canvas::class.java.getDeclaredMethod(&quot;freeTextLayoutCaches&quot;)"
         errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index 2903ae2..4486d14 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-text/lint-baseline.xml b/compose/ui/ui-text/lint-baseline.xml
index 7cf329d..4f7f4b5 100644
--- a/compose/ui/ui-text/lint-baseline.xml
+++ b/compose/ui/ui-text/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanInlineOptIn"
@@ -37,4 +37,103 @@
             file="src/commonMain/kotlin/androidx/compose/ui/text/font/FontVariation.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method createCharSequence has parameter &apos;resolveTypeface&apos; with type Function4&lt;? super FontFamily, ? super FontWeight, ? super FontStyle, ? super FontSynthesis, ? extends Typeface>."
+        errorLine1="    resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;resolveTypeface&apos; with type Function4&lt;? super FontFamily, ? super FontWeight, ? super FontStyle, ? super FontSynthesis, ? extends Typeface>."
+        errorLine1="        val resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface ="
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphIntrinsics.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method transform has parameter &apos;transform&apos; with type Function3&lt;? super String, ? super Integer, ? super Integer, ? extends String>."
+        errorLine1="    transform: (String, Int, Int) -> String"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method transform has parameter &apos;transform&apos; with type Function3&lt;? super String, ? super Integer, ? super Integer, String>."
+        errorLine1="    transform: (String, Int, Int) -> String"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setSpanStyles has parameter &apos;resolveTypeface&apos; with type Function4&lt;? super FontFamily, ? super FontWeight, ? super FontStyle, ? super FontSynthesis, ? extends Typeface>."
+        errorLine1="    resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setFontAttributes has parameter &apos;resolveTypeface&apos; with type Function4&lt;? super FontFamily, ? super FontWeight, ? super FontStyle, ? super FontSynthesis, ? extends Typeface>."
+        errorLine1="    resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method flattenFontStylesAndApply has parameter &apos;block&apos; with type Function3&lt;? super SpanStyle, ? super Integer, ? super Integer, Unit>."
+        errorLine1="    block: (SpanStyle, Int, Int) -> Unit"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method takeOrElse has parameter &apos;block&apos; with type Function0&lt;Float>."
+        errorLine1="private fun Float.takeOrElse(block: () -> Float): Float {"
+        errorLine2="                                    ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method startInput has parameter &apos;onImeActionPerformed&apos; with type Function1&lt;? super ImeAction, Unit>."
+        errorLine1="        onImeActionPerformed: (ImeAction) -> Unit"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method startInput has parameter &apos;onImeActionPerformed&apos; with type Function1&lt;? super ImeAction, Unit>."
+        errorLine1="        onImeActionPerformed: (ImeAction) -> Unit"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method applySpanStyle has parameter &apos;resolveTypeface&apos; with type Function4&lt;? super FontFamily, ? super FontWeight, ? super FontStyle, ? super FontSynthesis, ? extends Typeface>."
+        errorLine1="    resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
index 07dece7..2fd7809 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
@@ -51,7 +51,6 @@
     spanStyles: List<AnnotatedString.Range<SpanStyle>>,
     placeholders: List<AnnotatedString.Range<Placeholder>>,
     density: Density,
-    @Suppress("PrimitiveInLambda")
     resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,
     useEmojiCompat: Boolean,
 ): CharSequence {
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphIntrinsics.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphIntrinsics.android.kt
index 2f5b75a..8dfa683 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphIntrinsics.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphIntrinsics.android.kt
@@ -87,7 +87,6 @@
     )
 
     init {
-        @Suppress("PrimitiveInLambda")
         val resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface =
             { fontFamily, fontWeight, fontStyle, fontSynthesis ->
                 val result = fontFamilyResolver.resolve(
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
index 7ce7fc6..972b324 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/SpannableExtensions.android.kt
@@ -172,7 +172,6 @@
     contextTextStyle: TextStyle,
     spanStyles: List<AnnotatedString.Range<SpanStyle>>,
     density: Density,
-    @Suppress("PrimitiveInLambda")
     resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,
 ) {
 
@@ -277,7 +276,6 @@
 private fun Spannable.setFontAttributes(
     contextTextStyle: TextStyle,
     spanStyles: List<AnnotatedString.Range<SpanStyle>>,
-    @Suppress("PrimitiveInLambda")
     resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,
 ) {
     val fontRelatedSpanStyles = spanStyles.fastFilter {
@@ -330,7 +328,6 @@
 internal fun flattenFontStylesAndApply(
     contextFontSpanStyle: SpanStyle?,
     spanStyles: List<AnnotatedString.Range<SpanStyle>>,
-    @Suppress("PrimitiveInLambda")
     block: (SpanStyle, Int, Int) -> Unit
 ) {
     // quick way out for single SpanStyle or empty list.
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
index 542afe0..ee6daab 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/extensions/TextPaintExtensions.android.kt
@@ -45,7 +45,6 @@
  */
 internal fun AndroidTextPaint.applySpanStyle(
     style: SpanStyle,
-    @Suppress("PrimitiveInLambda")
     resolveTypeface: (FontFamily?, FontWeight, FontStyle, FontSynthesis) -> Typeface,
     density: Density,
     requiresLetterSpacing: Boolean = false,
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
index 7eb0595..d447d62 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/AnnotatedString.kt
@@ -904,7 +904,6 @@
  * @return newly allocated transformed AnnotatedString
  */
 internal expect fun AnnotatedString.transform(
-    @Suppress("PrimitiveInLambda")
     transform: (String, Int, Int) -> String
 ): AnnotatedString
 
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt
index 4394291..cf58e6a 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/MathUtils.kt
@@ -28,10 +28,7 @@
 /**
  * Subtracts [right] from [this], and if an overflow occurs returns result of [defaultValue].
  */
-internal inline fun Int.subtractExactOrElse(
-    right: Int,
-    defaultValue: () -> Int
-): Int {
+internal inline fun Int.subtractExactOrElse(right: Int, defaultValue: () -> Int): Int {
     val result = this - right
     // HD 2-12 Overflow iff the arguments have different signs and
     // the sign of the result is different from the sign of x
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
index 74046f65..f7d277d 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/TextInputService.kt
@@ -16,8 +16,10 @@
 
 package androidx.compose.ui.text.input
 
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.text.AtomicReference
+import androidx.compose.ui.text.TextLayoutResult
 
 /**
  * Handles communication with the IME. Informs about the IME changes via [EditCommand]s and
@@ -51,7 +53,6 @@
         value: TextFieldValue,
         imeOptions: ImeOptions,
         onEditCommand: (List<EditCommand>) -> Unit,
-        @Suppress("PrimitiveInLambda")
         onImeActionPerformed: (ImeAction) -> Unit
     ): TextInputSession {
         platformTextInputService.startInput(
@@ -111,6 +112,7 @@
     // TODO(b/183448615) @InternalTextApi
     fun hideSoftwareKeyboard(): Unit = platformTextInputService.hideSoftwareKeyboard()
 }
+
 /**
  * Represents a input session for interactions between a soft keyboard and editable text.
  *
@@ -175,6 +177,33 @@
     }
 
     /**
+     * Notify the input service of layout and position changes.
+     *
+     * @param textFieldValue the text field's [TextFieldValue]
+     * @param textLayoutResult the text field's [TextLayoutResult]
+     * @param textLayoutPositionInWindow position of the text field relative to the window
+     * @param innerTextFieldBounds visible bounds of the text field in local coordinates, or an
+     *   empty rectangle if the text field is not visible
+     * @param decorationBoxBounds visible bounds of the decoration box in local coordinates, or an
+     *   empty rectangle if the decoration box is not visible
+     */
+    fun updateTextLayoutResult(
+        textFieldValue: TextFieldValue,
+        textLayoutResult: TextLayoutResult,
+        textLayoutPositionInWindow: Offset,
+        innerTextFieldBounds: Rect,
+        decorationBoxBounds: Rect
+    ) = ensureOpenSession {
+        platformTextInputService.updateTextLayoutResult(
+            textFieldValue,
+            textLayoutResult,
+            textLayoutPositionInWindow,
+            innerTextFieldBounds,
+            decorationBoxBounds
+        )
+    }
+
+    /**
      * Notify IME about the new [TextFieldValue] and latest state of the editing buffer. [oldValue]
      * is the state of the buffer before the changes applied by the [newValue].
      *
@@ -243,7 +272,6 @@
         value: TextFieldValue,
         imeOptions: ImeOptions,
         onEditCommand: (List<EditCommand>) -> Unit,
-        @Suppress("PrimitiveInLambda")
         onImeActionPerformed: (ImeAction) -> Unit
     )
 
@@ -270,10 +298,10 @@
      */
     fun hideSoftwareKeyboard()
 
-    /*
+    /**
      * Notify the new editor model to IME.
      *
-     * @see TextInputService.updateState
+     * @see TextInputSession.updateState
      */
     fun updateState(oldValue: TextFieldValue?, newValue: TextFieldValue)
 
@@ -287,4 +315,18 @@
     // TODO(b/262648050) Try to find a better API.
     fun notifyFocusedRect(rect: Rect) {
     }
+
+    /**
+     * Notify the input service of layout and position changes.
+     *
+     * @see TextInputSession.updateTextLayoutResult
+     */
+    fun updateTextLayoutResult(
+        textFieldValue: TextFieldValue,
+        textLayoutResult: TextLayoutResult,
+        textLayoutPositionInWindow: Offset,
+        innerTextFieldBounds: Rect,
+        decorationBoxBounds: Rect
+    ) {
+    }
 }
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt
index 9924fbd..517236f 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextForegroundStyle.kt
@@ -143,9 +143,6 @@
     else -> this.copy(alpha = this.alpha * alpha)
 }
 
-private fun Float.takeOrElse(
-    @Suppress("PrimitiveInLambda")
-    block: () -> Float
-): Float {
+private fun Float.takeOrElse(block: () -> Float): Float {
     return if (this.isNaN()) block() else this
 }
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
index 1a40f8c..62a82c2 100644
--- a/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
+++ b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
@@ -27,7 +27,6 @@
  * @return newly allocated transformed AnnotatedString
  */
 internal actual fun AnnotatedString.transform(
-    @Suppress("PrimitiveInLambda")
     transform: (String, Int, Int) -> String
 ): AnnotatedString {
     val transitions = sortedSetOf(0, text.length)
diff --git a/compose/ui/ui-tooling-data/api/1.5.0-beta01.txt b/compose/ui/ui-tooling-data/api/1.5.0-beta01.txt
index 899fa9f..e6f50d0 100644
--- a/compose/ui/ui-tooling-data/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-tooling-data/api/1.5.0-beta01.txt
@@ -1,127 +1 @@
 // Signature format: 4.0
-package androidx.compose.ui.tooling.data {
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class CallGroup extends androidx.compose.ui.tooling.data.Group {
-    ctor public CallGroup(Object? key, String? name, androidx.compose.ui.unit.IntRect box, androidx.compose.ui.tooling.data.SourceLocation? location, Object? identity, java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters, java.util.Collection<?> data, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children, boolean isInline);
-    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ContextCache {
-    ctor public ContextCache();
-    method public void clear();
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public abstract sealed class Group {
-    method public final androidx.compose.ui.unit.IntRect getBox();
-    method public final java.util.Collection<androidx.compose.ui.tooling.data.Group> getChildren();
-    method public final java.util.Collection<java.lang.Object> getData();
-    method public final Object? getIdentity();
-    method public final Object? getKey();
-    method public final androidx.compose.ui.tooling.data.SourceLocation? getLocation();
-    method public java.util.List<androidx.compose.ui.layout.ModifierInfo> getModifierInfo();
-    method public final String? getName();
-    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
-    method public final boolean isInline();
-    property public final androidx.compose.ui.unit.IntRect box;
-    property public final java.util.Collection<androidx.compose.ui.tooling.data.Group> children;
-    property public final java.util.Collection<java.lang.Object> data;
-    property public final Object? identity;
-    property public final boolean isInline;
-    property public final Object? key;
-    property public final androidx.compose.ui.tooling.data.SourceLocation? location;
-    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
-    property public final String? name;
-    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class JoinedKey {
-    ctor public JoinedKey(Object? left, Object? right);
-    method public Object? component1();
-    method public Object? component2();
-    method public androidx.compose.ui.tooling.data.JoinedKey copy(Object? left, Object? right);
-    method public Object? getLeft();
-    method public Object? getRight();
-    property public final Object? left;
-    property public final Object? right;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class NodeGroup extends androidx.compose.ui.tooling.data.Group {
-    ctor public NodeGroup(Object? key, Object node, androidx.compose.ui.unit.IntRect box, java.util.Collection<?> data, java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children);
-    method public Object getNode();
-    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
-    property public final Object node;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ParameterInformation {
-    ctor public ParameterInformation(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
-    method public String component1();
-    method public Object? component2();
-    method public boolean component3();
-    method public boolean component4();
-    method public boolean component5();
-    method public String? component6();
-    method public boolean component7();
-    method public androidx.compose.ui.tooling.data.ParameterInformation copy(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
-    method public boolean getCompared();
-    method public boolean getFromDefault();
-    method public String? getInlineClass();
-    method public String getName();
-    method public boolean getStable();
-    method public boolean getStatic();
-    method public Object? getValue();
-    property public final boolean compared;
-    property public final boolean fromDefault;
-    property public final String? inlineClass;
-    property public final String name;
-    property public final boolean stable;
-    property public final boolean static;
-    property public final Object? value;
-  }
-
-  public final class SlotTreeKt {
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static androidx.compose.ui.tooling.data.Group asTree(androidx.compose.runtime.tooling.CompositionData);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> findParameters(androidx.compose.runtime.tooling.CompositionGroup, optional androidx.compose.ui.tooling.data.ContextCache? cache);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static String? getPosition(androidx.compose.ui.tooling.data.Group);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static <T> T? mapTree(androidx.compose.runtime.tooling.CompositionData, kotlin.jvm.functions.Function3<? super androidx.compose.runtime.tooling.CompositionGroup,? super androidx.compose.ui.tooling.data.SourceContext,? super java.util.List<? extends T>,? extends T> factory, optional androidx.compose.ui.tooling.data.ContextCache cache);
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public interface SourceContext {
-    method public androidx.compose.ui.unit.IntRect getBounds();
-    method public int getDepth();
-    method public androidx.compose.ui.tooling.data.SourceLocation? getLocation();
-    method public String? getName();
-    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
-    method public default boolean isInline();
-    property public abstract androidx.compose.ui.unit.IntRect bounds;
-    property public abstract int depth;
-    property public default boolean isInline;
-    property public abstract androidx.compose.ui.tooling.data.SourceLocation? location;
-    property public abstract String? name;
-    property public abstract java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class SourceLocation {
-    ctor public SourceLocation(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
-    method public int component1();
-    method public int component2();
-    method public int component3();
-    method public String? component4();
-    method public int component5();
-    method public androidx.compose.ui.tooling.data.SourceLocation copy(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
-    method public int getLength();
-    method public int getLineNumber();
-    method public int getOffset();
-    method public int getPackageHash();
-    method public String? getSourceFile();
-    property public final int length;
-    property public final int lineNumber;
-    property public final int offset;
-    property public final int packageHash;
-    property public final String? sourceFile;
-  }
-
-  @kotlin.RequiresOptIn(message="This API is for tooling only and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface UiToolingDataApi {
-  }
-
-}
-
diff --git a/compose/ui/ui-tooling-data/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-tooling-data/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..899fa9f
--- /dev/null
+++ b/compose/ui/ui-tooling-data/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,127 @@
+// Signature format: 4.0
+package androidx.compose.ui.tooling.data {
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class CallGroup extends androidx.compose.ui.tooling.data.Group {
+    ctor public CallGroup(Object? key, String? name, androidx.compose.ui.unit.IntRect box, androidx.compose.ui.tooling.data.SourceLocation? location, Object? identity, java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters, java.util.Collection<?> data, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children, boolean isInline);
+    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ContextCache {
+    ctor public ContextCache();
+    method public void clear();
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public abstract sealed class Group {
+    method public final androidx.compose.ui.unit.IntRect getBox();
+    method public final java.util.Collection<androidx.compose.ui.tooling.data.Group> getChildren();
+    method public final java.util.Collection<java.lang.Object> getData();
+    method public final Object? getIdentity();
+    method public final Object? getKey();
+    method public final androidx.compose.ui.tooling.data.SourceLocation? getLocation();
+    method public java.util.List<androidx.compose.ui.layout.ModifierInfo> getModifierInfo();
+    method public final String? getName();
+    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
+    method public final boolean isInline();
+    property public final androidx.compose.ui.unit.IntRect box;
+    property public final java.util.Collection<androidx.compose.ui.tooling.data.Group> children;
+    property public final java.util.Collection<java.lang.Object> data;
+    property public final Object? identity;
+    property public final boolean isInline;
+    property public final Object? key;
+    property public final androidx.compose.ui.tooling.data.SourceLocation? location;
+    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
+    property public final String? name;
+    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class JoinedKey {
+    ctor public JoinedKey(Object? left, Object? right);
+    method public Object? component1();
+    method public Object? component2();
+    method public androidx.compose.ui.tooling.data.JoinedKey copy(Object? left, Object? right);
+    method public Object? getLeft();
+    method public Object? getRight();
+    property public final Object? left;
+    property public final Object? right;
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class NodeGroup extends androidx.compose.ui.tooling.data.Group {
+    ctor public NodeGroup(Object? key, Object node, androidx.compose.ui.unit.IntRect box, java.util.Collection<?> data, java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children);
+    method public Object getNode();
+    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
+    property public final Object node;
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ParameterInformation {
+    ctor public ParameterInformation(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
+    method public String component1();
+    method public Object? component2();
+    method public boolean component3();
+    method public boolean component4();
+    method public boolean component5();
+    method public String? component6();
+    method public boolean component7();
+    method public androidx.compose.ui.tooling.data.ParameterInformation copy(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
+    method public boolean getCompared();
+    method public boolean getFromDefault();
+    method public String? getInlineClass();
+    method public String getName();
+    method public boolean getStable();
+    method public boolean getStatic();
+    method public Object? getValue();
+    property public final boolean compared;
+    property public final boolean fromDefault;
+    property public final String? inlineClass;
+    property public final String name;
+    property public final boolean stable;
+    property public final boolean static;
+    property public final Object? value;
+  }
+
+  public final class SlotTreeKt {
+    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static androidx.compose.ui.tooling.data.Group asTree(androidx.compose.runtime.tooling.CompositionData);
+    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> findParameters(androidx.compose.runtime.tooling.CompositionGroup, optional androidx.compose.ui.tooling.data.ContextCache? cache);
+    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static String? getPosition(androidx.compose.ui.tooling.data.Group);
+    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static <T> T? mapTree(androidx.compose.runtime.tooling.CompositionData, kotlin.jvm.functions.Function3<? super androidx.compose.runtime.tooling.CompositionGroup,? super androidx.compose.ui.tooling.data.SourceContext,? super java.util.List<? extends T>,? extends T> factory, optional androidx.compose.ui.tooling.data.ContextCache cache);
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public interface SourceContext {
+    method public androidx.compose.ui.unit.IntRect getBounds();
+    method public int getDepth();
+    method public androidx.compose.ui.tooling.data.SourceLocation? getLocation();
+    method public String? getName();
+    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
+    method public default boolean isInline();
+    property public abstract androidx.compose.ui.unit.IntRect bounds;
+    property public abstract int depth;
+    property public default boolean isInline;
+    property public abstract androidx.compose.ui.tooling.data.SourceLocation? location;
+    property public abstract String? name;
+    property public abstract java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
+  }
+
+  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class SourceLocation {
+    ctor public SourceLocation(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
+    method public int component1();
+    method public int component2();
+    method public int component3();
+    method public String? component4();
+    method public int component5();
+    method public androidx.compose.ui.tooling.data.SourceLocation copy(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
+    method public int getLength();
+    method public int getLineNumber();
+    method public int getOffset();
+    method public int getPackageHash();
+    method public String? getSourceFile();
+    property public final int length;
+    property public final int lineNumber;
+    property public final int offset;
+    property public final int packageHash;
+    property public final String? sourceFile;
+  }
+
+  @kotlin.RequiresOptIn(message="This API is for tooling only and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface UiToolingDataApi {
+  }
+
+}
+
diff --git a/compose/ui/ui-tooling-data/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-tooling-data/api/restricted_1.5.0-beta01.txt
index 899fa9f..e6f50d0 100644
--- a/compose/ui/ui-tooling-data/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-tooling-data/api/restricted_1.5.0-beta01.txt
@@ -1,127 +1 @@
 // Signature format: 4.0
-package androidx.compose.ui.tooling.data {
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class CallGroup extends androidx.compose.ui.tooling.data.Group {
-    ctor public CallGroup(Object? key, String? name, androidx.compose.ui.unit.IntRect box, androidx.compose.ui.tooling.data.SourceLocation? location, Object? identity, java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters, java.util.Collection<?> data, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children, boolean isInline);
-    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ContextCache {
-    ctor public ContextCache();
-    method public void clear();
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public abstract sealed class Group {
-    method public final androidx.compose.ui.unit.IntRect getBox();
-    method public final java.util.Collection<androidx.compose.ui.tooling.data.Group> getChildren();
-    method public final java.util.Collection<java.lang.Object> getData();
-    method public final Object? getIdentity();
-    method public final Object? getKey();
-    method public final androidx.compose.ui.tooling.data.SourceLocation? getLocation();
-    method public java.util.List<androidx.compose.ui.layout.ModifierInfo> getModifierInfo();
-    method public final String? getName();
-    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
-    method public final boolean isInline();
-    property public final androidx.compose.ui.unit.IntRect box;
-    property public final java.util.Collection<androidx.compose.ui.tooling.data.Group> children;
-    property public final java.util.Collection<java.lang.Object> data;
-    property public final Object? identity;
-    property public final boolean isInline;
-    property public final Object? key;
-    property public final androidx.compose.ui.tooling.data.SourceLocation? location;
-    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
-    property public final String? name;
-    property public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class JoinedKey {
-    ctor public JoinedKey(Object? left, Object? right);
-    method public Object? component1();
-    method public Object? component2();
-    method public androidx.compose.ui.tooling.data.JoinedKey copy(Object? left, Object? right);
-    method public Object? getLeft();
-    method public Object? getRight();
-    property public final Object? left;
-    property public final Object? right;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class NodeGroup extends androidx.compose.ui.tooling.data.Group {
-    ctor public NodeGroup(Object? key, Object node, androidx.compose.ui.unit.IntRect box, java.util.Collection<?> data, java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo, java.util.Collection<? extends androidx.compose.ui.tooling.data.Group> children);
-    method public Object getNode();
-    property public java.util.List<androidx.compose.ui.layout.ModifierInfo> modifierInfo;
-    property public final Object node;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class ParameterInformation {
-    ctor public ParameterInformation(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
-    method public String component1();
-    method public Object? component2();
-    method public boolean component3();
-    method public boolean component4();
-    method public boolean component5();
-    method public String? component6();
-    method public boolean component7();
-    method public androidx.compose.ui.tooling.data.ParameterInformation copy(String name, Object? value, boolean fromDefault, boolean static, boolean compared, String? inlineClass, boolean stable);
-    method public boolean getCompared();
-    method public boolean getFromDefault();
-    method public String? getInlineClass();
-    method public String getName();
-    method public boolean getStable();
-    method public boolean getStatic();
-    method public Object? getValue();
-    property public final boolean compared;
-    property public final boolean fromDefault;
-    property public final String? inlineClass;
-    property public final String name;
-    property public final boolean stable;
-    property public final boolean static;
-    property public final Object? value;
-  }
-
-  public final class SlotTreeKt {
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static androidx.compose.ui.tooling.data.Group asTree(androidx.compose.runtime.tooling.CompositionData);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> findParameters(androidx.compose.runtime.tooling.CompositionGroup, optional androidx.compose.ui.tooling.data.ContextCache? cache);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static String? getPosition(androidx.compose.ui.tooling.data.Group);
-    method @androidx.compose.ui.tooling.data.UiToolingDataApi public static <T> T? mapTree(androidx.compose.runtime.tooling.CompositionData, kotlin.jvm.functions.Function3<? super androidx.compose.runtime.tooling.CompositionGroup,? super androidx.compose.ui.tooling.data.SourceContext,? super java.util.List<? extends T>,? extends T> factory, optional androidx.compose.ui.tooling.data.ContextCache cache);
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public interface SourceContext {
-    method public androidx.compose.ui.unit.IntRect getBounds();
-    method public int getDepth();
-    method public androidx.compose.ui.tooling.data.SourceLocation? getLocation();
-    method public String? getName();
-    method public java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> getParameters();
-    method public default boolean isInline();
-    property public abstract androidx.compose.ui.unit.IntRect bounds;
-    property public abstract int depth;
-    property public default boolean isInline;
-    property public abstract androidx.compose.ui.tooling.data.SourceLocation? location;
-    property public abstract String? name;
-    property public abstract java.util.List<androidx.compose.ui.tooling.data.ParameterInformation> parameters;
-  }
-
-  @androidx.compose.ui.tooling.data.UiToolingDataApi public final class SourceLocation {
-    ctor public SourceLocation(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
-    method public int component1();
-    method public int component2();
-    method public int component3();
-    method public String? component4();
-    method public int component5();
-    method public androidx.compose.ui.tooling.data.SourceLocation copy(int lineNumber, int offset, int length, String? sourceFile, int packageHash);
-    method public int getLength();
-    method public int getLineNumber();
-    method public int getOffset();
-    method public int getPackageHash();
-    method public String? getSourceFile();
-    property public final int length;
-    property public final int lineNumber;
-    property public final int offset;
-    property public final int packageHash;
-    property public final String? sourceFile;
-  }
-
-  @kotlin.RequiresOptIn(message="This API is for tooling only and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface UiToolingDataApi {
-  }
-
-}
-
diff --git a/compose/ui/ui-tooling-data/build.gradle b/compose/ui/ui-tooling-data/build.gradle
index b69203b..a2ba3a7 100644
--- a/compose/ui/ui-tooling-data/build.gradle
+++ b/compose/ui/ui-tooling-data/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -30,6 +31,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-tooling-preview/api/current.txt b/compose/ui/ui-tooling-preview/api/current.txt
index ed0685d9..80f655a 100644
--- a/compose/ui/ui-tooling-preview/api/current.txt
+++ b/compose/ui/ui-tooling-preview/api/current.txt
@@ -69,6 +69,15 @@
     method public abstract androidx.compose.ui.tooling.preview.Preview[] value();
   }
 
+  @androidx.compose.ui.tooling.preview.Preview(name="Red", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.RED_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Blue", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.BLUE_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Green", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.GREEN_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Yellow", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.YELLOW_DOMINATED_EXAMPLE) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewDynamicColors {
+  }
+
+  @androidx.compose.ui.tooling.preview.Preview(name="85%", fontScale=0.85f) @androidx.compose.ui.tooling.preview.Preview(name="100%", fontScale=1.0f) @androidx.compose.ui.tooling.preview.Preview(name="115%", fontScale=1.15f) @androidx.compose.ui.tooling.preview.Preview(name="130%", fontScale=1.3f) @androidx.compose.ui.tooling.preview.Preview(name="150%", fontScale=1.5f) @androidx.compose.ui.tooling.preview.Preview(name="180%", fontScale=1.8f) @androidx.compose.ui.tooling.preview.Preview(name="200%", fontScale=2.0f) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewFontScale {
+  }
+
+  @androidx.compose.ui.tooling.preview.Preview(name="Light") @androidx.compose.ui.tooling.preview.Preview(name="Dark", uiMode=android.content.res.Configuration.UI_MODE_NIGHT_YES | android.content.res.Configuration.UI_MODE_TYPE_NORMAL) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewLightDark {
+  }
+
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface PreviewParameter {
     method public abstract int limit() default kotlin.jvm.internal.IntCompanionObject.MAX_VALUE;
     method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<?>> provider();
@@ -83,6 +92,9 @@
     property public abstract kotlin.sequences.Sequence<T> values;
   }
 
+  @androidx.compose.ui.tooling.preview.Preview(name="Phone", device=androidx.compose.ui.tooling.preview.Devices.PHONE) @androidx.compose.ui.tooling.preview.Preview(name="Phone - Landscape", device="spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420") @androidx.compose.ui.tooling.preview.Preview(name="Unfolded Foldable", device=androidx.compose.ui.tooling.preview.Devices.FOLDABLE) @androidx.compose.ui.tooling.preview.Preview(name="Tablet", device=androidx.compose.ui.tooling.preview.Devices.TABLET) @androidx.compose.ui.tooling.preview.Preview(name="Desktop", device=androidx.compose.ui.tooling.preview.Devices.DESKTOP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewScreenSizes {
+  }
+
   public final class Wallpapers {
     field public static final int BLUE_DOMINATED_EXAMPLE = 2; // 0x2
     field public static final int GREEN_DOMINATED_EXAMPLE = 1; // 0x1
diff --git a/compose/ui/ui-tooling-preview/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-tooling-preview/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..ed0685d9
--- /dev/null
+++ b/compose/ui/ui-tooling-preview/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,113 @@
+// Signature format: 4.0
+package androidx.compose.ui.tooling.preview {
+
+  public final class Devices {
+    field public static final String AUTOMOTIVE_1024p = "id:automotive_1024p_landscape";
+    field public static final String DEFAULT = "";
+    field public static final String DESKTOP = "spec:id=reference_desktop,shape=Normal,width=1920,height=1080,unit=dp,dpi=160";
+    field public static final String FOLDABLE = "spec:id=reference_foldable,shape=Normal,width=673,height=841,unit=dp,dpi=420";
+    field public static final androidx.compose.ui.tooling.preview.Devices INSTANCE;
+    field public static final String NEXUS_10 = "name:Nexus 10";
+    field public static final String NEXUS_5 = "id:Nexus 5";
+    field public static final String NEXUS_5X = "id:Nexus 5X";
+    field public static final String NEXUS_6 = "id:Nexus 6";
+    field public static final String NEXUS_6P = "id:Nexus 6P";
+    field public static final String NEXUS_7 = "id:Nexus 7";
+    field public static final String NEXUS_7_2013 = "id:Nexus 7 2013";
+    field public static final String NEXUS_9 = "id:Nexus 9";
+    field public static final String PHONE = "spec:id=reference_phone,shape=Normal,width=411,height=891,unit=dp,dpi=420";
+    field public static final String PIXEL = "id:pixel";
+    field public static final String PIXEL_2 = "id:pixel_2";
+    field public static final String PIXEL_2_XL = "id:pixel_2_xl";
+    field public static final String PIXEL_3 = "id:pixel_3";
+    field public static final String PIXEL_3A = "id:pixel_3a";
+    field public static final String PIXEL_3A_XL = "id:pixel_3a_xl";
+    field public static final String PIXEL_3_XL = "id:pixel_3_xl";
+    field public static final String PIXEL_4 = "id:pixel_4";
+    field public static final String PIXEL_4_XL = "id:pixel_4_xl";
+    field public static final String PIXEL_C = "id:pixel_c";
+    field public static final String PIXEL_XL = "id:pixel_xl";
+    field public static final String TABLET = "spec:id=reference_tablet,shape=Normal,width=1280,height=800,unit=dp,dpi=240";
+    field public static final String TV_1080p = "spec:shape=Normal,width=1920,height=1080,unit=dp,dpi=420";
+    field public static final String TV_720p = "spec:shape=Normal,width=1280,height=720,unit=dp,dpi=420";
+    field public static final String WEAR_OS_LARGE_ROUND = "id:wearos_large_round";
+    field public static final String WEAR_OS_RECT = "id:wearos_rect";
+    field public static final String WEAR_OS_SMALL_ROUND = "id:wearos_small_round";
+    field public static final String WEAR_OS_SQUARE = "id:wearos_square";
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface Preview {
+    method public abstract int apiLevel() default -1;
+    method public abstract long backgroundColor() default 0;
+    method public abstract String device() default androidx.compose.ui.tooling.preview.Devices.DEFAULT;
+    method public abstract float fontScale() default 1.0;
+    method public abstract String group() default "";
+    method public abstract int heightDp() default -1;
+    method public abstract String locale() default "";
+    method public abstract String name() default "";
+    method public abstract boolean showBackground() default false;
+    method public abstract boolean showSystemUi() default false;
+    method public abstract int uiMode() default 0;
+    method public abstract int wallpaper() default androidx.compose.ui.tooling.preview.Wallpapers.NONE;
+    method public abstract int widthDp() default -1;
+    property public abstract int apiLevel;
+    property public abstract long backgroundColor;
+    property public abstract String device;
+    property public abstract float fontScale;
+    property public abstract String group;
+    property public abstract int heightDp;
+    property public abstract String locale;
+    property public abstract String name;
+    property public abstract boolean showBackground;
+    property public abstract boolean showSystemUi;
+    property public abstract int uiMode;
+    property public abstract int wallpaper;
+    property public abstract int widthDp;
+  }
+
+  @kotlin.annotation.MustBeDocumented @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public static @interface Preview.Container {
+    method public abstract androidx.compose.ui.tooling.preview.Preview[] value();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface PreviewParameter {
+    method public abstract int limit() default kotlin.jvm.internal.IntCompanionObject.MAX_VALUE;
+    method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<?>> provider();
+    property public abstract int limit;
+    property public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<?>> provider;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface PreviewParameterProvider<T> {
+    method public default int getCount();
+    method public kotlin.sequences.Sequence<T> getValues();
+    property public default int count;
+    property public abstract kotlin.sequences.Sequence<T> values;
+  }
+
+  public final class Wallpapers {
+    field public static final int BLUE_DOMINATED_EXAMPLE = 2; // 0x2
+    field public static final int GREEN_DOMINATED_EXAMPLE = 1; // 0x1
+    field public static final androidx.compose.ui.tooling.preview.Wallpapers INSTANCE;
+    field public static final int NONE = -1; // 0xffffffff
+    field public static final int RED_DOMINATED_EXAMPLE = 0; // 0x0
+    field public static final int YELLOW_DOMINATED_EXAMPLE = 3; // 0x3
+  }
+
+}
+
+package androidx.compose.ui.tooling.preview.datasource {
+
+  public class CollectionPreviewParameterProvider<T> implements androidx.compose.ui.tooling.preview.PreviewParameterProvider<T> {
+    ctor public CollectionPreviewParameterProvider(java.util.Collection<? extends T> collection);
+    method public kotlin.sequences.Sequence<T> getValues();
+    property public kotlin.sequences.Sequence<T> values;
+  }
+
+  public final class LoremIpsum implements androidx.compose.ui.tooling.preview.PreviewParameterProvider<java.lang.String> {
+    ctor public LoremIpsum();
+    ctor public LoremIpsum(int words);
+    method public kotlin.sequences.Sequence<java.lang.String> getValues();
+    property public kotlin.sequences.Sequence<java.lang.String> values;
+  }
+
+}
+
diff --git a/compose/ui/ui-tooling-preview/api/restricted_current.txt b/compose/ui/ui-tooling-preview/api/restricted_current.txt
index ed0685d9..80f655a 100644
--- a/compose/ui/ui-tooling-preview/api/restricted_current.txt
+++ b/compose/ui/ui-tooling-preview/api/restricted_current.txt
@@ -69,6 +69,15 @@
     method public abstract androidx.compose.ui.tooling.preview.Preview[] value();
   }
 
+  @androidx.compose.ui.tooling.preview.Preview(name="Red", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.RED_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Blue", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.BLUE_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Green", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.GREEN_DOMINATED_EXAMPLE) @androidx.compose.ui.tooling.preview.Preview(name="Yellow", wallpaper=androidx.compose.ui.tooling.preview.Wallpapers.YELLOW_DOMINATED_EXAMPLE) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewDynamicColors {
+  }
+
+  @androidx.compose.ui.tooling.preview.Preview(name="85%", fontScale=0.85f) @androidx.compose.ui.tooling.preview.Preview(name="100%", fontScale=1.0f) @androidx.compose.ui.tooling.preview.Preview(name="115%", fontScale=1.15f) @androidx.compose.ui.tooling.preview.Preview(name="130%", fontScale=1.3f) @androidx.compose.ui.tooling.preview.Preview(name="150%", fontScale=1.5f) @androidx.compose.ui.tooling.preview.Preview(name="180%", fontScale=1.8f) @androidx.compose.ui.tooling.preview.Preview(name="200%", fontScale=2.0f) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewFontScale {
+  }
+
+  @androidx.compose.ui.tooling.preview.Preview(name="Light") @androidx.compose.ui.tooling.preview.Preview(name="Dark", uiMode=android.content.res.Configuration.UI_MODE_NIGHT_YES | android.content.res.Configuration.UI_MODE_TYPE_NORMAL) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewLightDark {
+  }
+
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface PreviewParameter {
     method public abstract int limit() default kotlin.jvm.internal.IntCompanionObject.MAX_VALUE;
     method public abstract kotlin.reflect.KClass<? extends androidx.compose.ui.tooling.preview.PreviewParameterProvider<?>> provider();
@@ -83,6 +92,9 @@
     property public abstract kotlin.sequences.Sequence<T> values;
   }
 
+  @androidx.compose.ui.tooling.preview.Preview(name="Phone", device=androidx.compose.ui.tooling.preview.Devices.PHONE) @androidx.compose.ui.tooling.preview.Preview(name="Phone - Landscape", device="spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420") @androidx.compose.ui.tooling.preview.Preview(name="Unfolded Foldable", device=androidx.compose.ui.tooling.preview.Devices.FOLDABLE) @androidx.compose.ui.tooling.preview.Preview(name="Tablet", device=androidx.compose.ui.tooling.preview.Devices.TABLET) @androidx.compose.ui.tooling.preview.Preview(name="Desktop", device=androidx.compose.ui.tooling.preview.Devices.DESKTOP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface PreviewScreenSizes {
+  }
+
   public final class Wallpapers {
     field public static final int BLUE_DOMINATED_EXAMPLE = 2; // 0x2
     field public static final int GREEN_DOMINATED_EXAMPLE = 1; // 0x1
diff --git a/compose/ui/ui-tooling-preview/build.gradle b/compose/ui/ui-tooling-preview/build.gradle
index a2aa077..022bc02c 100644
--- a/compose/ui/ui-tooling-preview/build.gradle
+++ b/compose/ui/ui-tooling-preview/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -30,6 +31,7 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
 
     sourceSets {
         commonMain {
diff --git a/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/MultiPreviews.kt b/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/MultiPreviews.kt
new file mode 100644
index 0000000..866d472
--- /dev/null
+++ b/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/MultiPreviews.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.ui.tooling.preview
+
+import android.content.res.Configuration.UI_MODE_NIGHT_YES
+import android.content.res.Configuration.UI_MODE_TYPE_NORMAL
+import androidx.compose.ui.tooling.preview.Devices.DESKTOP
+import androidx.compose.ui.tooling.preview.Devices.FOLDABLE
+import androidx.compose.ui.tooling.preview.Devices.PHONE
+import androidx.compose.ui.tooling.preview.Devices.TABLET
+import androidx.compose.ui.tooling.preview.Wallpapers.BLUE_DOMINATED_EXAMPLE
+import androidx.compose.ui.tooling.preview.Wallpapers.GREEN_DOMINATED_EXAMPLE
+import androidx.compose.ui.tooling.preview.Wallpapers.RED_DOMINATED_EXAMPLE
+import androidx.compose.ui.tooling.preview.Wallpapers.YELLOW_DOMINATED_EXAMPLE
+
+/**
+ * A MultiPreview annotation for displaying a @[Composable] method using the screen sizes of five different reference devices.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(
+        AnnotationTarget.ANNOTATION_CLASS,
+        AnnotationTarget.FUNCTION
+)
+@Preview(name = "Phone", device = PHONE)
+@Preview(name = "Phone - Landscape",
+         device = "spec:width = 411dp, height = 891dp, orientation = landscape, dpi = 420")
+@Preview(name = "Unfolded Foldable", device = FOLDABLE)
+@Preview(name = "Tablet", device = TABLET)
+@Preview(name = "Desktop", device = DESKTOP)
+annotation class PreviewScreenSizes
+
+/**
+ * A MultiPreview annotation for desplaying a @[Composable] method using seven standard font sizes.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(
+        AnnotationTarget.ANNOTATION_CLASS,
+        AnnotationTarget.FUNCTION
+)
+@Preview(name = "85%", fontScale = 0.85f)
+@Preview(name = "100%", fontScale = 1.0f)
+@Preview(name = "115%", fontScale = 1.15f)
+@Preview(name = "130%", fontScale = 1.3f)
+@Preview(name = "150%", fontScale = 1.5f)
+@Preview(name = "180%", fontScale = 1.8f)
+@Preview(name = "200%", fontScale = 2f)
+annotation class PreviewFontScale
+
+/**
+ * A MultiPreview annotation for desplaying a @[Composable] method using light and dark themes.
+ *
+ * Note that the app theme should support dark and light modes for these previews to be different.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(
+        AnnotationTarget.ANNOTATION_CLASS,
+        AnnotationTarget.FUNCTION
+)
+@Preview(name = "Light")
+@Preview(name = "Dark", uiMode = UI_MODE_NIGHT_YES or UI_MODE_TYPE_NORMAL)
+annotation class PreviewLightDark
+
+/**
+ * A MultiPreview annotation for desplaying a @[Composable] method using four different wallpaper colors.
+ *
+ * Note that the app should use a dynamic theme for these previews to be different.
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(
+        AnnotationTarget.ANNOTATION_CLASS,
+        AnnotationTarget.FUNCTION
+)
+@Preview(name = "Red", wallpaper = RED_DOMINATED_EXAMPLE)
+@Preview(name = "Blue", wallpaper = BLUE_DOMINATED_EXAMPLE)
+@Preview(name = "Green", wallpaper = GREEN_DOMINATED_EXAMPLE)
+@Preview(name = "Yellow", wallpaper = YELLOW_DOMINATED_EXAMPLE)
+annotation class PreviewDynamicColors
diff --git a/compose/ui/ui-tooling/api/1.5.0-beta01.txt b/compose/ui/ui-tooling/api/1.5.0-beta01.txt
index df56c2d..486b41e 100644
--- a/compose/ui/ui-tooling/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-tooling/api/1.5.0-beta01.txt
@@ -1,11 +1,6 @@
 // Signature format: 4.0
 package androidx.compose.ui.tooling {
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class ComposableInvoker {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public void invokeComposable(String className, String methodName, androidx.compose.runtime.Composer composer, java.lang.Object?... args);
-    field @Deprecated public static final androidx.compose.ui.tooling.ComposableInvoker INSTANCE;
-  }
-
   public final class InspectableKt {
     method @Deprecated @androidx.compose.runtime.Composable public static void InInspectionModeOnly(kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
diff --git a/compose/ui/ui-tooling/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-tooling/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..df56c2d
--- /dev/null
+++ b/compose/ui/ui-tooling/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,25 @@
+// Signature format: 4.0
+package androidx.compose.ui.tooling {
+
+  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class ComposableInvoker {
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public void invokeComposable(String className, String methodName, androidx.compose.runtime.Composer composer, java.lang.Object?... args);
+    field @Deprecated public static final androidx.compose.ui.tooling.ComposableInvoker INSTANCE;
+  }
+
+  public final class InspectableKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void InInspectionModeOnly(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+}
+
+package androidx.compose.ui.tooling.animation {
+
+  public final class ToolingState<T> implements androidx.compose.runtime.State<T> {
+    ctor public ToolingState(T default);
+    method public T getValue();
+    method public void setValue(T!);
+    property public T value;
+  }
+
+}
+
diff --git a/compose/ui/ui-tooling/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-tooling/api/restricted_1.5.0-beta01.txt
index df56c2d..486b41e 100644
--- a/compose/ui/ui-tooling/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-tooling/api/restricted_1.5.0-beta01.txt
@@ -1,11 +1,6 @@
 // Signature format: 4.0
 package androidx.compose.ui.tooling {
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class ComposableInvoker {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public void invokeComposable(String className, String methodName, androidx.compose.runtime.Composer composer, java.lang.Object?... args);
-    field @Deprecated public static final androidx.compose.ui.tooling.ComposableInvoker INSTANCE;
-  }
-
   public final class InspectableKt {
     method @Deprecated @androidx.compose.runtime.Composable public static void InInspectionModeOnly(kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index ea90aee..4e12802 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-tooling/lint-baseline.xml b/compose/ui/ui-tooling/lint-baseline.xml
index 4d211c8..433880c 100644
--- a/compose/ui/ui-tooling/lint-baseline.xml
+++ b/compose/ui/ui-tooling/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -19,4 +19,13 @@
             file="src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor InfiniteTransitionClock has parameter &apos;maxDuration&apos; with type Function0&lt;Long>."
+        errorLine1="    private val maxDuration: () -> Long = { 0 }"
+        errorLine2="                             ~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/tooling/animation/clock/InfiniteTransitionClock.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
index a8dfc85..a63a2c0 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ComposeViewAdapterTest.kt
@@ -603,6 +603,10 @@
             "androidx.compose.ui.tooling.SimpleComposablePreviewKt",
             "Multipreview"
         )
+        assertRendersCorrectly(
+                "androidx.compose.ui.tooling.SimpleComposablePreviewKt",
+                "MultiPreviews"
+        )
     }
 
     /**
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
index 12bde52..4b4e147 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/SimpleComposablePreview.kt
@@ -29,8 +29,12 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewDynamicColors
+import androidx.compose.ui.tooling.preview.PreviewFontScale
+import androidx.compose.ui.tooling.preview.PreviewLightDark
 import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import androidx.compose.ui.tooling.preview.PreviewScreenSizes
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.viewmodel.compose.viewModel
 
@@ -155,6 +159,15 @@
     }
 }
 
+@PreviewDynamicColors
+@PreviewFontScale
+@PreviewLightDark
+@PreviewScreenSizes
+@Composable
+fun MultiPreviews() {
+    Text("MultiPreviews test")
+}
+
 class TestContentParameterProviderBoolean : PreviewParameterProvider<Boolean> {
     override val values: Sequence<Boolean>
         get() = sequenceOf(false, true)
diff --git a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/clock/InfiniteTransitionClock.kt b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/clock/InfiniteTransitionClock.kt
index e554283..2cc56af 100644
--- a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/clock/InfiniteTransitionClock.kt
+++ b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/animation/clock/InfiniteTransitionClock.kt
@@ -34,7 +34,6 @@
  */
 internal class InfiniteTransitionClock(
     override val animation: InfiniteTransitionComposeAnimation,
-    @Suppress("PrimitiveInLambda")
     private val maxDuration: () -> Long = { 0 }
 ) :
     ComposeAnimationClock<InfiniteTransitionComposeAnimation, TargetState<Any>> {
diff --git a/compose/ui/ui-unit/api/1.5.0-beta01.txt b/compose/ui/ui-unit/api/1.5.0-beta01.txt
index bc439ae..b58f3eb 100644
--- a/compose/ui/ui-unit/api/1.5.0-beta01.txt
+++ b/compose/ui/ui-unit/api/1.5.0-beta01.txt
@@ -194,9 +194,6 @@
     property public final long Zero;
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalUnitApi {
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntOffset {
     method @androidx.compose.runtime.Stable public operator int component1();
     method @androidx.compose.runtime.Stable public operator int component2();
diff --git a/compose/ui/ui-unit/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-unit/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..bc439ae
--- /dev/null
+++ b/compose/ui/ui-unit/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,417 @@
+// Signature format: 4.0
+package androidx.compose.ui.unit {
+
+  public final class AndroidDensity_androidKt {
+    method public static androidx.compose.ui.unit.Density Density(android.content.Context context);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Constraints {
+    ctor public Constraints(@kotlin.PublishedApi long value);
+    method public long copy(optional int minWidth, optional int maxWidth, optional int minHeight, optional int maxHeight);
+    method public boolean getHasBoundedHeight();
+    method public boolean getHasBoundedWidth();
+    method public boolean getHasFixedHeight();
+    method public boolean getHasFixedWidth();
+    method public int getMaxHeight();
+    method public int getMaxWidth();
+    method public int getMinHeight();
+    method public int getMinWidth();
+    method public boolean isZero();
+    property public final boolean hasBoundedHeight;
+    property public final boolean hasBoundedWidth;
+    property @androidx.compose.runtime.Stable public final boolean hasFixedHeight;
+    property @androidx.compose.runtime.Stable public final boolean hasFixedWidth;
+    property @androidx.compose.runtime.Stable public final boolean isZero;
+    property public final int maxHeight;
+    property public final int maxWidth;
+    property public final int minHeight;
+    property public final int minWidth;
+    field public static final androidx.compose.ui.unit.Constraints.Companion Companion;
+    field public static final int Infinity = 2147483647; // 0x7fffffff
+  }
+
+  public static final class Constraints.Companion {
+    method @androidx.compose.runtime.Stable public long fixed(int width, int height);
+    method @androidx.compose.runtime.Stable public long fixedHeight(int height);
+    method @androidx.compose.runtime.Stable public long fixedWidth(int width);
+  }
+
+  public final class ConstraintsKt {
+    method @androidx.compose.runtime.Stable public static long Constraints(optional int minWidth, optional int maxWidth, optional int minHeight, optional int maxHeight);
+    method public static long constrain(long, long otherConstraints);
+    method @androidx.compose.runtime.Stable public static long constrain(long, long size);
+    method @androidx.compose.runtime.Stable public static int constrainHeight(long, int height);
+    method @androidx.compose.runtime.Stable public static int constrainWidth(long, int width);
+    method @androidx.compose.runtime.Stable public static boolean isSatisfiedBy(long, long size);
+    method @androidx.compose.runtime.Stable public static long offset(long, optional int horizontal, optional int vertical);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmDefaultWithCompatibility public interface Density {
+    method public float getDensity();
+    method public float getFontScale();
+    method @androidx.compose.runtime.Stable public default int roundToPx(float);
+    method @androidx.compose.runtime.Stable public default int roundToPx(long);
+    method @androidx.compose.runtime.Stable public default float toDp(float);
+    method @androidx.compose.runtime.Stable public default float toDp(int);
+    method @androidx.compose.runtime.Stable public default float toDp(long);
+    method @androidx.compose.runtime.Stable public default long toDpSize(long);
+    method @androidx.compose.runtime.Stable public default float toPx(float);
+    method @androidx.compose.runtime.Stable public default float toPx(long);
+    method @androidx.compose.runtime.Stable public default androidx.compose.ui.geometry.Rect toRect(androidx.compose.ui.unit.DpRect);
+    method @androidx.compose.runtime.Stable public default long toSize(long);
+    method @androidx.compose.runtime.Stable public default long toSp(float);
+    method @androidx.compose.runtime.Stable public default long toSp(float);
+    method @androidx.compose.runtime.Stable public default long toSp(int);
+    property public abstract float density;
+    property public abstract float fontScale;
+  }
+
+  public final class DensityKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.Density Density(float density, optional float fontScale);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Dp implements java.lang.Comparable<androidx.compose.ui.unit.Dp> {
+    ctor public Dp(float value);
+    method @androidx.compose.runtime.Stable public operator int compareTo(float other);
+    method @androidx.compose.runtime.Stable public inline operator float div(float other);
+    method @androidx.compose.runtime.Stable public inline operator float div(float other);
+    method @androidx.compose.runtime.Stable public inline operator float div(int other);
+    method public float getValue();
+    method @androidx.compose.runtime.Stable public inline operator float minus(float other);
+    method @androidx.compose.runtime.Stable public inline operator float plus(float other);
+    method @androidx.compose.runtime.Stable public inline operator float times(float other);
+    method @androidx.compose.runtime.Stable public inline operator float times(int other);
+    method @androidx.compose.runtime.Stable public inline operator float unaryMinus();
+    property public final float value;
+    field public static final androidx.compose.ui.unit.Dp.Companion Companion;
+  }
+
+  public static final class Dp.Companion {
+    method public float getHairline();
+    method public float getInfinity();
+    method public float getUnspecified();
+    property public final float Hairline;
+    property public final float Infinity;
+    property public final float Unspecified;
+  }
+
+  public final class DpKt {
+    method @androidx.compose.runtime.Stable public static long DpOffset(float x, float y);
+    method @androidx.compose.runtime.Stable public static long DpSize(float width, float height);
+    method @androidx.compose.runtime.Stable public static inline float coerceAtLeast(float, float minimumValue);
+    method @androidx.compose.runtime.Stable public static inline float coerceAtMost(float, float maximumValue);
+    method @androidx.compose.runtime.Stable public static inline float coerceIn(float, float minimumValue, float maximumValue);
+    method public static long getCenter(long);
+    method public static inline float getDp(double);
+    method public static inline float getDp(float);
+    method public static inline float getDp(int);
+    method public static inline float getHeight(androidx.compose.ui.unit.DpRect);
+    method public static inline long getSize(androidx.compose.ui.unit.DpRect);
+    method public static inline float getWidth(androidx.compose.ui.unit.DpRect);
+    method public static inline boolean isFinite(float);
+    method public static inline boolean isSpecified(float);
+    method public static inline boolean isSpecified(long);
+    method public static inline boolean isSpecified(long);
+    method public static inline boolean isUnspecified(float);
+    method public static inline boolean isUnspecified(long);
+    method public static inline boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static float lerp(float start, float stop, float fraction);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method @androidx.compose.runtime.Stable public static inline float max(float a, float b);
+    method @androidx.compose.runtime.Stable public static inline float min(float a, float b);
+    method public static inline float takeOrElse(float, kotlin.jvm.functions.Function0<androidx.compose.ui.unit.Dp> block);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.unit.DpOffset> block);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.unit.DpSize> block);
+    method @androidx.compose.runtime.Stable public static inline operator float times(double, float other);
+    method @androidx.compose.runtime.Stable public static inline operator float times(float, float other);
+    method @androidx.compose.runtime.Stable public static inline operator long times(float, long size);
+    method @androidx.compose.runtime.Stable public static inline operator float times(int, float other);
+    method @androidx.compose.runtime.Stable public static inline operator long times(int, long size);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DpOffset {
+    method public long copy(optional float x, optional float y);
+    method public float getX();
+    method public float getY();
+    method @androidx.compose.runtime.Stable public inline operator long minus(long other);
+    method @androidx.compose.runtime.Stable public inline operator long plus(long other);
+    property @androidx.compose.runtime.Stable public final float x;
+    property @androidx.compose.runtime.Stable public final float y;
+    field public static final androidx.compose.ui.unit.DpOffset.Companion Companion;
+  }
+
+  public static final class DpOffset.Companion {
+    method public long getUnspecified();
+    method public long getZero();
+    property public final long Unspecified;
+    property public final long Zero;
+  }
+
+  @androidx.compose.runtime.Immutable public final class DpRect {
+    ctor public DpRect(@androidx.compose.runtime.Stable float left, @androidx.compose.runtime.Stable float top, @androidx.compose.runtime.Stable float right, @androidx.compose.runtime.Stable float bottom);
+    ctor public DpRect(long origin, long size);
+    method public float component1-D9Ej5fM();
+    method public float component2-D9Ej5fM();
+    method public float component3-D9Ej5fM();
+    method public float component4-D9Ej5fM();
+    method public androidx.compose.ui.unit.DpRect copy-a9UjIt4(float left, float top, float right, float bottom);
+    method public float getBottom();
+    method public float getLeft();
+    method public float getRight();
+    method public float getTop();
+    property public final float bottom;
+    property public final float left;
+    property public final float right;
+    property public final float top;
+    field public static final androidx.compose.ui.unit.DpRect.Companion Companion;
+  }
+
+  public static final class DpRect.Companion {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class DpSize {
+    method @androidx.compose.runtime.Stable public inline operator float component1();
+    method @androidx.compose.runtime.Stable public inline operator float component2();
+    method public long copy(optional float width, optional float height);
+    method @androidx.compose.runtime.Stable public operator long div(float other);
+    method @androidx.compose.runtime.Stable public operator long div(int other);
+    method public float getHeight();
+    method public float getWidth();
+    method @androidx.compose.runtime.Stable public inline operator long minus(long other);
+    method @androidx.compose.runtime.Stable public inline operator long plus(long other);
+    method @androidx.compose.runtime.Stable public operator long times(float other);
+    method @androidx.compose.runtime.Stable public operator long times(int other);
+    property @androidx.compose.runtime.Stable public final float height;
+    property @androidx.compose.runtime.Stable public final float width;
+    field public static final androidx.compose.ui.unit.DpSize.Companion Companion;
+  }
+
+  public static final class DpSize.Companion {
+    method public long getUnspecified();
+    method public long getZero();
+    property public final long Unspecified;
+    property public final long Zero;
+  }
+
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalUnitApi {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntOffset {
+    method @androidx.compose.runtime.Stable public operator int component1();
+    method @androidx.compose.runtime.Stable public operator int component2();
+    method public long copy(optional int x, optional int y);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method public int getX();
+    method public int getY();
+    method @androidx.compose.runtime.Stable public inline operator long minus(long other);
+    method @androidx.compose.runtime.Stable public inline operator long plus(long other);
+    method @androidx.compose.runtime.Stable public operator long rem(int operand);
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    method @androidx.compose.runtime.Stable public inline operator long unaryMinus();
+    property @androidx.compose.runtime.Stable public final int x;
+    property @androidx.compose.runtime.Stable public final int y;
+    field public static final androidx.compose.ui.unit.IntOffset.Companion Companion;
+  }
+
+  public static final class IntOffset.Companion {
+    method public long getZero();
+    property public final long Zero;
+  }
+
+  public final class IntOffsetKt {
+    method @androidx.compose.runtime.Stable public static long IntOffset(int x, int y);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method @androidx.compose.runtime.Stable public static operator long minus(long, long offset);
+    method @androidx.compose.runtime.Stable public static operator long minus(long, long offset);
+    method @androidx.compose.runtime.Stable public static operator long plus(long, long offset);
+    method @androidx.compose.runtime.Stable public static operator long plus(long, long offset);
+    method @androidx.compose.runtime.Stable public static inline long round(long);
+    method @androidx.compose.runtime.Stable public static inline long toOffset(long);
+  }
+
+  @androidx.compose.runtime.Immutable public final class IntRect {
+    ctor public IntRect(@androidx.compose.runtime.Stable int left, @androidx.compose.runtime.Stable int top, @androidx.compose.runtime.Stable int right, @androidx.compose.runtime.Stable int bottom);
+    method public int component1();
+    method public int component2();
+    method public int component3();
+    method public int component4();
+    method public boolean contains(long offset);
+    method public androidx.compose.ui.unit.IntRect copy(int left, int top, int right, int bottom);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.unit.IntRect deflate(int delta);
+    method public int getBottom();
+    method public long getBottomCenter();
+    method public long getBottomLeft();
+    method public long getBottomRight();
+    method public long getCenter();
+    method public long getCenterLeft();
+    method public long getCenterRight();
+    method public int getHeight();
+    method public int getLeft();
+    method public int getMaxDimension();
+    method public int getMinDimension();
+    method public int getRight();
+    method public long getSize();
+    method public int getTop();
+    method public long getTopCenter();
+    method public long getTopLeft();
+    method public long getTopRight();
+    method public int getWidth();
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.unit.IntRect inflate(int delta);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.unit.IntRect intersect(androidx.compose.ui.unit.IntRect other);
+    method public boolean isEmpty();
+    method public boolean overlaps(androidx.compose.ui.unit.IntRect other);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.unit.IntRect translate(int translateX, int translateY);
+    method @androidx.compose.runtime.Stable public androidx.compose.ui.unit.IntRect translate(long offset);
+    property public final int bottom;
+    property public final long bottomCenter;
+    property public final long bottomLeft;
+    property public final long bottomRight;
+    property public final long center;
+    property public final long centerLeft;
+    property public final long centerRight;
+    property @androidx.compose.runtime.Stable public final int height;
+    property @androidx.compose.runtime.Stable public final boolean isEmpty;
+    property public final int left;
+    property public final int maxDimension;
+    property public final int minDimension;
+    property public final int right;
+    property @androidx.compose.runtime.Stable public final long size;
+    property public final int top;
+    property public final long topCenter;
+    property public final long topLeft;
+    property public final long topRight;
+    property @androidx.compose.runtime.Stable public final int width;
+    field public static final androidx.compose.ui.unit.IntRect.Companion Companion;
+  }
+
+  public static final class IntRect.Companion {
+    method public androidx.compose.ui.unit.IntRect getZero();
+    property public final androidx.compose.ui.unit.IntRect Zero;
+  }
+
+  public final class IntRectKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect IntRect(long center, int radius);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect IntRect(long offset, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect IntRect(long topLeft, long bottomRight);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect lerp(androidx.compose.ui.unit.IntRect start, androidx.compose.ui.unit.IntRect stop, float fraction);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect roundToIntRect(androidx.compose.ui.geometry.Rect);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.geometry.Rect toRect(androidx.compose.ui.unit.IntRect);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntSize {
+    method @androidx.compose.runtime.Stable public inline operator int component1();
+    method @androidx.compose.runtime.Stable public inline operator int component2();
+    method @androidx.compose.runtime.Stable public operator long div(int other);
+    method public int getHeight();
+    method public int getWidth();
+    method @androidx.compose.runtime.Stable public operator long times(int other);
+    property @androidx.compose.runtime.Stable public final int height;
+    property @androidx.compose.runtime.Stable public final int width;
+    field public static final androidx.compose.ui.unit.IntSize.Companion Companion;
+  }
+
+  public static final class IntSize.Companion {
+    method public long getZero();
+    property public final long Zero;
+  }
+
+  public final class IntSizeKt {
+    method @androidx.compose.runtime.Stable public static long IntSize(int width, int height);
+    method public static long getCenter(long);
+    method @androidx.compose.runtime.Stable public static operator long times(int, long size);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.unit.IntRect toIntRect(long);
+    method @androidx.compose.runtime.Stable public static long toSize(long);
+  }
+
+  public enum LayoutDirection {
+    method public static androidx.compose.ui.unit.LayoutDirection valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.unit.LayoutDirection[] values();
+    enum_constant public static final androidx.compose.ui.unit.LayoutDirection Ltr;
+    enum_constant public static final androidx.compose.ui.unit.LayoutDirection Rtl;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TextUnit {
+    method public inline operator int compareTo(long other);
+    method public inline operator long div(double other);
+    method public inline operator long div(float other);
+    method public inline operator long div(int other);
+    method public long getType();
+    method public float getValue();
+    method public boolean isEm();
+    method public boolean isSp();
+    method public inline operator long times(double other);
+    method public inline operator long times(float other);
+    method public inline operator long times(int other);
+    method public inline operator long unaryMinus();
+    property public final boolean isEm;
+    property public final boolean isSp;
+    property public final long type;
+    property public final float value;
+    field public static final androidx.compose.ui.unit.TextUnit.Companion Companion;
+  }
+
+  public static final class TextUnit.Companion {
+    method public long getUnspecified();
+    property public final long Unspecified;
+  }
+
+  public final class TextUnitKt {
+    method public static long TextUnit(float value, long type);
+    method public static long getEm(double);
+    method public static long getEm(float);
+    method public static long getEm(int);
+    method public static long getSp(double);
+    method public static long getSp(float);
+    method public static long getSp(int);
+    method public static inline boolean isSpecified(long);
+    method public static boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.unit.TextUnit> block);
+    method @androidx.compose.runtime.Stable public static inline operator long times(double, long other);
+    method @androidx.compose.runtime.Stable public static inline operator long times(float, long other);
+    method @androidx.compose.runtime.Stable public static inline operator long times(int, long other);
+  }
+
+  @kotlin.jvm.JvmInline public final value class TextUnitType {
+    ctor public TextUnitType(long type);
+    field public static final androidx.compose.ui.unit.TextUnitType.Companion Companion;
+  }
+
+  public static final class TextUnitType.Companion {
+    method public long getEm();
+    method public long getSp();
+    method public long getUnspecified();
+    property public final long Em;
+    property public final long Sp;
+    property public final long Unspecified;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Velocity {
+    method @androidx.compose.runtime.Stable public operator float component1();
+    method @androidx.compose.runtime.Stable public operator float component2();
+    method public long copy(optional float x, optional float y);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method public float getX();
+    method public float getY();
+    method @androidx.compose.runtime.Stable public operator long minus(long other);
+    method @androidx.compose.runtime.Stable public operator long plus(long other);
+    method @androidx.compose.runtime.Stable public operator long rem(float operand);
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    method @androidx.compose.runtime.Stable public operator long unaryMinus();
+    property @androidx.compose.runtime.Stable public final float x;
+    property @androidx.compose.runtime.Stable public final float y;
+    field public static final androidx.compose.ui.unit.Velocity.Companion Companion;
+  }
+
+  public static final class Velocity.Companion {
+    method public long getZero();
+    property public final long Zero;
+  }
+
+  public final class VelocityKt {
+    method @androidx.compose.runtime.Stable public static long Velocity(float x, float y);
+  }
+
+}
+
diff --git a/compose/ui/ui-unit/api/restricted_1.5.0-beta01.txt b/compose/ui/ui-unit/api/restricted_1.5.0-beta01.txt
index fa535e7..c076a0f 100644
--- a/compose/ui/ui-unit/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui-unit/api/restricted_1.5.0-beta01.txt
@@ -194,9 +194,6 @@
     property public final long Zero;
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalUnitApi {
-  }
-
   @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class IntOffset {
     method @androidx.compose.runtime.Stable public operator int component1();
     method @androidx.compose.runtime.Stable public operator int component2();
diff --git a/compose/ui/ui-unit/build.gradle b/compose/ui/ui-unit/build.gradle
index 627cd87..ab08862 100644
--- a/compose/ui/ui-unit/build.gradle
+++ b/compose/ui/ui-unit/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-util/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-util/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..a4ae8f0
--- /dev/null
+++ b/compose/ui/ui-util/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,38 @@
+// Signature format: 4.0
+package androidx.compose.ui.util {
+
+  public final class AndroidTrace_androidKt {
+    method public static inline <T> T trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
+  }
+
+  public final class InlineClassHelperKt {
+    method public static inline long packFloats(float val1, float val2);
+    method public static inline long packInts(int val1, int val2);
+    method public static inline float unpackFloat1(long value);
+    method public static inline float unpackFloat2(long value);
+    method public static inline int unpackInt1(long value);
+    method public static inline int unpackInt2(long value);
+  }
+
+  public final class ListUtilsKt {
+    method public static inline <T> boolean fastAll(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> boolean fastAny(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> T? fastFirstOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
+    method public static inline <T> void fastForEachIndexed(java.util.List<? extends T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
+    method public static inline <T> void fastForEachReversed(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
+    method public static inline <T> T? fastLastOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
+    method public static inline <T, R> java.util.List<R> fastMap(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
+    method public static inline <T, R, C extends java.util.Collection<? super R>> C fastMapTo(java.util.List<? extends T>, C destination, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
+    method public static inline <T, R extends java.lang.Comparable<? super R>> T? fastMaxBy(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> selector);
+    method public static inline <T> int fastSumBy(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Integer> selector);
+  }
+
+  public final class MathHelpersKt {
+    method public static float lerp(float start, float stop, float fraction);
+    method public static int lerp(int start, int stop, float fraction);
+    method public static long lerp(long start, long stop, float fraction);
+  }
+
+}
+
diff --git a/compose/ui/ui-util/build.gradle b/compose/ui/ui-util/build.gradle
index 4c19723..a041871 100644
--- a/compose/ui/ui-util/build.gradle
+++ b/compose/ui/ui-util/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/compose/ui/ui-viewbinding/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui-viewbinding/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..00c3178
--- /dev/null
+++ b/compose/ui/ui-viewbinding/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,10 @@
+// Signature format: 4.0
+package androidx.compose.ui.viewinterop {
+
+  public final class AndroidViewBindingKt {
+    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable public static <T extends androidx.viewbinding.ViewBinding> void AndroidViewBinding(kotlin.jvm.functions.Function3<? super android.view.LayoutInflater,? super android.view.ViewGroup,? super java.lang.Boolean,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onReset, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onRelease, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+  }
+
+}
+
diff --git a/compose/ui/ui/api/1.5.0-beta01.txt b/compose/ui/ui/api/1.5.0-beta01.txt
index ad58ecf..e264a40 100644
--- a/compose/ui/ui/api/1.5.0-beta01.txt
+++ b/compose/ui/ui/api/1.5.0-beta01.txt
@@ -112,21 +112,11 @@
   }
 
   public final class ComposedModifierKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, Object? key3, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object![]? keys, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method @Deprecated public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
     method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalComposeUiApi {
-  }
-
-  @kotlin.RequiresOptIn(message="Unstable API for use only between compose-ui modules sharing the same exact version, " + "subject to change without notice in major, minor, or patch releases.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeUiApi {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
@@ -159,7 +149,6 @@
     method public void onAttach();
     method public void onDetach();
     method public void onReset();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public final void sideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
     property public final kotlinx.coroutines.CoroutineScope coroutineScope;
     property public final boolean isAttached;
     property public final androidx.compose.ui.Modifier.Node node;
@@ -186,77 +175,6 @@
 
 }
 
-package androidx.compose.ui.autofill {
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface Autofill {
-    method public void cancelAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
-    method public void requestAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillNode {
-    ctor public AutofillNode(optional java.util.List<? extends androidx.compose.ui.autofill.AutofillType> autofillTypes, optional androidx.compose.ui.geometry.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
-    method public java.util.List<androidx.compose.ui.autofill.AutofillType> getAutofillTypes();
-    method public androidx.compose.ui.geometry.Rect? getBoundingBox();
-    method public int getId();
-    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
-    method public void setBoundingBox(androidx.compose.ui.geometry.Rect?);
-    property public final java.util.List<androidx.compose.ui.autofill.AutofillType> autofillTypes;
-    property public final androidx.compose.ui.geometry.Rect? boundingBox;
-    property public final int id;
-    property public final kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? onFill;
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillTree {
-    ctor public AutofillTree();
-    method public java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> getChildren();
-    method public kotlin.Unit? performAutofill(int id, String value);
-    method public operator void plusAssign(androidx.compose.ui.autofill.AutofillNode autofillNode);
-    property public final java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> children;
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public enum AutofillType {
-    method public static androidx.compose.ui.autofill.AutofillType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.ui.autofill.AutofillType[] values();
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressAuxiliaryDetails;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressCountry;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressLocality;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressRegion;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressStreet;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateDay;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateFull;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateMonth;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateYear;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDate;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDay;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationMonth;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationYear;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardNumber;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardSecurityCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType EmailAddress;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Gender;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewPassword;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewUsername;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Password;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFirstName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFullName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonLastName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleInitial;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNamePrefix;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNameSuffix;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneCountryCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumber;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberDevice;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberNational;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalAddress;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCodeExtended;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType SmsOtpCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Username;
-  }
-
-}
-
 package androidx.compose.ui.draw {
 
   public final class AlphaKt {
@@ -359,22 +277,14 @@
 
   public static final class FocusDirection.Companion {
     method public int getDown();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public int getEnter();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public int getExit();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getIn();
     method public int getLeft();
     method public int getNext();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getOut();
     method public int getPrevious();
     method public int getRight();
     method public int getUp();
     property public final int Down;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Enter;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Exit;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int In;
     property public final int Left;
     property public final int Next;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Out;
     property public final int Previous;
     property public final int Right;
     property public final int Up;
@@ -444,8 +354,6 @@
     method public boolean getCanFocus();
     method public default androidx.compose.ui.focus.FocusRequester getDown();
     method public default androidx.compose.ui.focus.FocusRequester getEnd();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getEnter();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getExit();
     method public default androidx.compose.ui.focus.FocusRequester getLeft();
     method public default androidx.compose.ui.focus.FocusRequester getNext();
     method public default androidx.compose.ui.focus.FocusRequester getPrevious();
@@ -455,8 +363,6 @@
     method public void setCanFocus(boolean);
     method public default void setDown(androidx.compose.ui.focus.FocusRequester);
     method public default void setEnd(androidx.compose.ui.focus.FocusRequester);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setEnter(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setExit(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
     method public default void setLeft(androidx.compose.ui.focus.FocusRequester);
     method public default void setNext(androidx.compose.ui.focus.FocusRequester);
     method public default void setPrevious(androidx.compose.ui.focus.FocusRequester);
@@ -466,8 +372,6 @@
     property public abstract boolean canFocus;
     property public default androidx.compose.ui.focus.FocusRequester down;
     property public default androidx.compose.ui.focus.FocusRequester end;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> enter;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> exit;
     property public default androidx.compose.ui.focus.FocusRequester left;
     property public default androidx.compose.ui.focus.FocusRequester next;
     property public default androidx.compose.ui.focus.FocusRequester previous;
@@ -497,33 +401,10 @@
   }
 
   public static final class FocusRequester.Companion {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory createRefs();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester getCancel();
     method public androidx.compose.ui.focus.FocusRequester getDefault();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.focus.FocusRequester Cancel;
     property public final androidx.compose.ui.focus.FocusRequester Default;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public static final class FocusRequester.Companion.FocusRequesterFactory {
-    method public operator androidx.compose.ui.focus.FocusRequester component1();
-    method public operator androidx.compose.ui.focus.FocusRequester component10();
-    method public operator androidx.compose.ui.focus.FocusRequester component11();
-    method public operator androidx.compose.ui.focus.FocusRequester component12();
-    method public operator androidx.compose.ui.focus.FocusRequester component13();
-    method public operator androidx.compose.ui.focus.FocusRequester component14();
-    method public operator androidx.compose.ui.focus.FocusRequester component15();
-    method public operator androidx.compose.ui.focus.FocusRequester component16();
-    method public operator androidx.compose.ui.focus.FocusRequester component2();
-    method public operator androidx.compose.ui.focus.FocusRequester component3();
-    method public operator androidx.compose.ui.focus.FocusRequester component4();
-    method public operator androidx.compose.ui.focus.FocusRequester component5();
-    method public operator androidx.compose.ui.focus.FocusRequester component6();
-    method public operator androidx.compose.ui.focus.FocusRequester component7();
-    method public operator androidx.compose.ui.focus.FocusRequester component8();
-    method public operator androidx.compose.ui.focus.FocusRequester component9();
-    field public static final androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory INSTANCE;
-  }
-
   @Deprecated @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusRequesterModifier extends androidx.compose.ui.Modifier.Element {
     method @Deprecated public androidx.compose.ui.focus.FocusRequester getFocusRequester();
     property @Deprecated public abstract androidx.compose.ui.focus.FocusRequester focusRequester;
@@ -945,7 +826,6 @@
 
   public interface InputModeManager {
     method public int getInputMode();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public boolean requestInputMode(int inputMode);
     property public abstract int inputMode;
   }
 
@@ -1581,16 +1461,6 @@
     method public static int getNativeKeyCode(long);
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftKeyboardInterceptionModifierNode extends androidx.compose.ui.node.DelegatableNode {
-    method public boolean onInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
-    method public boolean onPreInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
-  }
-
-  public final class SoftwareKeyboardInterceptionModifierKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onInterceptKeyBeforeSoftKeyboard);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onPreInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onPreInterceptKeyBeforeSoftKeyboard);
-  }
-
 }
 
 package androidx.compose.ui.input.nestedscroll {
@@ -1627,10 +1497,8 @@
   public static final class NestedScrollSource.Companion {
     method public int getDrag();
     method public int getFling();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getRelocate();
     property public final int Drag;
     property public final int Fling;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Relocate;
   }
 
 }
@@ -1661,14 +1529,6 @@
     property @Deprecated public final boolean positionChange;
   }
 
-  @androidx.compose.runtime.Immutable @androidx.compose.ui.ExperimentalComposeUiApi public final class HistoricalChange {
-    ctor public HistoricalChange(long uptimeMillis, long position);
-    method public long getPosition();
-    method public long getUptimeMillis();
-    property public final long position;
-    property public final long uptimeMillis;
-  }
-
   @kotlin.jvm.JvmInline public final value class PointerButtons {
     ctor public PointerButtons(int packedValue);
   }
@@ -1798,14 +1658,11 @@
     ctor @Deprecated public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
     ctor public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, boolean isInitiallyConsumed, optional int type, optional long scrollDelta);
     method public void consume();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
     method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
     method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
     method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type, optional long scrollDelta);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
     method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
     method @Deprecated public androidx.compose.ui.input.pointer.ConsumedData getConsumed();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> getHistorical();
     method public long getId();
     method public long getPosition();
     method public boolean getPressed();
@@ -1818,7 +1675,6 @@
     method public long getUptimeMillis();
     method public boolean isConsumed();
     property @Deprecated public final androidx.compose.ui.input.pointer.ConsumedData consumed;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical;
     property public final long id;
     property public final boolean isConsumed;
     property public final long position;
@@ -1862,11 +1718,6 @@
     property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
   }
 
-  public final class PointerInteropFilter_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier motionEventSpy(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> watcher);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier pointerInteropFilter(androidx.compose.ui.Modifier, optional androidx.compose.ui.input.pointer.RequestDisallowInterceptTouchEvent? requestDisallowInterceptTouchEvent, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,java.lang.Boolean> onTouchEvent);
-  }
-
   @kotlin.jvm.JvmInline public final value class PointerKeyboardModifiers {
     ctor public PointerKeyboardModifiers(int packedValue);
   }
@@ -1888,11 +1739,6 @@
     property public final int Unknown;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class RequestDisallowInterceptTouchEvent implements kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit> {
-    ctor public RequestDisallowInterceptTouchEvent();
-    method public void invoke(boolean disallowIntercept);
-  }
-
   public final class SuspendingPointerInputFilterKt {
     method public static androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode SuspendingPointerInputModifierNode(kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> pointerInputHandler);
     method public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
@@ -1930,9 +1776,6 @@
 
   public final class VelocityTrackerKt {
     method public static void addPointerInputChange(androidx.compose.ui.input.pointer.util.VelocityTracker, androidx.compose.ui.input.pointer.PointerInputChange event);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getVelocityTrackerAddPointsFix();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setVelocityTrackerAddPointsFix(boolean);
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final boolean VelocityTrackerAddPointsFix;
   }
 
 }
@@ -2052,11 +1895,6 @@
     ctor public HorizontalAlignmentLine(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Integer> merger);
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface IntermediateMeasureScope extends androidx.compose.ui.layout.LookaheadScope kotlinx.coroutines.CoroutineScope androidx.compose.ui.layout.MeasureScope {
-    method public long getLookaheadSize();
-    property public abstract long lookaheadSize;
-  }
-
   public interface IntrinsicMeasurable {
     method public Object? getParentData();
     method public int maxIntrinsicHeight(int width);
@@ -2068,8 +1906,6 @@
 
   public interface IntrinsicMeasureScope extends androidx.compose.ui.unit.Density {
     method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead;
     property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
   }
 
@@ -2156,27 +1992,6 @@
     method public static androidx.compose.ui.Modifier layout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
   }
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface LookaheadLayoutCoordinates extends androidx.compose.ui.layout.LayoutCoordinates {
-  }
-
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadLayoutScope {
-    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadScope {
-    method public androidx.compose.ui.layout.LayoutCoordinates getLookaheadScopeCoordinates(androidx.compose.ui.layout.Placeable.PlacementScope);
-    method @Deprecated public default androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.ui.layout.MeasureResult> measure);
-    method public default long localLookaheadPositionOf(androidx.compose.ui.layout.LayoutCoordinates, androidx.compose.ui.layout.LayoutCoordinates coordinates);
-    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
-    method public androidx.compose.ui.layout.LayoutCoordinates toLookaheadCoordinates(androidx.compose.ui.layout.LayoutCoordinates);
-  }
-
-  public final class LookaheadScopeKt {
-    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadLayout(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
-    method @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadScope(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntermediateMeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
-  }
-
   public interface Measurable extends androidx.compose.ui.layout.IntrinsicMeasurable {
     method public androidx.compose.ui.layout.Placeable measure(long constraints);
   }
@@ -2311,24 +2126,6 @@
     property protected abstract int parentWidth;
   }
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi @kotlin.jvm.JvmDefaultWithCompatibility public interface RelocationModifier extends androidx.compose.ui.Modifier.Element {
-    method @Deprecated public androidx.compose.ui.geometry.Rect computeDestination(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.layout.LayoutCoordinates layoutCoordinates);
-    method @Deprecated public suspend Object? performRelocation(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.geometry.Rect destination, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class RelocationModifierKt {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onRelocationRequest(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> onProvideDestination, kotlin.jvm.functions.Function3<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.geometry.Rect,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onPerformRelocation);
-  }
-
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class RelocationRequester {
-    ctor @Deprecated public RelocationRequester();
-    method @Deprecated public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class RelocationRequesterModifierKt {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier relocationRequester(androidx.compose.ui.Modifier, Object relocationRequester);
-  }
-
   public interface Remeasurement {
     method public void forceRemeasure();
   }
@@ -2420,10 +2217,6 @@
     method public void onModifierLocalsUpdated(androidx.compose.ui.modifier.ModifierLocalReadScope scope);
   }
 
-  public final class ModifierLocalConsumerKt {
-    method @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier modifierLocalConsumer(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.modifier.ModifierLocalReadScope,kotlin.Unit> consumer);
-  }
-
   public final class ModifierLocalKt {
     method public static <T> androidx.compose.ui.modifier.ProvidableModifierLocal<T> modifierLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
   }
@@ -2453,10 +2246,6 @@
     property public abstract T value;
   }
 
-  public final class ModifierLocalProviderKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static <T> androidx.compose.ui.Modifier modifierLocalProvider(androidx.compose.ui.Modifier, androidx.compose.ui.modifier.ProvidableModifierLocal<T> key, kotlin.jvm.functions.Function0<? extends T> value);
-  }
-
   public interface ModifierLocalReadScope {
     method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
   }
@@ -2510,13 +2299,6 @@
     method public void onGloballyPositioned(androidx.compose.ui.layout.LayoutCoordinates coordinates);
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalCoreApi {
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public sealed interface InteroperableComposeUiNode {
-    method public android.view.View? getInteropView();
-  }
-
   public interface LayoutAwareModifierNode extends androidx.compose.ui.node.DelegatableNode {
     method public default void onPlaced(androidx.compose.ui.layout.LayoutCoordinates coordinates);
     method public default void onRemeasured(long size);
@@ -2588,7 +2370,6 @@
     method public androidx.compose.ui.unit.Density getDensity();
     method public androidx.compose.ui.semantics.SemanticsOwner getSemanticsOwner();
     method public androidx.compose.ui.text.input.TextInputService getTextInputService();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void measureAndLayoutForTest();
     method public boolean sendKeyEvent(android.view.KeyEvent keyEvent);
     property public abstract androidx.compose.ui.unit.Density density;
     property public abstract androidx.compose.ui.semantics.SemanticsOwner semanticsOwner;
@@ -2705,8 +2486,6 @@
 
   public final class CompositionLocalsKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> getLocalDensity();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> getLocalFocusManager();
@@ -2714,15 +2493,12 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> getLocalHapticFeedback();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> getLocalInputModeManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> getLocalLayoutDirection();
-    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> getLocalPlatformTextInputPluginRegistry();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> getLocalTextInputService();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> getLocalTextToolbar();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> getLocalUriHandler();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ViewConfiguration> getLocalViewConfiguration();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.WindowInfo> getLocalWindowInfo();
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> LocalAccessibilityManager;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> LocalAutofill;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> LocalAutofillTree;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> LocalClipboardManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> LocalDensity;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> LocalFocusManager;
@@ -2730,7 +2506,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> LocalHapticFeedback;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> LocalInputModeManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> LocalLayoutDirection;
-    property @androidx.compose.ui.text.ExperimentalTextApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> LocalPlatformTextInputPluginRegistry;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> LocalTextInputService;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> LocalTextToolbar;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> LocalUriHandler;
@@ -2801,24 +2576,10 @@
     property public Object? valueOverride;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class LocalSoftwareKeyboardController {
-    method @androidx.compose.runtime.Composable public androidx.compose.ui.platform.SoftwareKeyboardController? getCurrent();
-    method public infix androidx.compose.runtime.ProvidedValue<androidx.compose.ui.platform.SoftwareKeyboardController> provides(androidx.compose.ui.platform.SoftwareKeyboardController softwareKeyboardController);
-    property @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.platform.SoftwareKeyboardController? current;
-    field public static final androidx.compose.ui.platform.LocalSoftwareKeyboardController INSTANCE;
-  }
-
   public final class NestedScrollInteropConnectionKt {
     method @androidx.compose.runtime.Composable public static androidx.compose.ui.input.nestedscroll.NestedScrollConnection rememberNestedScrollInteropConnection(optional android.view.View hostView);
   }
 
-  @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftwareKeyboardController {
-    method public void hide();
-    method @Deprecated public default void hideSoftwareKeyboard();
-    method public void show();
-    method @Deprecated public default void showSoftwareKeyboard();
-  }
-
   public final class TestTagKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier testTag(androidx.compose.ui.Modifier, String tag);
   }
@@ -2927,30 +2688,11 @@
   }
 
   @androidx.compose.runtime.Stable public interface WindowInfo {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default int getKeyboardModifiers();
     method public boolean isWindowFocused();
     property public abstract boolean isWindowFocused;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default int keyboardModifiers;
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public fun interface WindowRecomposerFactory {
-    method public androidx.compose.runtime.Recomposer createRecomposer(android.view.View windowRootView);
-    field public static final androidx.compose.ui.platform.WindowRecomposerFactory.Companion Companion;
-  }
-
-  public static final class WindowRecomposerFactory.Companion {
-    method public androidx.compose.ui.platform.WindowRecomposerFactory getLifecycleAware();
-    property public final androidx.compose.ui.platform.WindowRecomposerFactory LifecycleAware;
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public final class WindowRecomposerPolicy {
-    method public void setFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory);
-    method public inline <R> R withFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory, kotlin.jvm.functions.Function0<? extends R> block);
-    field public static final androidx.compose.ui.platform.WindowRecomposerPolicy INSTANCE;
   }
 
   public final class WindowRecomposer_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.Recomposer createLifecycleAwareWindowRecomposer(android.view.View, optional kotlin.coroutines.CoroutineContext coroutineContext, optional androidx.lifecycle.Lifecycle? lifecycle);
     method public static androidx.compose.runtime.CompositionContext? findViewTreeCompositionContext(android.view.View);
     method public static androidx.compose.runtime.CompositionContext? getCompositionContext(android.view.View);
     method public static void setCompositionContext(android.view.View, androidx.compose.runtime.CompositionContext?);
@@ -3283,12 +3025,6 @@
     field public static final androidx.compose.ui.semantics.SemanticsProperties INSTANCE;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class SemanticsPropertiesAndroid {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getTestTagsAsResourceId();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> TestTagsAsResourceId;
-    field public static final androidx.compose.ui.semantics.SemanticsPropertiesAndroid INSTANCE;
-  }
-
   public final class SemanticsPropertiesKt {
     method public static void collapse(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
     method public static void copyText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3322,7 +3058,6 @@
     method public static void heading(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void indexForKey(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Integer> mapping);
     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 @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 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);
@@ -3366,11 +3101,6 @@
     method public static void setVerticalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.ScrollAxisRange);
   }
 
-  public final class SemanticsProperties_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
-  }
-
   public final class SemanticsPropertyKey<T> {
     ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
     method public String getName();
@@ -3459,7 +3189,6 @@
 
   @androidx.compose.runtime.Immutable public final class PopupProperties {
     ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled);
-    ctor @androidx.compose.ui.ExperimentalComposeUiApi public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled, optional boolean usePlatformDefaultWidth);
     method public boolean getClippingEnabled();
     method public boolean getDismissOnBackPress();
     method public boolean getDismissOnClickOutside();
diff --git a/compose/ui/ui/api/public_plus_experimental_1.5.0-beta01.txt b/compose/ui/ui/api/public_plus_experimental_1.5.0-beta01.txt
new file mode 100644
index 0000000..434d4ce
--- /dev/null
+++ b/compose/ui/ui/api/public_plus_experimental_1.5.0-beta01.txt
@@ -0,0 +1,3491 @@
+// Signature format: 4.0
+package androidx.compose.ui {
+
+  public final class AbsoluteAlignment {
+    method public androidx.compose.ui.Alignment getBottomLeft();
+    method public androidx.compose.ui.Alignment getBottomRight();
+    method public androidx.compose.ui.Alignment getCenterLeft();
+    method public androidx.compose.ui.Alignment getCenterRight();
+    method public androidx.compose.ui.Alignment.Horizontal getLeft();
+    method public androidx.compose.ui.Alignment.Horizontal getRight();
+    method public androidx.compose.ui.Alignment getTopLeft();
+    method public androidx.compose.ui.Alignment getTopRight();
+    property public final androidx.compose.ui.Alignment BottomLeft;
+    property public final androidx.compose.ui.Alignment BottomRight;
+    property public final androidx.compose.ui.Alignment CenterLeft;
+    property public final androidx.compose.ui.Alignment CenterRight;
+    property public final androidx.compose.ui.Alignment.Horizontal Left;
+    property public final androidx.compose.ui.Alignment.Horizontal Right;
+    property public final androidx.compose.ui.Alignment TopLeft;
+    property public final androidx.compose.ui.Alignment TopRight;
+    field public static final androidx.compose.ui.AbsoluteAlignment INSTANCE;
+  }
+
+  @androidx.compose.runtime.Stable public fun interface Alignment {
+    method public long align(long size, long space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    field public static final androidx.compose.ui.Alignment.Companion Companion;
+  }
+
+  public static final class Alignment.Companion {
+    method public androidx.compose.ui.Alignment.Vertical getBottom();
+    method public androidx.compose.ui.Alignment getBottomCenter();
+    method public androidx.compose.ui.Alignment getBottomEnd();
+    method public androidx.compose.ui.Alignment getBottomStart();
+    method public androidx.compose.ui.Alignment getCenter();
+    method public androidx.compose.ui.Alignment getCenterEnd();
+    method public androidx.compose.ui.Alignment.Horizontal getCenterHorizontally();
+    method public androidx.compose.ui.Alignment getCenterStart();
+    method public androidx.compose.ui.Alignment.Vertical getCenterVertically();
+    method public androidx.compose.ui.Alignment.Horizontal getEnd();
+    method public androidx.compose.ui.Alignment.Horizontal getStart();
+    method public androidx.compose.ui.Alignment.Vertical getTop();
+    method public androidx.compose.ui.Alignment getTopCenter();
+    method public androidx.compose.ui.Alignment getTopEnd();
+    method public androidx.compose.ui.Alignment getTopStart();
+    property public final androidx.compose.ui.Alignment.Vertical Bottom;
+    property public final androidx.compose.ui.Alignment BottomCenter;
+    property public final androidx.compose.ui.Alignment BottomEnd;
+    property public final androidx.compose.ui.Alignment BottomStart;
+    property public final androidx.compose.ui.Alignment Center;
+    property public final androidx.compose.ui.Alignment CenterEnd;
+    property public final androidx.compose.ui.Alignment.Horizontal CenterHorizontally;
+    property public final androidx.compose.ui.Alignment CenterStart;
+    property public final androidx.compose.ui.Alignment.Vertical CenterVertically;
+    property public final androidx.compose.ui.Alignment.Horizontal End;
+    property public final androidx.compose.ui.Alignment.Horizontal Start;
+    property public final androidx.compose.ui.Alignment.Vertical Top;
+    property public final androidx.compose.ui.Alignment TopCenter;
+    property public final androidx.compose.ui.Alignment TopEnd;
+    property public final androidx.compose.ui.Alignment TopStart;
+  }
+
+  @androidx.compose.runtime.Stable public static fun interface Alignment.Horizontal {
+    method public int align(int size, int space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+  }
+
+  @androidx.compose.runtime.Stable public static fun interface Alignment.Vertical {
+    method public int align(int size, int space);
+  }
+
+  @androidx.compose.runtime.Immutable public final class BiasAbsoluteAlignment implements androidx.compose.ui.Alignment {
+    ctor public BiasAbsoluteAlignment(float horizontalBias, float verticalBias);
+    method public long align(long size, long space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public androidx.compose.ui.BiasAbsoluteAlignment copy(float horizontalBias, float verticalBias);
+  }
+
+  @androidx.compose.runtime.Immutable public static final class BiasAbsoluteAlignment.Horizontal implements androidx.compose.ui.Alignment.Horizontal {
+    ctor public BiasAbsoluteAlignment.Horizontal(float bias);
+    method public int align(int size, int space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public androidx.compose.ui.BiasAbsoluteAlignment.Horizontal copy(float bias);
+  }
+
+  @androidx.compose.runtime.Immutable public final class BiasAlignment implements androidx.compose.ui.Alignment {
+    ctor public BiasAlignment(float horizontalBias, float verticalBias);
+    method public long align(long size, long space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public float component1();
+    method public float component2();
+    method public androidx.compose.ui.BiasAlignment copy(float horizontalBias, float verticalBias);
+    method public float getHorizontalBias();
+    method public float getVerticalBias();
+    property public final float horizontalBias;
+    property public final float verticalBias;
+  }
+
+  @androidx.compose.runtime.Immutable public static final class BiasAlignment.Horizontal implements androidx.compose.ui.Alignment.Horizontal {
+    ctor public BiasAlignment.Horizontal(float bias);
+    method public int align(int size, int space, androidx.compose.ui.unit.LayoutDirection layoutDirection);
+    method public androidx.compose.ui.BiasAlignment.Horizontal copy(float bias);
+  }
+
+  @androidx.compose.runtime.Immutable public static final class BiasAlignment.Vertical implements androidx.compose.ui.Alignment.Vertical {
+    ctor public BiasAlignment.Vertical(float bias);
+    method public int align(int size, int space);
+    method public androidx.compose.ui.BiasAlignment.Vertical copy(float bias);
+  }
+
+  public final class CombinedModifier implements androidx.compose.ui.Modifier {
+    ctor public CombinedModifier(androidx.compose.ui.Modifier outer, androidx.compose.ui.Modifier inner);
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+  }
+
+  public final class ComposedModifierKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, Object? key3, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object![]? keys, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method @Deprecated public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+    method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
+  }
+
+  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalComposeUiApi {
+  }
+
+  @kotlin.RequiresOptIn(message="Unstable API for use only between compose-ui modules sharing the same exact version, " + "subject to change without notice in major, minor, or patch releases.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeUiApi {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+    method public default infix androidx.compose.ui.Modifier then(androidx.compose.ui.Modifier other);
+    field public static final androidx.compose.ui.Modifier.Companion Companion;
+  }
+
+  public static final class Modifier.Companion implements androidx.compose.ui.Modifier {
+    method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+    method public <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public static interface Modifier.Element extends androidx.compose.ui.Modifier {
+    method public default boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public default boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
+    method public default <R> R foldIn(R initial, kotlin.jvm.functions.Function2<? super R,? super androidx.compose.ui.Modifier.Element,? extends R> operation);
+    method public default <R> R foldOut(R initial, kotlin.jvm.functions.Function2<? super androidx.compose.ui.Modifier.Element,? super R,? extends R> operation);
+  }
+
+  public abstract static class Modifier.Node implements androidx.compose.ui.node.DelegatableNode {
+    ctor public Modifier.Node();
+    method public final kotlinx.coroutines.CoroutineScope getCoroutineScope();
+    method public final androidx.compose.ui.Modifier.Node getNode();
+    method public boolean getShouldAutoInvalidate();
+    method public final boolean isAttached();
+    method public void onAttach();
+    method public void onDetach();
+    method public void onReset();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public final void sideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
+    property public final kotlinx.coroutines.CoroutineScope coroutineScope;
+    property public final boolean isAttached;
+    property public final androidx.compose.ui.Modifier.Node node;
+    property public boolean shouldAutoInvalidate;
+  }
+
+  @androidx.compose.runtime.Stable public interface MotionDurationScale extends kotlin.coroutines.CoroutineContext.Element {
+    method public default kotlin.coroutines.CoroutineContext.Key<?> getKey();
+    method public float getScaleFactor();
+    property public default kotlin.coroutines.CoroutineContext.Key<?> key;
+    property public abstract float scaleFactor;
+    field public static final androidx.compose.ui.MotionDurationScale.Key Key;
+  }
+
+  public static final class MotionDurationScale.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.ui.MotionDurationScale> {
+  }
+
+  @androidx.compose.runtime.ComposableTargetMarker(description="UI Composable") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface UiComposable {
+  }
+
+  public final class ZIndexModifierKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier zIndex(androidx.compose.ui.Modifier, float zIndex);
+  }
+
+}
+
+package androidx.compose.ui.autofill {
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public interface Autofill {
+    method public void cancelAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
+    method public void requestAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillNode {
+    ctor public AutofillNode(optional java.util.List<? extends androidx.compose.ui.autofill.AutofillType> autofillTypes, optional androidx.compose.ui.geometry.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
+    method public java.util.List<androidx.compose.ui.autofill.AutofillType> getAutofillTypes();
+    method public androidx.compose.ui.geometry.Rect? getBoundingBox();
+    method public int getId();
+    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
+    method public void setBoundingBox(androidx.compose.ui.geometry.Rect?);
+    property public final java.util.List<androidx.compose.ui.autofill.AutofillType> autofillTypes;
+    property public final androidx.compose.ui.geometry.Rect? boundingBox;
+    property public final int id;
+    property public final kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? onFill;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillTree {
+    ctor public AutofillTree();
+    method public java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> getChildren();
+    method public kotlin.Unit? performAutofill(int id, String value);
+    method public operator void plusAssign(androidx.compose.ui.autofill.AutofillNode autofillNode);
+    property public final java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> children;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public enum AutofillType {
+    method public static androidx.compose.ui.autofill.AutofillType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.autofill.AutofillType[] values();
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressAuxiliaryDetails;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressCountry;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressLocality;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressRegion;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressStreet;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateDay;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateFull;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateMonth;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateYear;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDate;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDay;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationMonth;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationYear;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardNumber;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardSecurityCode;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType EmailAddress;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType Gender;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewPassword;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewUsername;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType Password;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFirstName;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFullName;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonLastName;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleInitial;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleName;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNamePrefix;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNameSuffix;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneCountryCode;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumber;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberDevice;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberNational;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalAddress;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCode;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCodeExtended;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType SmsOtpCode;
+    enum_constant public static final androidx.compose.ui.autofill.AutofillType Username;
+  }
+
+}
+
+package androidx.compose.ui.draw {
+
+  public final class AlphaKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier alpha(androidx.compose.ui.Modifier, float alpha);
+  }
+
+  public final class BlurKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier blur(androidx.compose.ui.Modifier, float radius, optional androidx.compose.ui.graphics.Shape edgeTreatment);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier blur(androidx.compose.ui.Modifier, float radiusX, float radiusY, optional androidx.compose.ui.graphics.Shape edgeTreatment);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class BlurredEdgeTreatment {
+    ctor public BlurredEdgeTreatment(androidx.compose.ui.graphics.Shape? shape);
+    method public androidx.compose.ui.graphics.Shape? getShape();
+    property public final androidx.compose.ui.graphics.Shape? shape;
+    field public static final androidx.compose.ui.draw.BlurredEdgeTreatment.Companion Companion;
+  }
+
+  public static final class BlurredEdgeTreatment.Companion {
+    method public androidx.compose.ui.graphics.Shape getRectangle();
+    method public androidx.compose.ui.graphics.Shape getUnbounded();
+    property public final androidx.compose.ui.graphics.Shape Rectangle;
+    property public final androidx.compose.ui.graphics.Shape Unbounded;
+  }
+
+  public interface BuildDrawCacheParams {
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method public long getSize();
+    property public abstract androidx.compose.ui.unit.Density density;
+    property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
+    property public abstract long size;
+  }
+
+  public final class CacheDrawScope implements androidx.compose.ui.unit.Density {
+    method public float getDensity();
+    method public float getFontScale();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method public long getSize();
+    method public androidx.compose.ui.draw.DrawResult onDrawBehind(kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> block);
+    method public androidx.compose.ui.draw.DrawResult onDrawWithContent(kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.ContentDrawScope,kotlin.Unit> block);
+    property public float density;
+    property public float fontScale;
+    property public final androidx.compose.ui.unit.LayoutDirection layoutDirection;
+    property public final long size;
+  }
+
+  public final class ClipKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier clip(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.Shape shape);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier clipToBounds(androidx.compose.ui.Modifier);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface DrawCacheModifier extends androidx.compose.ui.draw.DrawModifier {
+    method public void onBuildCache(androidx.compose.ui.draw.BuildDrawCacheParams params);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface DrawModifier extends androidx.compose.ui.Modifier.Element {
+    method public void draw(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
+  }
+
+  public final class DrawModifierKt {
+    method public static androidx.compose.ui.node.CacheDrawModifierNode CacheDrawModifierNode(kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
+    method public static androidx.compose.ui.Modifier drawBehind(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
+    method public static androidx.compose.ui.Modifier drawWithCache(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
+    method public static androidx.compose.ui.Modifier drawWithContent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.ContentDrawScope,kotlin.Unit> onDraw);
+  }
+
+  public final class DrawResult {
+  }
+
+  public final class PainterModifierKt {
+    method public static androidx.compose.ui.Modifier paint(androidx.compose.ui.Modifier, androidx.compose.ui.graphics.painter.Painter painter, optional boolean sizeToIntrinsics, optional androidx.compose.ui.Alignment alignment, optional androidx.compose.ui.layout.ContentScale contentScale, optional float alpha, optional androidx.compose.ui.graphics.ColorFilter? colorFilter);
+  }
+
+  public final class RotateKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier rotate(androidx.compose.ui.Modifier, float degrees);
+  }
+
+  public final class ScaleKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier scale(androidx.compose.ui.Modifier, float scale);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier scale(androidx.compose.ui.Modifier, float scaleX, float scaleY);
+  }
+
+  public final class ShadowKt {
+    method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, float elevation, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier shadow(androidx.compose.ui.Modifier, float elevation, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip, optional long ambientColor, optional long spotColor);
+  }
+
+}
+
+package androidx.compose.ui.focus {
+
+  public final class FocusChangedModifierKt {
+    method public static androidx.compose.ui.Modifier onFocusChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusState,kotlin.Unit> onFocusChanged);
+  }
+
+  @kotlin.jvm.JvmInline public final value class FocusDirection {
+    field public static final androidx.compose.ui.focus.FocusDirection.Companion Companion;
+  }
+
+  public static final class FocusDirection.Companion {
+    method public int getDown();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public int getEnter();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public int getExit();
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getIn();
+    method public int getLeft();
+    method public int getNext();
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getOut();
+    method public int getPrevious();
+    method public int getRight();
+    method public int getUp();
+    property public final int Down;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Enter;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Exit;
+    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int In;
+    property public final int Left;
+    property public final int Next;
+    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Out;
+    property public final int Previous;
+    property public final int Right;
+    property public final int Up;
+  }
+
+  @Deprecated @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusEventModifier extends androidx.compose.ui.Modifier.Element {
+    method @Deprecated public void onFocusEvent(androidx.compose.ui.focus.FocusState focusState);
+  }
+
+  public final class FocusEventModifierKt {
+    method public static androidx.compose.ui.Modifier onFocusEvent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusState,kotlin.Unit> onFocusEvent);
+  }
+
+  public interface FocusEventModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void onFocusEvent(androidx.compose.ui.focus.FocusState focusState);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusManager {
+    method public void clearFocus(optional boolean force);
+    method public boolean moveFocus(int focusDirection);
+  }
+
+  public final class FocusModifierKt {
+    method @Deprecated public static androidx.compose.ui.Modifier focusModifier(androidx.compose.ui.Modifier);
+    method public static androidx.compose.ui.Modifier focusTarget(androidx.compose.ui.Modifier);
+  }
+
+  @Deprecated public final class FocusOrder {
+    ctor @Deprecated public FocusOrder();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getDown();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getEnd();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getLeft();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getNext();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getPrevious();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getRight();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getStart();
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getUp();
+    method @Deprecated public void setDown(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setEnd(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setLeft(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setNext(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setPrevious(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setRight(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setStart(androidx.compose.ui.focus.FocusRequester);
+    method @Deprecated public void setUp(androidx.compose.ui.focus.FocusRequester);
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester down;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester end;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester left;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester next;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester previous;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester right;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester start;
+    property @Deprecated public final androidx.compose.ui.focus.FocusRequester up;
+  }
+
+  @Deprecated @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusOrderModifier extends androidx.compose.ui.Modifier.Element {
+    method @Deprecated public void populateFocusOrder(androidx.compose.ui.focus.FocusOrder focusOrder);
+  }
+
+  public final class FocusOrderModifierKt {
+    method @Deprecated public static androidx.compose.ui.Modifier focusOrder(androidx.compose.ui.Modifier, androidx.compose.ui.focus.FocusRequester focusRequester);
+    method @Deprecated public static androidx.compose.ui.Modifier focusOrder(androidx.compose.ui.Modifier, androidx.compose.ui.focus.FocusRequester focusRequester, kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusOrder,kotlin.Unit> focusOrderReceiver);
+    method @Deprecated public static androidx.compose.ui.Modifier focusOrder(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusOrder,kotlin.Unit> focusOrderReceiver);
+  }
+
+  public interface FocusProperties {
+    method public boolean getCanFocus();
+    method public default androidx.compose.ui.focus.FocusRequester getDown();
+    method public default androidx.compose.ui.focus.FocusRequester getEnd();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getEnter();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getExit();
+    method public default androidx.compose.ui.focus.FocusRequester getLeft();
+    method public default androidx.compose.ui.focus.FocusRequester getNext();
+    method public default androidx.compose.ui.focus.FocusRequester getPrevious();
+    method public default androidx.compose.ui.focus.FocusRequester getRight();
+    method public default androidx.compose.ui.focus.FocusRequester getStart();
+    method public default androidx.compose.ui.focus.FocusRequester getUp();
+    method public void setCanFocus(boolean);
+    method public default void setDown(androidx.compose.ui.focus.FocusRequester);
+    method public default void setEnd(androidx.compose.ui.focus.FocusRequester);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setEnter(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setExit(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
+    method public default void setLeft(androidx.compose.ui.focus.FocusRequester);
+    method public default void setNext(androidx.compose.ui.focus.FocusRequester);
+    method public default void setPrevious(androidx.compose.ui.focus.FocusRequester);
+    method public default void setRight(androidx.compose.ui.focus.FocusRequester);
+    method public default void setStart(androidx.compose.ui.focus.FocusRequester);
+    method public default void setUp(androidx.compose.ui.focus.FocusRequester);
+    property public abstract boolean canFocus;
+    property public default androidx.compose.ui.focus.FocusRequester down;
+    property public default androidx.compose.ui.focus.FocusRequester end;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> enter;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> exit;
+    property public default androidx.compose.ui.focus.FocusRequester left;
+    property public default androidx.compose.ui.focus.FocusRequester next;
+    property public default androidx.compose.ui.focus.FocusRequester previous;
+    property public default androidx.compose.ui.focus.FocusRequester right;
+    property public default androidx.compose.ui.focus.FocusRequester start;
+    property public default androidx.compose.ui.focus.FocusRequester up;
+  }
+
+  public final class FocusPropertiesKt {
+    method public static androidx.compose.ui.Modifier focusProperties(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusProperties,kotlin.Unit> scope);
+  }
+
+  public interface FocusPropertiesModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void applyFocusProperties(androidx.compose.ui.focus.FocusProperties focusProperties);
+  }
+
+  public final class FocusPropertiesModifierNodeKt {
+    method public static void invalidateFocusProperties(androidx.compose.ui.focus.FocusPropertiesModifierNode);
+  }
+
+  @androidx.compose.runtime.Stable public final class FocusRequester {
+    ctor public FocusRequester();
+    method public boolean captureFocus();
+    method public boolean freeFocus();
+    method public void requestFocus();
+    field public static final androidx.compose.ui.focus.FocusRequester.Companion Companion;
+  }
+
+  public static final class FocusRequester.Companion {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory createRefs();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester getCancel();
+    method public androidx.compose.ui.focus.FocusRequester getDefault();
+    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.focus.FocusRequester Cancel;
+    property public final androidx.compose.ui.focus.FocusRequester Default;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public static final class FocusRequester.Companion.FocusRequesterFactory {
+    method public operator androidx.compose.ui.focus.FocusRequester component1();
+    method public operator androidx.compose.ui.focus.FocusRequester component10();
+    method public operator androidx.compose.ui.focus.FocusRequester component11();
+    method public operator androidx.compose.ui.focus.FocusRequester component12();
+    method public operator androidx.compose.ui.focus.FocusRequester component13();
+    method public operator androidx.compose.ui.focus.FocusRequester component14();
+    method public operator androidx.compose.ui.focus.FocusRequester component15();
+    method public operator androidx.compose.ui.focus.FocusRequester component16();
+    method public operator androidx.compose.ui.focus.FocusRequester component2();
+    method public operator androidx.compose.ui.focus.FocusRequester component3();
+    method public operator androidx.compose.ui.focus.FocusRequester component4();
+    method public operator androidx.compose.ui.focus.FocusRequester component5();
+    method public operator androidx.compose.ui.focus.FocusRequester component6();
+    method public operator androidx.compose.ui.focus.FocusRequester component7();
+    method public operator androidx.compose.ui.focus.FocusRequester component8();
+    method public operator androidx.compose.ui.focus.FocusRequester component9();
+    field public static final androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory INSTANCE;
+  }
+
+  @Deprecated @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusRequesterModifier extends androidx.compose.ui.Modifier.Element {
+    method @Deprecated public androidx.compose.ui.focus.FocusRequester getFocusRequester();
+    property @Deprecated public abstract androidx.compose.ui.focus.FocusRequester focusRequester;
+  }
+
+  public final class FocusRequesterModifierKt {
+    method public static androidx.compose.ui.Modifier focusRequester(androidx.compose.ui.Modifier, androidx.compose.ui.focus.FocusRequester focusRequester);
+  }
+
+  public interface FocusRequesterModifierNode extends androidx.compose.ui.node.DelegatableNode {
+  }
+
+  public final class FocusRequesterModifierNodeKt {
+    method public static boolean captureFocus(androidx.compose.ui.focus.FocusRequesterModifierNode);
+    method public static boolean freeFocus(androidx.compose.ui.focus.FocusRequesterModifierNode);
+    method public static boolean requestFocus(androidx.compose.ui.focus.FocusRequesterModifierNode);
+  }
+
+  public interface FocusState {
+    method public boolean getHasFocus();
+    method public boolean isCaptured();
+    method public boolean isFocused();
+    property public abstract boolean hasFocus;
+    property public abstract boolean isCaptured;
+    property public abstract boolean isFocused;
+  }
+
+  public final class FocusTargetNode extends androidx.compose.ui.Modifier.Node implements androidx.compose.ui.modifier.ModifierLocalModifierNode androidx.compose.ui.node.ObserverModifierNode {
+    ctor public FocusTargetNode();
+    method public androidx.compose.ui.focus.FocusState getFocusState();
+    method public void onObservedReadsChanged();
+    property public final androidx.compose.ui.focus.FocusState focusState;
+  }
+
+}
+
+package androidx.compose.ui.graphics {
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class CompositingStrategy {
+    field public static final androidx.compose.ui.graphics.CompositingStrategy.Companion Companion;
+  }
+
+  public static final class CompositingStrategy.Companion {
+    method public int getAuto();
+    method public int getModulateAlpha();
+    method public int getOffscreen();
+    property public final int Auto;
+    property public final int ModulateAlpha;
+    property public final int Offscreen;
+  }
+
+  public final class GraphicsLayerModifierKt {
+    method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier graphicsLayer(androidx.compose.ui.Modifier, optional float scaleX, optional float scaleY, optional float alpha, optional float translationX, optional float translationY, optional float shadowElevation, optional float rotationX, optional float rotationY, optional float rotationZ, optional float cameraDistance, optional long transformOrigin, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip);
+    method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier graphicsLayer(androidx.compose.ui.Modifier, optional float scaleX, optional float scaleY, optional float alpha, optional float translationX, optional float translationY, optional float shadowElevation, optional float rotationX, optional float rotationY, optional float rotationZ, optional float cameraDistance, optional long transformOrigin, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip, optional androidx.compose.ui.graphics.RenderEffect? renderEffect);
+    method @Deprecated @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier graphicsLayer(androidx.compose.ui.Modifier, optional float scaleX, optional float scaleY, optional float alpha, optional float translationX, optional float translationY, optional float shadowElevation, optional float rotationX, optional float rotationY, optional float rotationZ, optional float cameraDistance, optional long transformOrigin, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip, optional androidx.compose.ui.graphics.RenderEffect? renderEffect, optional long ambientShadowColor, optional long spotShadowColor);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier graphicsLayer(androidx.compose.ui.Modifier, optional float scaleX, optional float scaleY, optional float alpha, optional float translationX, optional float translationY, optional float shadowElevation, optional float rotationX, optional float rotationY, optional float rotationZ, optional float cameraDistance, optional long transformOrigin, optional androidx.compose.ui.graphics.Shape shape, optional boolean clip, optional androidx.compose.ui.graphics.RenderEffect? renderEffect, optional long ambientShadowColor, optional long spotShadowColor, optional int compositingStrategy);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier graphicsLayer(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit> block);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier toolingGraphicsLayer(androidx.compose.ui.Modifier);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface GraphicsLayerScope extends androidx.compose.ui.unit.Density {
+    method public float getAlpha();
+    method public default long getAmbientShadowColor();
+    method public float getCameraDistance();
+    method public boolean getClip();
+    method public default int getCompositingStrategy();
+    method public default androidx.compose.ui.graphics.RenderEffect? getRenderEffect();
+    method public float getRotationX();
+    method public float getRotationY();
+    method public float getRotationZ();
+    method public float getScaleX();
+    method public float getScaleY();
+    method public float getShadowElevation();
+    method public androidx.compose.ui.graphics.Shape getShape();
+    method public default long getSize();
+    method public default long getSpotShadowColor();
+    method public long getTransformOrigin();
+    method public float getTranslationX();
+    method public float getTranslationY();
+    method public void setAlpha(float);
+    method public default void setAmbientShadowColor(long);
+    method public void setCameraDistance(float);
+    method public void setClip(boolean);
+    method public default void setCompositingStrategy(int);
+    method public default void setRenderEffect(androidx.compose.ui.graphics.RenderEffect?);
+    method public void setRotationX(float);
+    method public void setRotationY(float);
+    method public void setRotationZ(float);
+    method public void setScaleX(float);
+    method public void setScaleY(float);
+    method public void setShadowElevation(float);
+    method public void setShape(androidx.compose.ui.graphics.Shape);
+    method public default void setSpotShadowColor(long);
+    method public void setTransformOrigin(long);
+    method public void setTranslationX(float);
+    method public void setTranslationY(float);
+    property public abstract float alpha;
+    property public default long ambientShadowColor;
+    property public abstract float cameraDistance;
+    property public abstract boolean clip;
+    property public default int compositingStrategy;
+    property public default androidx.compose.ui.graphics.RenderEffect? renderEffect;
+    property public abstract float rotationX;
+    property public abstract float rotationY;
+    property public abstract float rotationZ;
+    property public abstract float scaleX;
+    property public abstract float scaleY;
+    property public abstract float shadowElevation;
+    property public abstract androidx.compose.ui.graphics.Shape shape;
+    property public default long size;
+    property public default long spotShadowColor;
+    property public abstract long transformOrigin;
+    property public abstract float translationX;
+    property public abstract float translationY;
+  }
+
+  public final class GraphicsLayerScopeKt {
+    method public static androidx.compose.ui.graphics.GraphicsLayerScope GraphicsLayerScope();
+    method public static long getDefaultShadowColor();
+    property public static final long DefaultShadowColor;
+    field public static final float DefaultCameraDistance = 8.0f;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class TransformOrigin {
+    method @androidx.compose.runtime.Stable public inline operator float component1();
+    method @androidx.compose.runtime.Stable public inline operator float component2();
+    method public long copy(optional float pivotFractionX, optional float pivotFractionY);
+    method public float getPivotFractionX();
+    method public float getPivotFractionY();
+    property public final float pivotFractionX;
+    property public final float pivotFractionY;
+    field public static final androidx.compose.ui.graphics.TransformOrigin.Companion Companion;
+  }
+
+  public static final class TransformOrigin.Companion {
+    method public long getCenter();
+    property public final long Center;
+  }
+
+  public final class TransformOriginKt {
+    method public static long TransformOrigin(float pivotFractionX, float pivotFractionY);
+  }
+
+}
+
+package androidx.compose.ui.graphics.vector {
+
+  @androidx.compose.runtime.Immutable public final class ImageVector {
+    method public boolean getAutoMirror();
+    method public float getDefaultHeight();
+    method public float getDefaultWidth();
+    method public String getName();
+    method public androidx.compose.ui.graphics.vector.VectorGroup getRoot();
+    method public int getTintBlendMode();
+    method public long getTintColor();
+    method public float getViewportHeight();
+    method public float getViewportWidth();
+    property public final boolean autoMirror;
+    property public final float defaultHeight;
+    property public final float defaultWidth;
+    property public final String name;
+    property public final androidx.compose.ui.graphics.vector.VectorGroup root;
+    property public final int tintBlendMode;
+    property public final long tintColor;
+    property public final float viewportHeight;
+    property public final float viewportWidth;
+    field public static final androidx.compose.ui.graphics.vector.ImageVector.Companion Companion;
+  }
+
+  public static final class ImageVector.Builder {
+    ctor @Deprecated public ImageVector.Builder(optional String name, float defaultWidth, float defaultHeight, float viewportWidth, float viewportHeight, optional long tintColor, optional int tintBlendMode);
+    ctor public ImageVector.Builder(optional String name, float defaultWidth, float defaultHeight, float viewportWidth, float viewportHeight, optional long tintColor, optional int tintBlendMode, optional boolean autoMirror);
+    method public androidx.compose.ui.graphics.vector.ImageVector.Builder addGroup(optional String name, optional float rotate, optional float pivotX, optional float pivotY, optional float scaleX, optional float scaleY, optional float translationX, optional float translationY, optional java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> clipPathData);
+    method public androidx.compose.ui.graphics.vector.ImageVector.Builder addPath(java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> pathData, optional int pathFillType, optional String name, optional androidx.compose.ui.graphics.Brush? fill, optional float fillAlpha, optional androidx.compose.ui.graphics.Brush? stroke, optional float strokeAlpha, optional float strokeLineWidth, optional int strokeLineCap, optional int strokeLineJoin, optional float strokeLineMiter, optional float trimPathStart, optional float trimPathEnd, optional float trimPathOffset);
+    method public androidx.compose.ui.graphics.vector.ImageVector build();
+    method public androidx.compose.ui.graphics.vector.ImageVector.Builder clearGroup();
+  }
+
+  public static final class ImageVector.Companion {
+  }
+
+  public final class ImageVectorKt {
+    method public static inline androidx.compose.ui.graphics.vector.ImageVector.Builder group(androidx.compose.ui.graphics.vector.ImageVector.Builder, optional String name, optional float rotate, optional float pivotX, optional float pivotY, optional float scaleX, optional float scaleY, optional float translationX, optional float translationY, optional java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> clipPathData, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.vector.ImageVector.Builder,kotlin.Unit> block);
+    method public static inline androidx.compose.ui.graphics.vector.ImageVector.Builder path(androidx.compose.ui.graphics.vector.ImageVector.Builder, optional String name, optional androidx.compose.ui.graphics.Brush? fill, optional float fillAlpha, optional androidx.compose.ui.graphics.Brush? stroke, optional float strokeAlpha, optional float strokeLineWidth, optional int strokeLineCap, optional int strokeLineJoin, optional float strokeLineMiter, optional int pathFillType, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.vector.PathBuilder,kotlin.Unit> pathBuilder);
+  }
+
+  public abstract sealed class VNode {
+    method public abstract void draw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    method public final void invalidate();
+  }
+
+  public final class VectorApplier extends androidx.compose.runtime.AbstractApplier<androidx.compose.ui.graphics.vector.VNode> {
+    ctor public VectorApplier(androidx.compose.ui.graphics.vector.VNode root);
+    method public void insertBottomUp(int index, androidx.compose.ui.graphics.vector.VNode instance);
+    method public void insertTopDown(int index, androidx.compose.ui.graphics.vector.VNode instance);
+    method public void move(int from, int to, int count);
+    method protected void onClear();
+    method public void remove(int index, int count);
+  }
+
+  @androidx.compose.runtime.ComposableTargetMarker(description="Vector Composable") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.FILE, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.TYPE_PARAMETER}) public @interface VectorComposable {
+  }
+
+  public final class VectorComposeKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.graphics.vector.VectorComposable public static void Group(optional String name, optional float rotation, optional float pivotX, optional float pivotY, optional float scaleX, optional float scaleY, optional float translationX, optional float translationY, optional java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> clipPathData, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.graphics.vector.VectorComposable public static void Path(java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode> pathData, optional int pathFillType, optional String name, optional androidx.compose.ui.graphics.Brush? fill, optional float fillAlpha, optional androidx.compose.ui.graphics.Brush? stroke, optional float strokeAlpha, optional float strokeLineWidth, optional int strokeLineCap, optional int strokeLineJoin, optional float strokeLineMiter, optional float trimPathStart, optional float trimPathEnd, optional float trimPathOffset);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface VectorConfig {
+    method public default <T> T getOrDefault(androidx.compose.ui.graphics.vector.VectorProperty<T> property, T defaultValue);
+  }
+
+  @androidx.compose.runtime.Immutable public final class VectorGroup extends androidx.compose.ui.graphics.vector.VectorNode implements java.lang.Iterable<androidx.compose.ui.graphics.vector.VectorNode> kotlin.jvm.internal.markers.KMappedMarker {
+    method public operator androidx.compose.ui.graphics.vector.VectorNode get(int index);
+    method public java.util.List<androidx.compose.ui.graphics.vector.PathNode> getClipPathData();
+    method public String getName();
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getRotation();
+    method public float getScaleX();
+    method public float getScaleY();
+    method public int getSize();
+    method public float getTranslationX();
+    method public float getTranslationY();
+    method public java.util.Iterator<androidx.compose.ui.graphics.vector.VectorNode> iterator();
+    property public final java.util.List<androidx.compose.ui.graphics.vector.PathNode> clipPathData;
+    property public final String name;
+    property public final float pivotX;
+    property public final float pivotY;
+    property public final float rotation;
+    property public final float scaleX;
+    property public final float scaleY;
+    property public final int size;
+    property public final float translationX;
+    property public final float translationY;
+  }
+
+  public final class VectorKt {
+    method public static inline java.util.List<androidx.compose.ui.graphics.vector.PathNode> PathData(kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.vector.PathBuilder,kotlin.Unit> block);
+    method public static java.util.List<androidx.compose.ui.graphics.vector.PathNode> addPathNodes(String? pathStr);
+    method public static int getDefaultFillType();
+    method public static int getDefaultStrokeLineCap();
+    method public static int getDefaultStrokeLineJoin();
+    method public static int getDefaultTintBlendMode();
+    method public static long getDefaultTintColor();
+    method public static java.util.List<androidx.compose.ui.graphics.vector.PathNode> getEmptyPath();
+    property public static final int DefaultFillType;
+    property public static final int DefaultStrokeLineCap;
+    property public static final int DefaultStrokeLineJoin;
+    property public static final int DefaultTintBlendMode;
+    property public static final long DefaultTintColor;
+    property public static final java.util.List<androidx.compose.ui.graphics.vector.PathNode> EmptyPath;
+    field public static final String DefaultGroupName = "";
+    field public static final String DefaultPathName = "";
+    field public static final float DefaultPivotX = 0.0f;
+    field public static final float DefaultPivotY = 0.0f;
+    field public static final float DefaultRotation = 0.0f;
+    field public static final float DefaultScaleX = 1.0f;
+    field public static final float DefaultScaleY = 1.0f;
+    field public static final float DefaultStrokeLineMiter = 4.0f;
+    field public static final float DefaultStrokeLineWidth = 0.0f;
+    field public static final float DefaultTranslationX = 0.0f;
+    field public static final float DefaultTranslationY = 0.0f;
+    field public static final float DefaultTrimPathEnd = 1.0f;
+    field public static final float DefaultTrimPathOffset = 0.0f;
+    field public static final float DefaultTrimPathStart = 0.0f;
+  }
+
+  public abstract sealed class VectorNode {
+  }
+
+  public final class VectorPainter extends androidx.compose.ui.graphics.painter.Painter {
+    method public long getIntrinsicSize();
+    method protected void onDraw(androidx.compose.ui.graphics.drawscope.DrawScope);
+    property public long intrinsicSize;
+  }
+
+  public final class VectorPainterKt {
+    method @androidx.compose.runtime.Composable public static void RenderVectorGroup(androidx.compose.ui.graphics.vector.VectorGroup group, optional java.util.Map<java.lang.String,? extends androidx.compose.ui.graphics.vector.VectorConfig> configs);
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.vector.VectorPainter rememberVectorPainter(androidx.compose.ui.graphics.vector.ImageVector image);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static androidx.compose.ui.graphics.vector.VectorPainter rememberVectorPainter(float defaultWidth, float defaultHeight, optional float viewportWidth, optional float viewportHeight, optional String name, optional long tintColor, optional int tintBlendMode, optional boolean autoMirror, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> content);
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.runtime.ComposableOpenTarget(index=0xffffffff) public static androidx.compose.ui.graphics.vector.VectorPainter rememberVectorPainter(float defaultWidth, float defaultHeight, optional float viewportWidth, optional float viewportHeight, optional String name, optional long tintColor, optional int tintBlendMode, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,kotlin.Unit> content);
+    field public static final String RootGroupName = "VectorRootGroup";
+  }
+
+  @androidx.compose.runtime.Immutable public final class VectorPath extends androidx.compose.ui.graphics.vector.VectorNode {
+    method public androidx.compose.ui.graphics.Brush? getFill();
+    method public float getFillAlpha();
+    method public String getName();
+    method public java.util.List<androidx.compose.ui.graphics.vector.PathNode> getPathData();
+    method public int getPathFillType();
+    method public androidx.compose.ui.graphics.Brush? getStroke();
+    method public float getStrokeAlpha();
+    method public int getStrokeLineCap();
+    method public int getStrokeLineJoin();
+    method public float getStrokeLineMiter();
+    method public float getStrokeLineWidth();
+    method public float getTrimPathEnd();
+    method public float getTrimPathOffset();
+    method public float getTrimPathStart();
+    property public final androidx.compose.ui.graphics.Brush? fill;
+    property public final float fillAlpha;
+    property public final String name;
+    property public final java.util.List<androidx.compose.ui.graphics.vector.PathNode> pathData;
+    property public final int pathFillType;
+    property public final androidx.compose.ui.graphics.Brush? stroke;
+    property public final float strokeAlpha;
+    property public final int strokeLineCap;
+    property public final int strokeLineJoin;
+    property public final float strokeLineMiter;
+    property public final float strokeLineWidth;
+    property public final float trimPathEnd;
+    property public final float trimPathOffset;
+    property public final float trimPathStart;
+  }
+
+  public abstract sealed class VectorProperty<T> {
+  }
+
+  public static final class VectorProperty.Fill extends androidx.compose.ui.graphics.vector.VectorProperty<androidx.compose.ui.graphics.Brush> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.Fill INSTANCE;
+  }
+
+  public static final class VectorProperty.FillAlpha extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.FillAlpha INSTANCE;
+  }
+
+  public static final class VectorProperty.PathData extends androidx.compose.ui.graphics.vector.VectorProperty<java.util.List<? extends androidx.compose.ui.graphics.vector.PathNode>> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.PathData INSTANCE;
+  }
+
+  public static final class VectorProperty.PivotX extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.PivotX INSTANCE;
+  }
+
+  public static final class VectorProperty.PivotY extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.PivotY INSTANCE;
+  }
+
+  public static final class VectorProperty.Rotation extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.Rotation INSTANCE;
+  }
+
+  public static final class VectorProperty.ScaleX extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.ScaleX INSTANCE;
+  }
+
+  public static final class VectorProperty.ScaleY extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.ScaleY INSTANCE;
+  }
+
+  public static final class VectorProperty.Stroke extends androidx.compose.ui.graphics.vector.VectorProperty<androidx.compose.ui.graphics.Brush> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.Stroke INSTANCE;
+  }
+
+  public static final class VectorProperty.StrokeAlpha extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.StrokeAlpha INSTANCE;
+  }
+
+  public static final class VectorProperty.StrokeLineWidth extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.StrokeLineWidth INSTANCE;
+  }
+
+  public static final class VectorProperty.TranslateX extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.TranslateX INSTANCE;
+  }
+
+  public static final class VectorProperty.TranslateY extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.TranslateY INSTANCE;
+  }
+
+  public static final class VectorProperty.TrimPathEnd extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.TrimPathEnd INSTANCE;
+  }
+
+  public static final class VectorProperty.TrimPathOffset extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.TrimPathOffset INSTANCE;
+  }
+
+  public static final class VectorProperty.TrimPathStart extends androidx.compose.ui.graphics.vector.VectorProperty<java.lang.Float> {
+    field public static final androidx.compose.ui.graphics.vector.VectorProperty.TrimPathStart INSTANCE;
+  }
+
+}
+
+package androidx.compose.ui.hapticfeedback {
+
+  public interface HapticFeedback {
+    method public void performHapticFeedback(int hapticFeedbackType);
+  }
+
+  @kotlin.jvm.JvmInline public final value class HapticFeedbackType {
+    ctor public HapticFeedbackType(int value);
+    field public static final androidx.compose.ui.hapticfeedback.HapticFeedbackType.Companion Companion;
+  }
+
+  public static final class HapticFeedbackType.Companion {
+    method public int getLongPress();
+    method public int getTextHandleMove();
+    method public java.util.List<androidx.compose.ui.hapticfeedback.HapticFeedbackType> values();
+    property public final int LongPress;
+    property public final int TextHandleMove;
+  }
+
+}
+
+package androidx.compose.ui.input {
+
+  @kotlin.jvm.JvmInline public final value class InputMode {
+    field public static final androidx.compose.ui.input.InputMode.Companion Companion;
+  }
+
+  public static final class InputMode.Companion {
+    method public int getKeyboard();
+    method public int getTouch();
+    property public final int Keyboard;
+    property public final int Touch;
+  }
+
+  public interface InputModeManager {
+    method public int getInputMode();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public boolean requestInputMode(int inputMode);
+    property public abstract int inputMode;
+  }
+
+}
+
+package androidx.compose.ui.input.key {
+
+  @kotlin.jvm.JvmInline public final value class Key {
+    ctor public Key(long keyCode);
+    method public long getKeyCode();
+    property public final long keyCode;
+    field public static final androidx.compose.ui.input.key.Key.Companion Companion;
+  }
+
+  public static final class Key.Companion {
+    method public long getA();
+    method public long getAllApps();
+    method public long getAltLeft();
+    method public long getAltRight();
+    method public long getApostrophe();
+    method public long getAppSwitch();
+    method public long getAssist();
+    method public long getAt();
+    method public long getAvReceiverInput();
+    method public long getAvReceiverPower();
+    method public long getB();
+    method public long getBack();
+    method public long getBackslash();
+    method public long getBackspace();
+    method public long getBookmark();
+    method public long getBreak();
+    method public long getBrightnessDown();
+    method public long getBrightnessUp();
+    method public long getBrowser();
+    method public long getButton1();
+    method public long getButton10();
+    method public long getButton11();
+    method public long getButton12();
+    method public long getButton13();
+    method public long getButton14();
+    method public long getButton15();
+    method public long getButton16();
+    method public long getButton2();
+    method public long getButton3();
+    method public long getButton4();
+    method public long getButton5();
+    method public long getButton6();
+    method public long getButton7();
+    method public long getButton8();
+    method public long getButton9();
+    method public long getButtonA();
+    method public long getButtonB();
+    method public long getButtonC();
+    method public long getButtonL1();
+    method public long getButtonL2();
+    method public long getButtonMode();
+    method public long getButtonR1();
+    method public long getButtonR2();
+    method public long getButtonSelect();
+    method public long getButtonStart();
+    method public long getButtonThumbLeft();
+    method public long getButtonThumbRight();
+    method public long getButtonX();
+    method public long getButtonY();
+    method public long getButtonZ();
+    method public long getC();
+    method public long getCalculator();
+    method public long getCalendar();
+    method public long getCall();
+    method public long getCamera();
+    method public long getCapsLock();
+    method public long getCaptions();
+    method public long getChannelDown();
+    method public long getChannelUp();
+    method public long getClear();
+    method public long getComma();
+    method public long getContacts();
+    method public long getCopy();
+    method public long getCtrlLeft();
+    method public long getCtrlRight();
+    method public long getCut();
+    method public long getD();
+    method public long getDelete();
+    method public long getDirectionCenter();
+    method public long getDirectionDown();
+    method public long getDirectionDownLeft();
+    method public long getDirectionDownRight();
+    method public long getDirectionLeft();
+    method public long getDirectionRight();
+    method public long getDirectionUp();
+    method public long getDirectionUpLeft();
+    method public long getDirectionUpRight();
+    method public long getDvr();
+    method public long getE();
+    method public long getEight();
+    method public long getEisu();
+    method public long getEndCall();
+    method public long getEnter();
+    method public long getEnvelope();
+    method public long getEquals();
+    method public long getEscape();
+    method public long getF();
+    method public long getF1();
+    method public long getF10();
+    method public long getF11();
+    method public long getF12();
+    method public long getF2();
+    method public long getF3();
+    method public long getF4();
+    method public long getF5();
+    method public long getF6();
+    method public long getF7();
+    method public long getF8();
+    method public long getF9();
+    method public long getFive();
+    method public long getFocus();
+    method public long getForward();
+    method public long getFour();
+    method public long getFunction();
+    method public long getG();
+    method public long getGrave();
+    method public long getGuide();
+    method public long getH();
+    method public long getHeadsetHook();
+    method public long getHelp();
+    method public long getHenkan();
+    method public long getHome();
+    method public long getI();
+    method public long getInfo();
+    method public long getInsert();
+    method public long getJ();
+    method public long getK();
+    method public long getKana();
+    method public long getKatakanaHiragana();
+    method public long getL();
+    method public long getLanguageSwitch();
+    method public long getLastChannel();
+    method public long getLeftBracket();
+    method public long getM();
+    method public long getMannerMode();
+    method public long getMediaAudioTrack();
+    method public long getMediaClose();
+    method public long getMediaEject();
+    method public long getMediaFastForward();
+    method public long getMediaNext();
+    method public long getMediaPause();
+    method public long getMediaPlay();
+    method public long getMediaPlayPause();
+    method public long getMediaPrevious();
+    method public long getMediaRecord();
+    method public long getMediaRewind();
+    method public long getMediaSkipBackward();
+    method public long getMediaSkipForward();
+    method public long getMediaStepBackward();
+    method public long getMediaStepForward();
+    method public long getMediaStop();
+    method public long getMediaTopMenu();
+    method public long getMenu();
+    method public long getMetaLeft();
+    method public long getMetaRight();
+    method public long getMicrophoneMute();
+    method public long getMinus();
+    method public long getMoveEnd();
+    method public long getMoveHome();
+    method public long getMuhenkan();
+    method public long getMultiply();
+    method public long getMusic();
+    method public long getN();
+    method public long getNavigateIn();
+    method public long getNavigateNext();
+    method public long getNavigateOut();
+    method public long getNavigatePrevious();
+    method public long getNine();
+    method public long getNotification();
+    method public long getNumLock();
+    method public long getNumPad0();
+    method public long getNumPad1();
+    method public long getNumPad2();
+    method public long getNumPad3();
+    method public long getNumPad4();
+    method public long getNumPad5();
+    method public long getNumPad6();
+    method public long getNumPad7();
+    method public long getNumPad8();
+    method public long getNumPad9();
+    method public long getNumPadAdd();
+    method public long getNumPadComma();
+    method public long getNumPadDivide();
+    method public long getNumPadDot();
+    method public long getNumPadEnter();
+    method public long getNumPadEquals();
+    method public long getNumPadLeftParenthesis();
+    method public long getNumPadMultiply();
+    method public long getNumPadRightParenthesis();
+    method public long getNumPadSubtract();
+    method public long getNumber();
+    method public long getO();
+    method public long getOne();
+    method public long getP();
+    method public long getPageDown();
+    method public long getPageUp();
+    method public long getPairing();
+    method public long getPaste();
+    method public long getPeriod();
+    method public long getPictureSymbols();
+    method public long getPlus();
+    method public long getPound();
+    method public long getPower();
+    method public long getPrintScreen();
+    method public long getProfileSwitch();
+    method public long getProgramBlue();
+    method public long getProgramGreen();
+    method public long getProgramRed();
+    method public long getProgramYellow();
+    method public long getQ();
+    method public long getR();
+    method public long getRefresh();
+    method public long getRightBracket();
+    method public long getRo();
+    method public long getS();
+    method public long getScrollLock();
+    method public long getSearch();
+    method public long getSemicolon();
+    method public long getSetTopBoxInput();
+    method public long getSetTopBoxPower();
+    method public long getSettings();
+    method public long getSeven();
+    method public long getShiftLeft();
+    method public long getShiftRight();
+    method public long getSix();
+    method public long getSlash();
+    method public long getSleep();
+    method public long getSoftLeft();
+    method public long getSoftRight();
+    method public long getSoftSleep();
+    method public long getSpacebar();
+    method public long getStem1();
+    method public long getStem2();
+    method public long getStem3();
+    method public long getStemPrimary();
+    method public long getSwitchCharset();
+    method public long getSymbol();
+    method public long getSystemNavigationDown();
+    method public long getSystemNavigationLeft();
+    method public long getSystemNavigationRight();
+    method public long getSystemNavigationUp();
+    method public long getT();
+    method public long getTab();
+    method public long getThree();
+    method public long getThumbsDown();
+    method public long getThumbsUp();
+    method public long getToggle2D3D();
+    method public long getTv();
+    method public long getTvAntennaCable();
+    method public long getTvAudioDescription();
+    method public long getTvAudioDescriptionMixingVolumeDown();
+    method public long getTvAudioDescriptionMixingVolumeUp();
+    method public long getTvContentsMenu();
+    method public long getTvDataService();
+    method public long getTvInput();
+    method public long getTvInputComponent1();
+    method public long getTvInputComponent2();
+    method public long getTvInputComposite1();
+    method public long getTvInputComposite2();
+    method public long getTvInputHdmi1();
+    method public long getTvInputHdmi2();
+    method public long getTvInputHdmi3();
+    method public long getTvInputHdmi4();
+    method public long getTvInputVga1();
+    method public long getTvMediaContextMenu();
+    method public long getTvNetwork();
+    method public long getTvNumberEntry();
+    method public long getTvPower();
+    method public long getTvRadioService();
+    method public long getTvSatellite();
+    method public long getTvSatelliteBs();
+    method public long getTvSatelliteCs();
+    method public long getTvSatelliteService();
+    method public long getTvTeletext();
+    method public long getTvTerrestrialAnalog();
+    method public long getTvTerrestrialDigital();
+    method public long getTvTimerProgramming();
+    method public long getTvZoomMode();
+    method public long getTwo();
+    method public long getU();
+    method public long getUnknown();
+    method public long getV();
+    method public long getVoiceAssist();
+    method public long getVolumeDown();
+    method public long getVolumeMute();
+    method public long getVolumeUp();
+    method public long getW();
+    method public long getWakeUp();
+    method public long getWindow();
+    method public long getX();
+    method public long getY();
+    method public long getYen();
+    method public long getZ();
+    method public long getZenkakuHankaru();
+    method public long getZero();
+    method public long getZoomIn();
+    method public long getZoomOut();
+    property public final long A;
+    property public final long AllApps;
+    property public final long AltLeft;
+    property public final long AltRight;
+    property public final long Apostrophe;
+    property public final long AppSwitch;
+    property public final long Assist;
+    property public final long At;
+    property public final long AvReceiverInput;
+    property public final long AvReceiverPower;
+    property public final long B;
+    property public final long Back;
+    property public final long Backslash;
+    property public final long Backspace;
+    property public final long Bookmark;
+    property public final long Break;
+    property public final long BrightnessDown;
+    property public final long BrightnessUp;
+    property public final long Browser;
+    property public final long Button1;
+    property public final long Button10;
+    property public final long Button11;
+    property public final long Button12;
+    property public final long Button13;
+    property public final long Button14;
+    property public final long Button15;
+    property public final long Button16;
+    property public final long Button2;
+    property public final long Button3;
+    property public final long Button4;
+    property public final long Button5;
+    property public final long Button6;
+    property public final long Button7;
+    property public final long Button8;
+    property public final long Button9;
+    property public final long ButtonA;
+    property public final long ButtonB;
+    property public final long ButtonC;
+    property public final long ButtonL1;
+    property public final long ButtonL2;
+    property public final long ButtonMode;
+    property public final long ButtonR1;
+    property public final long ButtonR2;
+    property public final long ButtonSelect;
+    property public final long ButtonStart;
+    property public final long ButtonThumbLeft;
+    property public final long ButtonThumbRight;
+    property public final long ButtonX;
+    property public final long ButtonY;
+    property public final long ButtonZ;
+    property public final long C;
+    property public final long Calculator;
+    property public final long Calendar;
+    property public final long Call;
+    property public final long Camera;
+    property public final long CapsLock;
+    property public final long Captions;
+    property public final long ChannelDown;
+    property public final long ChannelUp;
+    property public final long Clear;
+    property public final long Comma;
+    property public final long Contacts;
+    property public final long Copy;
+    property public final long CtrlLeft;
+    property public final long CtrlRight;
+    property public final long Cut;
+    property public final long D;
+    property public final long Delete;
+    property public final long DirectionCenter;
+    property public final long DirectionDown;
+    property public final long DirectionDownLeft;
+    property public final long DirectionDownRight;
+    property public final long DirectionLeft;
+    property public final long DirectionRight;
+    property public final long DirectionUp;
+    property public final long DirectionUpLeft;
+    property public final long DirectionUpRight;
+    property public final long Dvr;
+    property public final long E;
+    property public final long Eight;
+    property public final long Eisu;
+    property public final long EndCall;
+    property public final long Enter;
+    property public final long Envelope;
+    property public final long Equals;
+    property public final long Escape;
+    property public final long F;
+    property public final long F1;
+    property public final long F10;
+    property public final long F11;
+    property public final long F12;
+    property public final long F2;
+    property public final long F3;
+    property public final long F4;
+    property public final long F5;
+    property public final long F6;
+    property public final long F7;
+    property public final long F8;
+    property public final long F9;
+    property public final long Five;
+    property public final long Focus;
+    property public final long Forward;
+    property public final long Four;
+    property public final long Function;
+    property public final long G;
+    property public final long Grave;
+    property public final long Guide;
+    property public final long H;
+    property public final long HeadsetHook;
+    property public final long Help;
+    property public final long Henkan;
+    property public final long Home;
+    property public final long I;
+    property public final long Info;
+    property public final long Insert;
+    property public final long J;
+    property public final long K;
+    property public final long Kana;
+    property public final long KatakanaHiragana;
+    property public final long L;
+    property public final long LanguageSwitch;
+    property public final long LastChannel;
+    property public final long LeftBracket;
+    property public final long M;
+    property public final long MannerMode;
+    property public final long MediaAudioTrack;
+    property public final long MediaClose;
+    property public final long MediaEject;
+    property public final long MediaFastForward;
+    property public final long MediaNext;
+    property public final long MediaPause;
+    property public final long MediaPlay;
+    property public final long MediaPlayPause;
+    property public final long MediaPrevious;
+    property public final long MediaRecord;
+    property public final long MediaRewind;
+    property public final long MediaSkipBackward;
+    property public final long MediaSkipForward;
+    property public final long MediaStepBackward;
+    property public final long MediaStepForward;
+    property public final long MediaStop;
+    property public final long MediaTopMenu;
+    property public final long Menu;
+    property public final long MetaLeft;
+    property public final long MetaRight;
+    property public final long MicrophoneMute;
+    property public final long Minus;
+    property public final long MoveEnd;
+    property public final long MoveHome;
+    property public final long Muhenkan;
+    property public final long Multiply;
+    property public final long Music;
+    property public final long N;
+    property public final long NavigateIn;
+    property public final long NavigateNext;
+    property public final long NavigateOut;
+    property public final long NavigatePrevious;
+    property public final long Nine;
+    property public final long Notification;
+    property public final long NumLock;
+    property public final long NumPad0;
+    property public final long NumPad1;
+    property public final long NumPad2;
+    property public final long NumPad3;
+    property public final long NumPad4;
+    property public final long NumPad5;
+    property public final long NumPad6;
+    property public final long NumPad7;
+    property public final long NumPad8;
+    property public final long NumPad9;
+    property public final long NumPadAdd;
+    property public final long NumPadComma;
+    property public final long NumPadDivide;
+    property public final long NumPadDot;
+    property public final long NumPadEnter;
+    property public final long NumPadEquals;
+    property public final long NumPadLeftParenthesis;
+    property public final long NumPadMultiply;
+    property public final long NumPadRightParenthesis;
+    property public final long NumPadSubtract;
+    property public final long Number;
+    property public final long O;
+    property public final long One;
+    property public final long P;
+    property public final long PageDown;
+    property public final long PageUp;
+    property public final long Pairing;
+    property public final long Paste;
+    property public final long Period;
+    property public final long PictureSymbols;
+    property public final long Plus;
+    property public final long Pound;
+    property public final long Power;
+    property public final long PrintScreen;
+    property public final long ProfileSwitch;
+    property public final long ProgramBlue;
+    property public final long ProgramGreen;
+    property public final long ProgramRed;
+    property public final long ProgramYellow;
+    property public final long Q;
+    property public final long R;
+    property public final long Refresh;
+    property public final long RightBracket;
+    property public final long Ro;
+    property public final long S;
+    property public final long ScrollLock;
+    property public final long Search;
+    property public final long Semicolon;
+    property public final long SetTopBoxInput;
+    property public final long SetTopBoxPower;
+    property public final long Settings;
+    property public final long Seven;
+    property public final long ShiftLeft;
+    property public final long ShiftRight;
+    property public final long Six;
+    property public final long Slash;
+    property public final long Sleep;
+    property public final long SoftLeft;
+    property public final long SoftRight;
+    property public final long SoftSleep;
+    property public final long Spacebar;
+    property public final long Stem1;
+    property public final long Stem2;
+    property public final long Stem3;
+    property public final long StemPrimary;
+    property public final long SwitchCharset;
+    property public final long Symbol;
+    property public final long SystemNavigationDown;
+    property public final long SystemNavigationLeft;
+    property public final long SystemNavigationRight;
+    property public final long SystemNavigationUp;
+    property public final long T;
+    property public final long Tab;
+    property public final long Three;
+    property public final long ThumbsDown;
+    property public final long ThumbsUp;
+    property public final long Toggle2D3D;
+    property public final long Tv;
+    property public final long TvAntennaCable;
+    property public final long TvAudioDescription;
+    property public final long TvAudioDescriptionMixingVolumeDown;
+    property public final long TvAudioDescriptionMixingVolumeUp;
+    property public final long TvContentsMenu;
+    property public final long TvDataService;
+    property public final long TvInput;
+    property public final long TvInputComponent1;
+    property public final long TvInputComponent2;
+    property public final long TvInputComposite1;
+    property public final long TvInputComposite2;
+    property public final long TvInputHdmi1;
+    property public final long TvInputHdmi2;
+    property public final long TvInputHdmi3;
+    property public final long TvInputHdmi4;
+    property public final long TvInputVga1;
+    property public final long TvMediaContextMenu;
+    property public final long TvNetwork;
+    property public final long TvNumberEntry;
+    property public final long TvPower;
+    property public final long TvRadioService;
+    property public final long TvSatellite;
+    property public final long TvSatelliteBs;
+    property public final long TvSatelliteCs;
+    property public final long TvSatelliteService;
+    property public final long TvTeletext;
+    property public final long TvTerrestrialAnalog;
+    property public final long TvTerrestrialDigital;
+    property public final long TvTimerProgramming;
+    property public final long TvZoomMode;
+    property public final long Two;
+    property public final long U;
+    property public final long Unknown;
+    property public final long V;
+    property public final long VoiceAssist;
+    property public final long VolumeDown;
+    property public final long VolumeMute;
+    property public final long VolumeUp;
+    property public final long W;
+    property public final long WakeUp;
+    property public final long Window;
+    property public final long X;
+    property public final long Y;
+    property public final long Yen;
+    property public final long Z;
+    property public final long ZenkakuHankaru;
+    property public final long Zero;
+    property public final long ZoomIn;
+    property public final long ZoomOut;
+  }
+
+  @kotlin.jvm.JvmInline public final value class KeyEvent {
+    ctor public KeyEvent(android.view.KeyEvent nativeKeyEvent);
+    method public android.view.KeyEvent getNativeKeyEvent();
+    property public final android.view.KeyEvent nativeKeyEvent;
+  }
+
+  @kotlin.jvm.JvmInline public final value class KeyEventType {
+    field public static final androidx.compose.ui.input.key.KeyEventType.Companion Companion;
+  }
+
+  public static final class KeyEventType.Companion {
+    method public int getKeyDown();
+    method public int getKeyUp();
+    method public int getUnknown();
+    property public final int KeyDown;
+    property public final int KeyUp;
+    property public final int Unknown;
+  }
+
+  public final class KeyEvent_androidKt {
+    method public static long getKey(android.view.KeyEvent);
+    method public static int getType(android.view.KeyEvent);
+    method public static int getUtf16CodePoint(android.view.KeyEvent);
+    method public static boolean isAltPressed(android.view.KeyEvent);
+    method public static boolean isCtrlPressed(android.view.KeyEvent);
+    method public static boolean isMetaPressed(android.view.KeyEvent);
+    method public static boolean isShiftPressed(android.view.KeyEvent);
+  }
+
+  public final class KeyInputModifierKt {
+    method public static androidx.compose.ui.Modifier onKeyEvent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onKeyEvent);
+    method public static androidx.compose.ui.Modifier onPreviewKeyEvent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onPreviewKeyEvent);
+  }
+
+  public interface KeyInputModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public boolean onKeyEvent(android.view.KeyEvent event);
+    method public boolean onPreKeyEvent(android.view.KeyEvent event);
+  }
+
+  public final class Key_androidKt {
+    method public static long Key(int nativeKeyCode);
+    method public static int getNativeKeyCode(long);
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftKeyboardInterceptionModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public boolean onInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
+    method public boolean onPreInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
+  }
+
+  public final class SoftwareKeyboardInterceptionModifierKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onInterceptKeyBeforeSoftKeyboard);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onPreInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onPreInterceptKeyBeforeSoftKeyboard);
+  }
+
+}
+
+package androidx.compose.ui.input.nestedscroll {
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface NestedScrollConnection {
+    method public default suspend Object? onPostFling(long consumed, long available, kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>);
+    method public default long onPostScroll(long consumed, long available, int source);
+    method public default suspend Object? onPreFling(long available, kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>);
+    method public default long onPreScroll(long available, int source);
+  }
+
+  public final class NestedScrollDispatcher {
+    ctor public NestedScrollDispatcher();
+    method public suspend Object? dispatchPostFling(long consumed, long available, kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>);
+    method public long dispatchPostScroll(long consumed, long available, int source);
+    method public suspend Object? dispatchPreFling(long available, kotlin.coroutines.Continuation<? super androidx.compose.ui.unit.Velocity>);
+    method public long dispatchPreScroll(long available, int source);
+    method public kotlinx.coroutines.CoroutineScope getCoroutineScope();
+    property public final kotlinx.coroutines.CoroutineScope coroutineScope;
+  }
+
+  public final class NestedScrollModifierKt {
+    method public static androidx.compose.ui.Modifier nestedScroll(androidx.compose.ui.Modifier, androidx.compose.ui.input.nestedscroll.NestedScrollConnection connection, optional androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher? dispatcher);
+  }
+
+  public final class NestedScrollNodeKt {
+    method public static androidx.compose.ui.node.DelegatableNode nestedScrollModifierNode(androidx.compose.ui.input.nestedscroll.NestedScrollConnection connection, androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher? dispatcher);
+  }
+
+  @kotlin.jvm.JvmInline public final value class NestedScrollSource {
+    field public static final androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion Companion;
+  }
+
+  public static final class NestedScrollSource.Companion {
+    method public int getDrag();
+    method public int getFling();
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getRelocate();
+    property public final int Drag;
+    property public final int Fling;
+    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Relocate;
+  }
+
+}
+
+package androidx.compose.ui.input.pointer {
+
+  @kotlin.coroutines.RestrictsSuspension @kotlin.jvm.JvmDefaultWithCompatibility public interface AwaitPointerEventScope extends androidx.compose.ui.unit.Density {
+    method public suspend Object? awaitPointerEvent(optional androidx.compose.ui.input.pointer.PointerEventPass pass, optional kotlin.coroutines.Continuation<? super androidx.compose.ui.input.pointer.PointerEvent>);
+    method public androidx.compose.ui.input.pointer.PointerEvent getCurrentEvent();
+    method public default long getExtendedTouchPadding();
+    method public long getSize();
+    method public androidx.compose.ui.platform.ViewConfiguration getViewConfiguration();
+    method public default suspend <T> Object? withTimeout(long timeMillis, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.AwaitPointerEventScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method public default suspend <T> Object? withTimeoutOrNull(long timeMillis, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.AwaitPointerEventScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    property public abstract androidx.compose.ui.input.pointer.PointerEvent currentEvent;
+    property public default long extendedTouchPadding;
+    property public abstract long size;
+    property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
+  }
+
+  @Deprecated public final class ConsumedData {
+    ctor @Deprecated public ConsumedData(optional @Deprecated boolean positionChange, optional @Deprecated boolean downChange);
+    method @Deprecated public boolean getDownChange();
+    method @Deprecated public boolean getPositionChange();
+    method @Deprecated public void setDownChange(boolean);
+    method @Deprecated public void setPositionChange(boolean);
+    property @Deprecated public final boolean downChange;
+    property @Deprecated public final boolean positionChange;
+  }
+
+  @androidx.compose.runtime.Immutable @androidx.compose.ui.ExperimentalComposeUiApi public final class HistoricalChange {
+    ctor public HistoricalChange(long uptimeMillis, long position);
+    method public long getPosition();
+    method public long getUptimeMillis();
+    property public final long position;
+    property public final long uptimeMillis;
+  }
+
+  @kotlin.jvm.JvmInline public final value class PointerButtons {
+    ctor public PointerButtons(int packedValue);
+  }
+
+  public final class PointerEvent {
+    ctor public PointerEvent(java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes);
+    method public java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> component1();
+    method public androidx.compose.ui.input.pointer.PointerEvent copy(java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes, android.view.MotionEvent? motionEvent);
+    method public int getButtons();
+    method public java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> getChanges();
+    method public int getKeyboardModifiers();
+    method public int getType();
+    property public final int buttons;
+    property public final java.util.List<androidx.compose.ui.input.pointer.PointerInputChange> changes;
+    property public final int keyboardModifiers;
+    property public final int type;
+  }
+
+  public final class PointerEventKt {
+    method @Deprecated public static boolean anyChangeConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean changedToDown(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean changedToDownIgnoreConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean changedToUp(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean changedToUpIgnoreConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+    method @Deprecated public static void consumeAllChanges(androidx.compose.ui.input.pointer.PointerInputChange);
+    method @Deprecated public static void consumeDownChange(androidx.compose.ui.input.pointer.PointerInputChange);
+    method @Deprecated public static void consumePositionChange(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static int indexOfFirstPressed(int);
+    method public static int indexOfLastPressed(int);
+    method @Deprecated public static boolean isOutOfBounds(androidx.compose.ui.input.pointer.PointerInputChange, long size);
+    method public static boolean isOutOfBounds(androidx.compose.ui.input.pointer.PointerInputChange, long size, long extendedTouchPadding);
+    method public static boolean isPressed(int, int buttonIndex);
+    method public static long positionChange(androidx.compose.ui.input.pointer.PointerInputChange);
+    method @Deprecated public static boolean positionChangeConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static long positionChangeIgnoreConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean positionChanged(androidx.compose.ui.input.pointer.PointerInputChange);
+    method public static boolean positionChangedIgnoreConsumed(androidx.compose.ui.input.pointer.PointerInputChange);
+  }
+
+  public enum PointerEventPass {
+    method public static androidx.compose.ui.input.pointer.PointerEventPass valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.input.pointer.PointerEventPass[] values();
+    enum_constant public static final androidx.compose.ui.input.pointer.PointerEventPass Final;
+    enum_constant public static final androidx.compose.ui.input.pointer.PointerEventPass Initial;
+    enum_constant public static final androidx.compose.ui.input.pointer.PointerEventPass Main;
+  }
+
+  public final class PointerEventTimeoutCancellationException extends java.util.concurrent.CancellationException {
+    ctor public PointerEventTimeoutCancellationException(long time);
+  }
+
+  @kotlin.jvm.JvmInline public final value class PointerEventType {
+    field public static final androidx.compose.ui.input.pointer.PointerEventType.Companion Companion;
+  }
+
+  public static final class PointerEventType.Companion {
+    method public int getEnter();
+    method public int getExit();
+    method public int getMove();
+    method public int getPress();
+    method public int getRelease();
+    method public int getScroll();
+    method public int getUnknown();
+    property public final int Enter;
+    property public final int Exit;
+    property public final int Move;
+    property public final int Press;
+    property public final int Release;
+    property public final int Scroll;
+    property public final int Unknown;
+  }
+
+  public final class PointerEvent_androidKt {
+    method public static boolean getAreAnyPressed(int);
+    method public static int indexOfFirstPressed(int);
+    method public static int indexOfLastPressed(int);
+    method public static boolean isAltGraphPressed(int);
+    method public static boolean isAltPressed(int);
+    method public static boolean isBackPressed(int);
+    method public static boolean isCapsLockOn(int);
+    method public static boolean isCtrlPressed(int);
+    method public static boolean isForwardPressed(int);
+    method public static boolean isFunctionPressed(int);
+    method public static boolean isMetaPressed(int);
+    method public static boolean isNumLockOn(int);
+    method public static boolean isPressed(int, int buttonIndex);
+    method public static boolean isPrimaryPressed(int);
+    method public static boolean isScrollLockOn(int);
+    method public static boolean isSecondaryPressed(int);
+    method public static boolean isShiftPressed(int);
+    method public static boolean isSymPressed(int);
+    method public static boolean isTertiaryPressed(int);
+  }
+
+  @androidx.compose.runtime.Stable public interface PointerIcon {
+    field public static final androidx.compose.ui.input.pointer.PointerIcon.Companion Companion;
+  }
+
+  public static final class PointerIcon.Companion {
+    method public androidx.compose.ui.input.pointer.PointerIcon getCrosshair();
+    method public androidx.compose.ui.input.pointer.PointerIcon getDefault();
+    method public androidx.compose.ui.input.pointer.PointerIcon getHand();
+    method public androidx.compose.ui.input.pointer.PointerIcon getText();
+    property public final androidx.compose.ui.input.pointer.PointerIcon Crosshair;
+    property public final androidx.compose.ui.input.pointer.PointerIcon Default;
+    property public final androidx.compose.ui.input.pointer.PointerIcon Hand;
+    property public final androidx.compose.ui.input.pointer.PointerIcon Text;
+  }
+
+  public final class PointerIconKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier pointerHoverIcon(androidx.compose.ui.Modifier, androidx.compose.ui.input.pointer.PointerIcon icon, optional boolean overrideDescendants);
+  }
+
+  public final class PointerIcon_androidKt {
+    method public static androidx.compose.ui.input.pointer.PointerIcon PointerIcon(android.view.PointerIcon pointerIcon);
+    method public static androidx.compose.ui.input.pointer.PointerIcon PointerIcon(int pointerIconType);
+  }
+
+  @kotlin.jvm.JvmInline public final value class PointerId {
+    ctor public PointerId(long value);
+    method public long getValue();
+    property public final long value;
+  }
+
+  @androidx.compose.runtime.Immutable public final class PointerInputChange {
+    ctor public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, float pressure, long previousUptimeMillis, long previousPosition, boolean previousPressed, boolean isInitiallyConsumed, optional int type, optional long scrollDelta);
+    ctor @Deprecated public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
+    ctor public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, boolean isInitiallyConsumed, optional int type, optional long scrollDelta);
+    method public void consume();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
+    method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
+    method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
+    method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type, optional long scrollDelta);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
+    method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
+    method @Deprecated public androidx.compose.ui.input.pointer.ConsumedData getConsumed();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> getHistorical();
+    method public long getId();
+    method public long getPosition();
+    method public boolean getPressed();
+    method public float getPressure();
+    method public long getPreviousPosition();
+    method public boolean getPreviousPressed();
+    method public long getPreviousUptimeMillis();
+    method public long getScrollDelta();
+    method public int getType();
+    method public long getUptimeMillis();
+    method public boolean isConsumed();
+    property @Deprecated public final androidx.compose.ui.input.pointer.ConsumedData consumed;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public final java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical;
+    property public final long id;
+    property public final boolean isConsumed;
+    property public final long position;
+    property public final boolean pressed;
+    property public final float pressure;
+    property public final long previousPosition;
+    property public final boolean previousPressed;
+    property public final long previousUptimeMillis;
+    property public final long scrollDelta;
+    property public final int type;
+    property public final long uptimeMillis;
+  }
+
+  public abstract class PointerInputFilter {
+    ctor public PointerInputFilter();
+    method public boolean getInterceptOutOfBoundsChildEvents();
+    method public boolean getShareWithSiblings();
+    method public final long getSize();
+    method public abstract void onCancel();
+    method public abstract void onPointerEvent(androidx.compose.ui.input.pointer.PointerEvent pointerEvent, androidx.compose.ui.input.pointer.PointerEventPass pass, long bounds);
+    property public boolean interceptOutOfBoundsChildEvents;
+    property public boolean shareWithSiblings;
+    property public final long size;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface PointerInputModifier extends androidx.compose.ui.Modifier.Element {
+    method public androidx.compose.ui.input.pointer.PointerInputFilter getPointerInputFilter();
+    property public abstract androidx.compose.ui.input.pointer.PointerInputFilter pointerInputFilter;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface PointerInputScope extends androidx.compose.ui.unit.Density {
+    method public suspend <R> Object? awaitPointerEventScope(kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.AwaitPointerEventScope,? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+    method public default long getExtendedTouchPadding();
+    method public default boolean getInterceptOutOfBoundsChildEvents();
+    method public long getSize();
+    method public androidx.compose.ui.platform.ViewConfiguration getViewConfiguration();
+    method public default void setInterceptOutOfBoundsChildEvents(boolean);
+    property public default long extendedTouchPadding;
+    property public default boolean interceptOutOfBoundsChildEvents;
+    property public abstract long size;
+    property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
+  }
+
+  public final class PointerInteropFilter_androidKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier motionEventSpy(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> watcher);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier pointerInteropFilter(androidx.compose.ui.Modifier, optional androidx.compose.ui.input.pointer.RequestDisallowInterceptTouchEvent? requestDisallowInterceptTouchEvent, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,java.lang.Boolean> onTouchEvent);
+  }
+
+  @kotlin.jvm.JvmInline public final value class PointerKeyboardModifiers {
+    ctor public PointerKeyboardModifiers(int packedValue);
+  }
+
+  @kotlin.jvm.JvmInline public final value class PointerType {
+    field public static final androidx.compose.ui.input.pointer.PointerType.Companion Companion;
+  }
+
+  public static final class PointerType.Companion {
+    method public int getEraser();
+    method public int getMouse();
+    method public int getStylus();
+    method public int getTouch();
+    method public int getUnknown();
+    property public final int Eraser;
+    property public final int Mouse;
+    property public final int Stylus;
+    property public final int Touch;
+    property public final int Unknown;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public final class RequestDisallowInterceptTouchEvent implements kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit> {
+    ctor public RequestDisallowInterceptTouchEvent();
+    method public void invoke(boolean disallowIntercept);
+  }
+
+  public final class SuspendingPointerInputFilterKt {
+    method public static androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode SuspendingPointerInputModifierNode(kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> pointerInputHandler);
+    method public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, Object![]? keys, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public sealed interface SuspendingPointerInputModifierNode extends androidx.compose.ui.node.PointerInputModifierNode {
+    method public kotlin.jvm.functions.Function2<androidx.compose.ui.input.pointer.PointerInputScope,kotlin.coroutines.Continuation<? super kotlin.Unit>,java.lang.Object> getPointerInputHandler();
+    method public void resetPointerInputHandler();
+    method public void setPointerInputHandler(kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?>);
+    property public abstract kotlin.jvm.functions.Function2<androidx.compose.ui.input.pointer.PointerInputScope,kotlin.coroutines.Continuation<? super kotlin.Unit>,java.lang.Object> pointerInputHandler;
+  }
+
+}
+
+package androidx.compose.ui.input.pointer.util {
+
+  public final class VelocityTracker {
+    ctor public VelocityTracker();
+    method public void addPosition(long timeMillis, long position);
+    method public long calculateVelocity();
+    method public void resetTracking();
+  }
+
+  public final class VelocityTracker1D {
+    ctor public VelocityTracker1D(boolean isDataDifferential);
+    method public void addDataPoint(long timeMillis, float dataPoint);
+    method public float calculateVelocity();
+    method public boolean isDataDifferential();
+    method public void resetTracking();
+    property public final boolean isDataDifferential;
+  }
+
+  public final class VelocityTrackerKt {
+    method public static void addPointerInputChange(androidx.compose.ui.input.pointer.util.VelocityTracker, androidx.compose.ui.input.pointer.PointerInputChange event);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getVelocityTrackerAddPointsFix();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setVelocityTrackerAddPointsFix(boolean);
+    property @androidx.compose.ui.ExperimentalComposeUiApi public static final boolean VelocityTrackerAddPointsFix;
+  }
+
+}
+
+package androidx.compose.ui.input.rotary {
+
+  public final class RotaryInputModifierKt {
+    method public static androidx.compose.ui.Modifier onPreRotaryScrollEvent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.rotary.RotaryScrollEvent,java.lang.Boolean> onPreRotaryScrollEvent);
+    method public static androidx.compose.ui.Modifier onRotaryScrollEvent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.rotary.RotaryScrollEvent,java.lang.Boolean> onRotaryScrollEvent);
+  }
+
+  public interface RotaryInputModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public boolean onPreRotaryScrollEvent(androidx.compose.ui.input.rotary.RotaryScrollEvent event);
+    method public boolean onRotaryScrollEvent(androidx.compose.ui.input.rotary.RotaryScrollEvent event);
+  }
+
+  public final class RotaryScrollEvent {
+    method public float getHorizontalScrollPixels();
+    method public long getUptimeMillis();
+    method public float getVerticalScrollPixels();
+    property public final float horizontalScrollPixels;
+    property public final long uptimeMillis;
+    property public final float verticalScrollPixels;
+  }
+
+}
+
+package androidx.compose.ui.layout {
+
+  @androidx.compose.runtime.Immutable public abstract sealed class AlignmentLine {
+    field public static final androidx.compose.ui.layout.AlignmentLine.Companion Companion;
+    field public static final int Unspecified = -2147483648; // 0x80000000
+  }
+
+  public static final class AlignmentLine.Companion {
+  }
+
+  public final class AlignmentLineKt {
+    method public static androidx.compose.ui.layout.HorizontalAlignmentLine getFirstBaseline();
+    method public static androidx.compose.ui.layout.HorizontalAlignmentLine getLastBaseline();
+    property public static final androidx.compose.ui.layout.HorizontalAlignmentLine FirstBaseline;
+    property public static final androidx.compose.ui.layout.HorizontalAlignmentLine LastBaseline;
+  }
+
+  public interface BeyondBoundsLayout {
+    method public <T> T? layout(int direction, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.BeyondBoundsLayout.BeyondBoundsScope,? extends T> block);
+  }
+
+  public static interface BeyondBoundsLayout.BeyondBoundsScope {
+    method public boolean getHasMoreContent();
+    property public abstract boolean hasMoreContent;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class BeyondBoundsLayout.LayoutDirection {
+    field public static final androidx.compose.ui.layout.BeyondBoundsLayout.LayoutDirection.Companion Companion;
+  }
+
+  public static final class BeyondBoundsLayout.LayoutDirection.Companion {
+    method public int getAbove();
+    method public int getAfter();
+    method public int getBefore();
+    method public int getBelow();
+    method public int getLeft();
+    method public int getRight();
+    property public final int Above;
+    property public final int After;
+    property public final int Before;
+    property public final int Below;
+    property public final int Left;
+    property public final int Right;
+  }
+
+  public final class BeyondBoundsLayoutKt {
+    method public static androidx.compose.ui.modifier.ProvidableModifierLocal<androidx.compose.ui.layout.BeyondBoundsLayout> getModifierLocalBeyondBoundsLayout();
+    property public static final androidx.compose.ui.modifier.ProvidableModifierLocal<androidx.compose.ui.layout.BeyondBoundsLayout> ModifierLocalBeyondBoundsLayout;
+  }
+
+  @androidx.compose.runtime.Stable public interface ContentScale {
+    method public long computeScaleFactor(long srcSize, long dstSize);
+    field public static final androidx.compose.ui.layout.ContentScale.Companion Companion;
+  }
+
+  public static final class ContentScale.Companion {
+    method public androidx.compose.ui.layout.ContentScale getCrop();
+    method public androidx.compose.ui.layout.ContentScale getFillBounds();
+    method public androidx.compose.ui.layout.ContentScale getFillHeight();
+    method public androidx.compose.ui.layout.ContentScale getFillWidth();
+    method public androidx.compose.ui.layout.ContentScale getFit();
+    method public androidx.compose.ui.layout.ContentScale getInside();
+    method public androidx.compose.ui.layout.FixedScale getNone();
+    property public final androidx.compose.ui.layout.ContentScale Crop;
+    property public final androidx.compose.ui.layout.ContentScale FillBounds;
+    property public final androidx.compose.ui.layout.ContentScale FillHeight;
+    property public final androidx.compose.ui.layout.ContentScale FillWidth;
+    property public final androidx.compose.ui.layout.ContentScale Fit;
+    property public final androidx.compose.ui.layout.ContentScale Inside;
+    property public final androidx.compose.ui.layout.FixedScale None;
+  }
+
+  @androidx.compose.runtime.Immutable public final class FixedScale implements androidx.compose.ui.layout.ContentScale {
+    ctor public FixedScale(float value);
+    method public float component1();
+    method public long computeScaleFactor(long srcSize, long dstSize);
+    method public androidx.compose.ui.layout.FixedScale copy(float value);
+    method public float getValue();
+    property public final float value;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface GraphicLayerInfo {
+    method public long getLayerId();
+    method public default long getOwnerViewId();
+    property public abstract long layerId;
+    property public default long ownerViewId;
+  }
+
+  public final class HorizontalAlignmentLine extends androidx.compose.ui.layout.AlignmentLine {
+    ctor public HorizontalAlignmentLine(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Integer> merger);
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface IntermediateMeasureScope extends androidx.compose.ui.layout.LookaheadScope kotlinx.coroutines.CoroutineScope androidx.compose.ui.layout.MeasureScope {
+    method public long getLookaheadSize();
+    property public abstract long lookaheadSize;
+  }
+
+  public interface IntrinsicMeasurable {
+    method public Object? getParentData();
+    method public int maxIntrinsicHeight(int width);
+    method public int maxIntrinsicWidth(int height);
+    method public int minIntrinsicHeight(int width);
+    method public int minIntrinsicWidth(int height);
+    property public abstract Object? parentData;
+  }
+
+  public interface IntrinsicMeasureScope extends androidx.compose.ui.unit.Density {
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead();
+    property @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead;
+    property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface LayoutCoordinates {
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public androidx.compose.ui.layout.LayoutCoordinates? getParentCoordinates();
+    method public androidx.compose.ui.layout.LayoutCoordinates? getParentLayoutCoordinates();
+    method public java.util.Set<androidx.compose.ui.layout.AlignmentLine> getProvidedAlignmentLines();
+    method public long getSize();
+    method public boolean isAttached();
+    method public androidx.compose.ui.geometry.Rect localBoundingBoxOf(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, optional boolean clipBounds);
+    method public long localPositionOf(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, long relativeToSource);
+    method public long localToRoot(long relativeToLocal);
+    method public long localToWindow(long relativeToLocal);
+    method public default void transformFrom(androidx.compose.ui.layout.LayoutCoordinates sourceCoordinates, float[] matrix);
+    method public long windowToLocal(long relativeToWindow);
+    property public abstract boolean isAttached;
+    property public abstract androidx.compose.ui.layout.LayoutCoordinates? parentCoordinates;
+    property public abstract androidx.compose.ui.layout.LayoutCoordinates? parentLayoutCoordinates;
+    property public abstract java.util.Set<androidx.compose.ui.layout.AlignmentLine> providedAlignmentLines;
+    property public abstract long size;
+  }
+
+  public final class LayoutCoordinatesKt {
+    method public static androidx.compose.ui.geometry.Rect boundsInParent(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static androidx.compose.ui.geometry.Rect boundsInRoot(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static androidx.compose.ui.geometry.Rect boundsInWindow(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static androidx.compose.ui.layout.LayoutCoordinates findRootCoordinates(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInParent(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInRoot(androidx.compose.ui.layout.LayoutCoordinates);
+    method public static long positionInWindow(androidx.compose.ui.layout.LayoutCoordinates);
+  }
+
+  public final class LayoutIdKt {
+    method public static Object? getLayoutId(androidx.compose.ui.layout.Measurable);
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier layoutId(androidx.compose.ui.Modifier, Object layoutId);
+  }
+
+  public interface LayoutIdParentData {
+    method public Object getLayoutId();
+    property public abstract Object layoutId;
+  }
+
+  public interface LayoutInfo {
+    method public androidx.compose.ui.layout.LayoutCoordinates getCoordinates();
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public int getHeight();
+    method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+    method public java.util.List<androidx.compose.ui.layout.ModifierInfo> getModifierInfo();
+    method public androidx.compose.ui.layout.LayoutInfo? getParentInfo();
+    method public int getSemanticsId();
+    method public androidx.compose.ui.platform.ViewConfiguration getViewConfiguration();
+    method public int getWidth();
+    method public boolean isAttached();
+    method public boolean isPlaced();
+    property public abstract androidx.compose.ui.layout.LayoutCoordinates coordinates;
+    property public abstract androidx.compose.ui.unit.Density density;
+    property public abstract int height;
+    property public abstract boolean isAttached;
+    property public abstract boolean isPlaced;
+    property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
+    property public abstract androidx.compose.ui.layout.LayoutInfo? parentInfo;
+    property public abstract int semanticsId;
+    property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
+    property public abstract int width;
+  }
+
+  public final class LayoutKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static inline void Layout(optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static inline void Layout(java.util.List<? extends kotlin.jvm.functions.Function0<kotlin.Unit>> contents, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MultiContentMeasurePolicy measurePolicy);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static inline void Layout(kotlin.jvm.functions.Function0<kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void MultiMeasureLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function0<kotlin.Unit> content, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface LayoutModifier extends androidx.compose.ui.Modifier.Element {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure(androidx.compose.ui.layout.MeasureScope, androidx.compose.ui.layout.Measurable measurable, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int height);
+  }
+
+  public final class LayoutModifierKt {
+    method public static androidx.compose.ui.Modifier layout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
+  }
+
+  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface LookaheadLayoutCoordinates extends androidx.compose.ui.layout.LayoutCoordinates {
+  }
+
+  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadLayoutScope {
+    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadScope {
+    method public androidx.compose.ui.layout.LayoutCoordinates getLookaheadScopeCoordinates(androidx.compose.ui.layout.Placeable.PlacementScope);
+    method @Deprecated public default androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.ui.layout.MeasureResult> measure);
+    method public default long localLookaheadPositionOf(androidx.compose.ui.layout.LayoutCoordinates, androidx.compose.ui.layout.LayoutCoordinates coordinates);
+    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
+    method public androidx.compose.ui.layout.LayoutCoordinates toLookaheadCoordinates(androidx.compose.ui.layout.LayoutCoordinates);
+  }
+
+  public final class LookaheadScopeKt {
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadLayout(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadScope(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntermediateMeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
+  }
+
+  public interface Measurable extends androidx.compose.ui.layout.IntrinsicMeasurable {
+    method public androidx.compose.ui.layout.Placeable measure(long constraints);
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public fun interface MeasurePolicy {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure(androidx.compose.ui.layout.MeasureScope, java.util.List<? extends androidx.compose.ui.layout.Measurable> measurables, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable> measurables, int height);
+  }
+
+  public interface MeasureResult {
+    method public java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> getAlignmentLines();
+    method public int getHeight();
+    method public int getWidth();
+    method public void placeChildren();
+    property public abstract java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> alignmentLines;
+    property public abstract int height;
+    property public abstract int width;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface MeasureScope extends androidx.compose.ui.layout.IntrinsicMeasureScope {
+    method public default androidx.compose.ui.layout.MeasureResult layout(int width, int height, optional java.util.Map<androidx.compose.ui.layout.AlignmentLine,java.lang.Integer> alignmentLines, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.Placeable.PlacementScope,kotlin.Unit> placementBlock);
+  }
+
+  public interface Measured {
+    method public operator int get(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public int getMeasuredHeight();
+    method public int getMeasuredWidth();
+    method public default Object? getParentData();
+    property public abstract int measuredHeight;
+    property public abstract int measuredWidth;
+    property public default Object? parentData;
+  }
+
+  public final class ModifierInfo {
+    ctor public ModifierInfo(androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.LayoutCoordinates coordinates, optional Object? extra);
+    method public androidx.compose.ui.layout.LayoutCoordinates getCoordinates();
+    method public Object? getExtra();
+    method public androidx.compose.ui.Modifier getModifier();
+    property public final androidx.compose.ui.layout.LayoutCoordinates coordinates;
+    property public final Object? extra;
+    property public final androidx.compose.ui.Modifier modifier;
+  }
+
+  @androidx.compose.runtime.Stable public fun interface MultiContentMeasurePolicy {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>> measurables, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>> measurables, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure(androidx.compose.ui.layout.MeasureScope, java.util.List<? extends java.util.List<? extends androidx.compose.ui.layout.Measurable>> measurables, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>> measurables, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, java.util.List<? extends java.util.List<? extends androidx.compose.ui.layout.IntrinsicMeasurable>> measurables, int height);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface OnGloballyPositionedModifier extends androidx.compose.ui.Modifier.Element {
+    method public void onGloballyPositioned(androidx.compose.ui.layout.LayoutCoordinates coordinates);
+  }
+
+  public final class OnGloballyPositionedModifierKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onGloballyPositioned(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,kotlin.Unit> onGloballyPositioned);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface OnPlacedModifier extends androidx.compose.ui.Modifier.Element {
+    method public void onPlaced(androidx.compose.ui.layout.LayoutCoordinates coordinates);
+  }
+
+  public final class OnPlacedModifierKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LayoutCoordinates,kotlin.Unit> onPlaced);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface OnRemeasuredModifier extends androidx.compose.ui.Modifier.Element {
+    method public void onRemeasured(long size);
+  }
+
+  public final class OnRemeasuredModifierKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier onSizeChanged(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.IntSize,kotlin.Unit> onSizeChanged);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ParentDataModifier extends androidx.compose.ui.Modifier.Element {
+    method public Object? modifyParentData(androidx.compose.ui.unit.Density, Object? parentData);
+  }
+
+  @androidx.compose.runtime.Stable public interface PinnableContainer {
+    method public androidx.compose.ui.layout.PinnableContainer.PinnedHandle pin();
+  }
+
+  public static fun interface PinnableContainer.PinnedHandle {
+    method public void release();
+  }
+
+  public final class PinnableContainerKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.layout.PinnableContainer> getLocalPinnableContainer();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.layout.PinnableContainer> LocalPinnableContainer;
+  }
+
+  public abstract class Placeable implements androidx.compose.ui.layout.Measured {
+    ctor public Placeable();
+    method protected final long getApparentToRealOffset();
+    method public final int getHeight();
+    method public int getMeasuredHeight();
+    method protected final long getMeasuredSize();
+    method public int getMeasuredWidth();
+    method protected final long getMeasurementConstraints();
+    method public final int getWidth();
+    method protected abstract void placeAt(long position, float zIndex, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit>? layerBlock);
+    method protected final void setMeasuredSize(long);
+    method protected final void setMeasurementConstraints(long);
+    property protected final long apparentToRealOffset;
+    property public final int height;
+    property public int measuredHeight;
+    property protected final long measuredSize;
+    property public int measuredWidth;
+    property protected final long measurementConstraints;
+    property public final int width;
+  }
+
+  public abstract static class Placeable.PlacementScope {
+    ctor public Placeable.PlacementScope();
+    method public androidx.compose.ui.layout.LayoutCoordinates? getCoordinates();
+    method protected abstract androidx.compose.ui.unit.LayoutDirection getParentLayoutDirection();
+    method protected abstract int getParentWidth();
+    method public final void place(androidx.compose.ui.layout.Placeable, int x, int y, optional float zIndex);
+    method public final void place(androidx.compose.ui.layout.Placeable, long position, optional float zIndex);
+    method public final void placeRelative(androidx.compose.ui.layout.Placeable, int x, int y, optional float zIndex);
+    method public final void placeRelative(androidx.compose.ui.layout.Placeable, long position, optional float zIndex);
+    method public final void placeRelativeWithLayer(androidx.compose.ui.layout.Placeable, int x, int y, optional float zIndex, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit> layerBlock);
+    method public final void placeRelativeWithLayer(androidx.compose.ui.layout.Placeable, long position, optional float zIndex, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit> layerBlock);
+    method public final void placeWithLayer(androidx.compose.ui.layout.Placeable, int x, int y, optional float zIndex, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit> layerBlock);
+    method public final void placeWithLayer(androidx.compose.ui.layout.Placeable, long position, optional float zIndex, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.GraphicsLayerScope,kotlin.Unit> layerBlock);
+    property public androidx.compose.ui.layout.LayoutCoordinates? coordinates;
+    property protected abstract androidx.compose.ui.unit.LayoutDirection parentLayoutDirection;
+    property protected abstract int parentWidth;
+  }
+
+  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi @kotlin.jvm.JvmDefaultWithCompatibility public interface RelocationModifier extends androidx.compose.ui.Modifier.Element {
+    method @Deprecated public androidx.compose.ui.geometry.Rect computeDestination(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.layout.LayoutCoordinates layoutCoordinates);
+    method @Deprecated public suspend Object? performRelocation(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.geometry.Rect destination, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class RelocationModifierKt {
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onRelocationRequest(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> onProvideDestination, kotlin.jvm.functions.Function3<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.geometry.Rect,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onPerformRelocation);
+  }
+
+  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class RelocationRequester {
+    ctor @Deprecated public RelocationRequester();
+    method @Deprecated public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class RelocationRequesterModifierKt {
+    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier relocationRequester(androidx.compose.ui.Modifier, Object relocationRequester);
+  }
+
+  public interface Remeasurement {
+    method public void forceRemeasure();
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface RemeasurementModifier extends androidx.compose.ui.Modifier.Element {
+    method public void onRemeasurementAvailable(androidx.compose.ui.layout.Remeasurement remeasurement);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class ScaleFactor {
+    method @androidx.compose.runtime.Stable public inline operator float component1();
+    method @androidx.compose.runtime.Stable public inline operator float component2();
+    method public long copy(optional float scaleX, optional float scaleY);
+    method @androidx.compose.runtime.Stable public operator long div(float operand);
+    method public float getScaleX();
+    method public float getScaleY();
+    method @androidx.compose.runtime.Stable public operator long times(float operand);
+    property @androidx.compose.runtime.Stable public final float scaleX;
+    property @androidx.compose.runtime.Stable public final float scaleY;
+    field public static final androidx.compose.ui.layout.ScaleFactor.Companion Companion;
+  }
+
+  public static final class ScaleFactor.Companion {
+    method public long getUnspecified();
+    property public final long Unspecified;
+  }
+
+  public final class ScaleFactorKt {
+    method @androidx.compose.runtime.Stable public static long ScaleFactor(float scaleX, float scaleY);
+    method @androidx.compose.runtime.Stable public static operator long div(long, long scaleFactor);
+    method public static inline boolean isSpecified(long);
+    method public static inline boolean isUnspecified(long);
+    method @androidx.compose.runtime.Stable public static long lerp(long start, long stop, float fraction);
+    method public static inline long takeOrElse(long, kotlin.jvm.functions.Function0<androidx.compose.ui.layout.ScaleFactor> block);
+    method @androidx.compose.runtime.Stable public static operator long times(long, long scaleFactor);
+    method @androidx.compose.runtime.Stable public static operator long times(long, long size);
+  }
+
+  public final class SubcomposeLayoutKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static void SubcomposeLayout(androidx.compose.ui.layout.SubcomposeLayoutState state, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
+    method @androidx.compose.runtime.Composable public static void SubcomposeLayout(optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.SubcomposeMeasureScope,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measurePolicy);
+    method public static androidx.compose.ui.layout.SubcomposeSlotReusePolicy SubcomposeSlotReusePolicy(int maxSlotsToRetainForReuse);
+  }
+
+  public final class SubcomposeLayoutState {
+    ctor public SubcomposeLayoutState();
+    ctor public SubcomposeLayoutState(androidx.compose.ui.layout.SubcomposeSlotReusePolicy slotReusePolicy);
+    ctor @Deprecated public SubcomposeLayoutState(int maxSlotsToRetainForReuse);
+    method public androidx.compose.ui.layout.SubcomposeLayoutState.PrecomposedSlotHandle precompose(Object? slotId, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public static interface SubcomposeLayoutState.PrecomposedSlotHandle {
+    method public void dispose();
+    method public default int getPlaceablesCount();
+    method public default void premeasure(int index, long constraints);
+    property public default int placeablesCount;
+  }
+
+  public interface SubcomposeMeasureScope extends androidx.compose.ui.layout.MeasureScope {
+    method public java.util.List<androidx.compose.ui.layout.Measurable> subcompose(Object? slotId, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public interface SubcomposeSlotReusePolicy {
+    method public boolean areCompatible(Object? slotId, Object? reusableSlotId);
+    method public void getSlotsToRetain(androidx.compose.ui.layout.SubcomposeSlotReusePolicy.SlotIdsSet slotIds);
+  }
+
+  public static final class SubcomposeSlotReusePolicy.SlotIdsSet implements java.util.Collection<java.lang.Object> kotlin.jvm.internal.markers.KMappedMarker {
+    method public void clear();
+    method public java.util.Iterator<java.lang.Object> iterator();
+    method public boolean remove(Object? slotId);
+    method public boolean removeAll(java.util.Collection<?> slotIds);
+    method public boolean removeAll(kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Boolean> predicate);
+    method public boolean retainAll(java.util.Collection<?> slotIds);
+    method public boolean retainAll(kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Boolean> predicate);
+  }
+
+  public final class TestModifierUpdaterKt {
+  }
+
+  public final class VerticalAlignmentLine extends androidx.compose.ui.layout.AlignmentLine {
+    ctor public VerticalAlignmentLine(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Integer> merger);
+  }
+
+}
+
+package androidx.compose.ui.modifier {
+
+  @androidx.compose.runtime.Stable public abstract sealed class ModifierLocal<T> {
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface ModifierLocalConsumer extends androidx.compose.ui.Modifier.Element {
+    method public void onModifierLocalsUpdated(androidx.compose.ui.modifier.ModifierLocalReadScope scope);
+  }
+
+  public final class ModifierLocalConsumerKt {
+    method @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier modifierLocalConsumer(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.modifier.ModifierLocalReadScope,kotlin.Unit> consumer);
+  }
+
+  public final class ModifierLocalKt {
+    method public static <T> androidx.compose.ui.modifier.ProvidableModifierLocal<T> modifierLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
+  }
+
+  public abstract sealed class ModifierLocalMap {
+  }
+
+  public interface ModifierLocalModifierNode extends androidx.compose.ui.modifier.ModifierLocalReadScope androidx.compose.ui.node.DelegatableNode {
+    method public default <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+    method public default androidx.compose.ui.modifier.ModifierLocalMap getProvidedValues();
+    method public default <T> void provide(androidx.compose.ui.modifier.ModifierLocal<T> key, T value);
+    property public default androidx.compose.ui.modifier.ModifierLocalMap providedValues;
+  }
+
+  public final class ModifierLocalModifierNodeKt {
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf();
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<?>... keys);
+    method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(androidx.compose.ui.modifier.ModifierLocal<T> key);
+    method public static androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<?>,?>... entries);
+    method public static <T> androidx.compose.ui.modifier.ModifierLocalMap modifierLocalMapOf(kotlin.Pair<? extends androidx.compose.ui.modifier.ModifierLocal<T>,? extends T> entry);
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface ModifierLocalProvider<T> extends androidx.compose.ui.Modifier.Element {
+    method public androidx.compose.ui.modifier.ProvidableModifierLocal<T> getKey();
+    method public T getValue();
+    property public abstract androidx.compose.ui.modifier.ProvidableModifierLocal<T> key;
+    property public abstract T value;
+  }
+
+  public final class ModifierLocalProviderKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static <T> androidx.compose.ui.Modifier modifierLocalProvider(androidx.compose.ui.Modifier, androidx.compose.ui.modifier.ProvidableModifierLocal<T> key, kotlin.jvm.functions.Function0<? extends T> value);
+  }
+
+  public interface ModifierLocalReadScope {
+    method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
+  }
+
+  @androidx.compose.runtime.Stable public final class ProvidableModifierLocal<T> extends androidx.compose.ui.modifier.ModifierLocal<T> {
+    ctor public ProvidableModifierLocal(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
+  }
+
+}
+
+package androidx.compose.ui.node {
+
+  public interface CacheDrawModifierNode extends androidx.compose.ui.node.DrawModifierNode {
+    method public void invalidateDrawCache();
+  }
+
+  public interface CompositionLocalConsumerModifierNode extends androidx.compose.ui.node.DelegatableNode {
+  }
+
+  public final class CompositionLocalConsumerModifierNodeKt {
+    method public static <T> T currentValueOf(androidx.compose.ui.node.CompositionLocalConsumerModifierNode, androidx.compose.runtime.CompositionLocal<T> local);
+  }
+
+  public interface DelegatableNode {
+    method public androidx.compose.ui.Modifier.Node getNode();
+    property public abstract androidx.compose.ui.Modifier.Node node;
+  }
+
+  public final class DelegatableNodeKt {
+    method public static void invalidateSubtree(androidx.compose.ui.node.DelegatableNode);
+    method public static androidx.compose.ui.unit.Density requireDensity(androidx.compose.ui.node.DelegatableNode);
+    method public static androidx.compose.ui.unit.LayoutDirection requireLayoutDirection(androidx.compose.ui.node.DelegatableNode);
+  }
+
+  public abstract class DelegatingNode extends androidx.compose.ui.Modifier.Node {
+    ctor public DelegatingNode();
+    method protected final <T extends androidx.compose.ui.node.DelegatableNode> T delegate(T delegatableNode);
+    method protected final void undelegate(androidx.compose.ui.node.DelegatableNode instance);
+  }
+
+  public interface DrawModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void draw(androidx.compose.ui.graphics.drawscope.ContentDrawScope);
+    method public default void onMeasureResultChanged();
+  }
+
+  public final class DrawModifierNodeKt {
+    method public static void invalidateDraw(androidx.compose.ui.node.DrawModifierNode);
+  }
+
+  public interface GlobalPositionAwareModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void onGloballyPositioned(androidx.compose.ui.layout.LayoutCoordinates coordinates);
+  }
+
+  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalCoreApi {
+  }
+
+  @androidx.compose.ui.InternalComposeUiApi public sealed interface InteroperableComposeUiNode {
+    method public android.view.View? getInteropView();
+  }
+
+  public interface LayoutAwareModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public default void onPlaced(androidx.compose.ui.layout.LayoutCoordinates coordinates);
+    method public default void onRemeasured(long size);
+  }
+
+  public interface LayoutModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public default int maxIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int width);
+    method public default int maxIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int height);
+    method public androidx.compose.ui.layout.MeasureResult measure(androidx.compose.ui.layout.MeasureScope, androidx.compose.ui.layout.Measurable measurable, long constraints);
+    method public default int minIntrinsicHeight(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int width);
+    method public default int minIntrinsicWidth(androidx.compose.ui.layout.IntrinsicMeasureScope, androidx.compose.ui.layout.IntrinsicMeasurable measurable, int height);
+  }
+
+  public final class LayoutModifierNodeKt {
+    method public static void invalidateLayer(androidx.compose.ui.node.LayoutModifierNode);
+    method public static void invalidateMeasurement(androidx.compose.ui.node.LayoutModifierNode);
+    method public static void invalidatePlacement(androidx.compose.ui.node.LayoutModifierNode);
+    method public static void remeasureSync(androidx.compose.ui.node.LayoutModifierNode);
+  }
+
+  public abstract class ModifierNodeElement<N extends androidx.compose.ui.Modifier.Node> implements androidx.compose.ui.platform.InspectableValue androidx.compose.ui.Modifier.Element {
+    ctor public ModifierNodeElement();
+    method public abstract N create();
+    method public abstract boolean equals(Object? other);
+    method public final kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> getInspectableElements();
+    method public final String? getNameFallback();
+    method public final Object? getValueOverride();
+    method public abstract int hashCode();
+    method public void inspectableProperties(androidx.compose.ui.platform.InspectorInfo);
+    method public abstract void update(N node);
+    property public final kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> inspectableElements;
+    property public final String? nameFallback;
+    property public final Object? valueOverride;
+  }
+
+  public interface ObserverModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void onObservedReadsChanged();
+  }
+
+  public final class ObserverModifierNodeKt {
+    method public static <T extends androidx.compose.ui.Modifier.Node & androidx.compose.ui.node.ObserverModifierNode> void observeReads(T, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+  }
+
+  public interface ParentDataModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public Object? modifyParentData(androidx.compose.ui.unit.Density, Object? parentData);
+  }
+
+  public final class ParentDataModifierNodeKt {
+    method public static void invalidateParentData(androidx.compose.ui.node.ParentDataModifierNode);
+  }
+
+  public interface PointerInputModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public default boolean interceptOutOfBoundsChildEvents();
+    method public void onCancelPointerInput();
+    method public default void onDensityChange();
+    method public void onPointerEvent(androidx.compose.ui.input.pointer.PointerEvent pointerEvent, androidx.compose.ui.input.pointer.PointerEventPass pass, long bounds);
+    method public default void onViewConfigurationChange();
+    method public default boolean sharePointerInputWithSiblings();
+  }
+
+  public final class Ref<T> {
+    ctor public Ref();
+    method public T? getValue();
+    method public void setValue(T?);
+    property public final T? value;
+  }
+
+  public interface RootForTest {
+    method public androidx.compose.ui.unit.Density getDensity();
+    method public androidx.compose.ui.semantics.SemanticsOwner getSemanticsOwner();
+    method public androidx.compose.ui.text.input.TextInputService getTextInputService();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default void measureAndLayoutForTest();
+    method public boolean sendKeyEvent(android.view.KeyEvent keyEvent);
+    property public abstract androidx.compose.ui.unit.Density density;
+    property public abstract androidx.compose.ui.semantics.SemanticsOwner semanticsOwner;
+    property public abstract androidx.compose.ui.text.input.TextInputService textInputService;
+  }
+
+  public interface SemanticsModifierNode extends androidx.compose.ui.node.DelegatableNode {
+    method public void applySemantics(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public default boolean getShouldClearDescendantSemantics();
+    method public default boolean getShouldMergeDescendantSemantics();
+    property public default boolean shouldClearDescendantSemantics;
+    property public default boolean shouldMergeDescendantSemantics;
+  }
+
+  public final class SemanticsModifierNodeKt {
+    method public static void invalidateSemantics(androidx.compose.ui.node.SemanticsModifierNode);
+  }
+
+}
+
+package androidx.compose.ui.platform {
+
+  public abstract class AbstractComposeView extends android.view.ViewGroup {
+    ctor public AbstractComposeView(android.content.Context context);
+    ctor public AbstractComposeView(android.content.Context context, optional android.util.AttributeSet? attrs);
+    ctor public AbstractComposeView(android.content.Context context, optional android.util.AttributeSet? attrs, optional int defStyleAttr);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public abstract void Content();
+    method public final void createComposition();
+    method public final void disposeComposition();
+    method public final boolean getHasComposition();
+    method protected boolean getShouldCreateCompositionOnAttachedToWindow();
+    method public final boolean getShowLayoutBounds();
+    method protected final void onLayout(boolean changed, int left, int top, int right, int bottom);
+    method protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
+    method public final void setParentCompositionContext(androidx.compose.runtime.CompositionContext? parent);
+    method public final void setShowLayoutBounds(boolean);
+    method public final void setViewCompositionStrategy(androidx.compose.ui.platform.ViewCompositionStrategy strategy);
+    property public final boolean hasComposition;
+    property protected boolean shouldCreateCompositionOnAttachedToWindow;
+    property public final boolean showLayoutBounds;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface AccessibilityManager {
+    method public long calculateRecommendedTimeoutMillis(long originalTimeoutMillis, optional boolean containsIcons, optional boolean containsText, optional boolean containsControls);
+  }
+
+  public final class AndroidCompositionLocals_androidKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.res.Configuration> getLocalConfiguration();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> getLocalContext();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.lifecycle.LifecycleOwner> getLocalLifecycleOwner();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.savedstate.SavedStateRegistryOwner> getLocalSavedStateRegistryOwner();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<android.view.View> getLocalView();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.content.res.Configuration> LocalConfiguration;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.content.Context> LocalContext;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.lifecycle.LifecycleOwner> LocalLifecycleOwner;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.savedstate.SavedStateRegistryOwner> LocalSavedStateRegistryOwner;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<android.view.View> LocalView;
+  }
+
+  public final class AndroidUiDispatcher extends kotlinx.coroutines.CoroutineDispatcher {
+    method public void dispatch(kotlin.coroutines.CoroutineContext context, Runnable block);
+    method public android.view.Choreographer getChoreographer();
+    method public androidx.compose.runtime.MonotonicFrameClock getFrameClock();
+    property public final android.view.Choreographer choreographer;
+    property public final androidx.compose.runtime.MonotonicFrameClock frameClock;
+    field public static final androidx.compose.ui.platform.AndroidUiDispatcher.Companion Companion;
+  }
+
+  public static final class AndroidUiDispatcher.Companion {
+    method public kotlin.coroutines.CoroutineContext getCurrentThread();
+    method public kotlin.coroutines.CoroutineContext getMain();
+    property public final kotlin.coroutines.CoroutineContext CurrentThread;
+    property public final kotlin.coroutines.CoroutineContext Main;
+  }
+
+  public final class AndroidUiFrameClock implements androidx.compose.runtime.MonotonicFrameClock {
+    ctor public AndroidUiFrameClock(android.view.Choreographer choreographer);
+    method public android.view.Choreographer getChoreographer();
+    method public suspend <R> Object? withFrameNanos(kotlin.jvm.functions.Function1<? super java.lang.Long,? extends R> onFrame, kotlin.coroutines.Continuation<? super R>);
+    property public final android.view.Choreographer choreographer;
+  }
+
+  public final class AndroidUriHandler implements androidx.compose.ui.platform.UriHandler {
+    ctor public AndroidUriHandler(android.content.Context context);
+    method public void openUri(String uri);
+  }
+
+  public final class AndroidViewConfiguration implements androidx.compose.ui.platform.ViewConfiguration {
+    ctor public AndroidViewConfiguration(android.view.ViewConfiguration viewConfiguration);
+    method public long getDoubleTapMinTimeMillis();
+    method public long getDoubleTapTimeoutMillis();
+    method public long getLongPressTimeoutMillis();
+    method public float getTouchSlop();
+    property public long doubleTapMinTimeMillis;
+    property public long doubleTapTimeoutMillis;
+    property public long longPressTimeoutMillis;
+    property public float touchSlop;
+  }
+
+  public interface ClipboardManager {
+    method public androidx.compose.ui.text.AnnotatedString? getText();
+    method public default boolean hasText();
+    method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
+  }
+
+  public final class ComposeView extends androidx.compose.ui.platform.AbstractComposeView {
+    ctor public ComposeView(android.content.Context context);
+    ctor public ComposeView(android.content.Context context, optional android.util.AttributeSet? attrs);
+    ctor public ComposeView(android.content.Context context, optional android.util.AttributeSet? attrs, optional int defStyleAttr);
+    method @androidx.compose.runtime.Composable public void Content();
+    method public void setContent(kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    property protected boolean shouldCreateCompositionOnAttachedToWindow;
+  }
+
+  public final class CompositionLocalsKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> getLocalDensity();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> getLocalFocusManager();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> getLocalFontFamilyResolver();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> getLocalHapticFeedback();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> getLocalInputModeManager();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> getLocalLayoutDirection();
+    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> getLocalPlatformTextInputPluginRegistry();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> getLocalTextInputService();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> getLocalTextToolbar();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> getLocalUriHandler();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ViewConfiguration> getLocalViewConfiguration();
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.WindowInfo> getLocalWindowInfo();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> LocalAccessibilityManager;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> LocalAutofill;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> LocalAutofillTree;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> LocalClipboardManager;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> LocalDensity;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> LocalFocusManager;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.font.FontFamily.Resolver> LocalFontFamilyResolver;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> LocalHapticFeedback;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> LocalInputModeManager;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> LocalLayoutDirection;
+    property @androidx.compose.ui.text.ExperimentalTextApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> LocalPlatformTextInputPluginRegistry;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> LocalTextInputService;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> LocalTextToolbar;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> LocalUriHandler;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ViewConfiguration> LocalViewConfiguration;
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.WindowInfo> LocalWindowInfo;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface InfiniteAnimationPolicy extends kotlin.coroutines.CoroutineContext.Element {
+    method public default kotlin.coroutines.CoroutineContext.Key<?> getKey();
+    method public suspend <R> Object? onInfiniteOperation(kotlin.jvm.functions.Function1<? super kotlin.coroutines.Continuation<? super R>,?> block, kotlin.coroutines.Continuation<? super R>);
+    property public default kotlin.coroutines.CoroutineContext.Key<?> key;
+    field public static final androidx.compose.ui.platform.InfiniteAnimationPolicy.Key Key;
+  }
+
+  public static final class InfiniteAnimationPolicy.Key implements kotlin.coroutines.CoroutineContext.Key<androidx.compose.ui.platform.InfiniteAnimationPolicy> {
+  }
+
+  public final class InspectableModifier extends androidx.compose.ui.platform.InspectorValueInfo implements androidx.compose.ui.Modifier.Element {
+    ctor public InspectableModifier(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo);
+    method public androidx.compose.ui.platform.InspectableModifier.End getEnd();
+    property public final androidx.compose.ui.platform.InspectableModifier.End end;
+  }
+
+  public final class InspectableModifier.End implements androidx.compose.ui.Modifier.Element {
+    ctor public InspectableModifier.End();
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface InspectableValue {
+    method public default kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> getInspectableElements();
+    method public default String? getNameFallback();
+    method public default Object? getValueOverride();
+    property public default kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> inspectableElements;
+    property public default String? nameFallback;
+    property public default Object? valueOverride;
+  }
+
+  public final class InspectableValueKt {
+    method public static inline kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> debugInspectorInfo(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> definitions);
+    method public static kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> getNoInspectorInfo();
+    method public static inline androidx.compose.ui.Modifier inspectable(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
+    method public static boolean isDebugInspectorInfoEnabled();
+    method public static void setDebugInspectorInfoEnabled(boolean);
+    property public static final kotlin.jvm.functions.Function1<androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> NoInspectorInfo;
+    property public static final boolean isDebugInspectorInfoEnabled;
+  }
+
+  public final class InspectionModeKt {
+    method public static androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> getLocalInspectionMode();
+    property public static final androidx.compose.runtime.ProvidableCompositionLocal<java.lang.Boolean> LocalInspectionMode;
+  }
+
+  public final class InspectorInfo {
+    ctor public InspectorInfo();
+    method public String? getName();
+    method public androidx.compose.ui.platform.ValueElementSequence getProperties();
+    method public Object? getValue();
+    method public void setName(String?);
+    method public void setValue(Object?);
+    property public final String? name;
+    property public final androidx.compose.ui.platform.ValueElementSequence properties;
+    property public final Object? value;
+  }
+
+  public abstract class InspectorValueInfo implements androidx.compose.ui.platform.InspectableValue {
+    ctor public InspectorValueInfo(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> info);
+    property public kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> inspectableElements;
+    property public String? nameFallback;
+    property public Object? valueOverride;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public final class LocalSoftwareKeyboardController {
+    method @androidx.compose.runtime.Composable public androidx.compose.ui.platform.SoftwareKeyboardController? getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.compose.ui.platform.SoftwareKeyboardController> provides(androidx.compose.ui.platform.SoftwareKeyboardController softwareKeyboardController);
+    property @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.platform.SoftwareKeyboardController? current;
+    field public static final androidx.compose.ui.platform.LocalSoftwareKeyboardController INSTANCE;
+  }
+
+  public final class NestedScrollInteropConnectionKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.input.nestedscroll.NestedScrollConnection rememberNestedScrollInteropConnection(optional android.view.View hostView);
+  }
+
+  @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftwareKeyboardController {
+    method public void hide();
+    method @Deprecated public default void hideSoftwareKeyboard();
+    method public void show();
+    method @Deprecated public default void showSoftwareKeyboard();
+  }
+
+  public final class TestTagKt {
+    method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier testTag(androidx.compose.ui.Modifier, String tag);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface TextToolbar {
+    method public androidx.compose.ui.platform.TextToolbarStatus getStatus();
+    method public void hide();
+    method public void showMenu(androidx.compose.ui.geometry.Rect rect, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onCopyRequested, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onPasteRequested, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onCutRequested, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onSelectAllRequested);
+    property public abstract androidx.compose.ui.platform.TextToolbarStatus status;
+  }
+
+  public enum TextToolbarStatus {
+    method public static androidx.compose.ui.platform.TextToolbarStatus valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.platform.TextToolbarStatus[] values();
+    enum_constant public static final androidx.compose.ui.platform.TextToolbarStatus Hidden;
+    enum_constant public static final androidx.compose.ui.platform.TextToolbarStatus Shown;
+  }
+
+  public interface UriHandler {
+    method public void openUri(String uri);
+  }
+
+  public final class ValueElement {
+    ctor public ValueElement(String name, Object? value);
+    method public String component1();
+    method public Object? component2();
+    method public androidx.compose.ui.platform.ValueElement copy(String name, Object? value);
+    method public String getName();
+    method public Object? getValue();
+    property public final String name;
+    property public final Object? value;
+  }
+
+  public final class ValueElementSequence implements kotlin.sequences.Sequence<androidx.compose.ui.platform.ValueElement> {
+    ctor public ValueElementSequence();
+    method public java.util.Iterator<androidx.compose.ui.platform.ValueElement> iterator();
+    method public operator void set(String name, Object? value);
+  }
+
+  public interface ViewCompositionStrategy {
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> installFor(androidx.compose.ui.platform.AbstractComposeView view);
+    field public static final androidx.compose.ui.platform.ViewCompositionStrategy.Companion Companion;
+  }
+
+  public static final class ViewCompositionStrategy.Companion {
+    method public androidx.compose.ui.platform.ViewCompositionStrategy getDefault();
+    property public final androidx.compose.ui.platform.ViewCompositionStrategy Default;
+  }
+
+  public static final class ViewCompositionStrategy.DisposeOnDetachedFromWindow implements androidx.compose.ui.platform.ViewCompositionStrategy {
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> installFor(androidx.compose.ui.platform.AbstractComposeView view);
+    field public static final androidx.compose.ui.platform.ViewCompositionStrategy.DisposeOnDetachedFromWindow INSTANCE;
+  }
+
+  public static final class ViewCompositionStrategy.DisposeOnDetachedFromWindowOrReleasedFromPool implements androidx.compose.ui.platform.ViewCompositionStrategy {
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> installFor(androidx.compose.ui.platform.AbstractComposeView view);
+    field public static final androidx.compose.ui.platform.ViewCompositionStrategy.DisposeOnDetachedFromWindowOrReleasedFromPool INSTANCE;
+  }
+
+  public static final class ViewCompositionStrategy.DisposeOnLifecycleDestroyed implements androidx.compose.ui.platform.ViewCompositionStrategy {
+    ctor public ViewCompositionStrategy.DisposeOnLifecycleDestroyed(androidx.lifecycle.Lifecycle lifecycle);
+    ctor public ViewCompositionStrategy.DisposeOnLifecycleDestroyed(androidx.lifecycle.LifecycleOwner lifecycleOwner);
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> installFor(androidx.compose.ui.platform.AbstractComposeView view);
+  }
+
+  public static final class ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed implements androidx.compose.ui.platform.ViewCompositionStrategy {
+    method public kotlin.jvm.functions.Function0<kotlin.Unit> installFor(androidx.compose.ui.platform.AbstractComposeView view);
+    field public static final androidx.compose.ui.platform.ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed INSTANCE;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ViewConfiguration {
+    method public long getDoubleTapMinTimeMillis();
+    method public long getDoubleTapTimeoutMillis();
+    method public long getLongPressTimeoutMillis();
+    method public default long getMinimumTouchTargetSize();
+    method public float getTouchSlop();
+    property public abstract long doubleTapMinTimeMillis;
+    property public abstract long doubleTapTimeoutMillis;
+    property public abstract long longPressTimeoutMillis;
+    property public default long minimumTouchTargetSize;
+    property public abstract float touchSlop;
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface ViewRootForInspector {
+    method public default androidx.compose.ui.platform.AbstractComposeView? getSubCompositionView();
+    method public default android.view.View? getViewRoot();
+    property public default androidx.compose.ui.platform.AbstractComposeView? subCompositionView;
+    property public default android.view.View? viewRoot;
+  }
+
+  @VisibleForTesting public interface ViewRootForTest extends androidx.compose.ui.node.RootForTest {
+    method public boolean getHasPendingMeasureOrLayout();
+    method public android.view.View getView();
+    method public void invalidateDescendants();
+    method public boolean isLifecycleInResumedState();
+    property public abstract boolean hasPendingMeasureOrLayout;
+    property public abstract boolean isLifecycleInResumedState;
+    property public abstract android.view.View view;
+    field public static final androidx.compose.ui.platform.ViewRootForTest.Companion Companion;
+  }
+
+  public static final class ViewRootForTest.Companion {
+    method public kotlin.jvm.functions.Function1<androidx.compose.ui.platform.ViewRootForTest,kotlin.Unit>? getOnViewCreatedCallback();
+    method public void setOnViewCreatedCallback(kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.ViewRootForTest,kotlin.Unit>?);
+    property public final kotlin.jvm.functions.Function1<androidx.compose.ui.platform.ViewRootForTest,kotlin.Unit>? onViewCreatedCallback;
+  }
+
+  @androidx.compose.runtime.Stable public interface WindowInfo {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public default int getKeyboardModifiers();
+    method public boolean isWindowFocused();
+    property public abstract boolean isWindowFocused;
+    property @androidx.compose.ui.ExperimentalComposeUiApi public default int keyboardModifiers;
+  }
+
+  @androidx.compose.ui.InternalComposeUiApi public fun interface WindowRecomposerFactory {
+    method public androidx.compose.runtime.Recomposer createRecomposer(android.view.View windowRootView);
+    field public static final androidx.compose.ui.platform.WindowRecomposerFactory.Companion Companion;
+  }
+
+  public static final class WindowRecomposerFactory.Companion {
+    method public androidx.compose.ui.platform.WindowRecomposerFactory getLifecycleAware();
+    property public final androidx.compose.ui.platform.WindowRecomposerFactory LifecycleAware;
+  }
+
+  @androidx.compose.ui.InternalComposeUiApi public final class WindowRecomposerPolicy {
+    method public void setFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory);
+    method public inline <R> R withFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory, kotlin.jvm.functions.Function0<? extends R> block);
+    field public static final androidx.compose.ui.platform.WindowRecomposerPolicy INSTANCE;
+  }
+
+  public final class WindowRecomposer_androidKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.Recomposer createLifecycleAwareWindowRecomposer(android.view.View, optional kotlin.coroutines.CoroutineContext coroutineContext, optional androidx.lifecycle.Lifecycle? lifecycle);
+    method public static androidx.compose.runtime.CompositionContext? findViewTreeCompositionContext(android.view.View);
+    method public static androidx.compose.runtime.CompositionContext? getCompositionContext(android.view.View);
+    method public static void setCompositionContext(android.view.View, androidx.compose.runtime.CompositionContext?);
+  }
+
+}
+
+package androidx.compose.ui.res {
+
+  public final class ColorResources_androidKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static long colorResource(@ColorRes int id);
+  }
+
+  public final class FontResources_androidKt {
+    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static androidx.compose.ui.text.font.Typeface fontResource(androidx.compose.ui.text.font.FontFamily fontFamily);
+  }
+
+  public final class ImageResources_androidKt {
+    method public static androidx.compose.ui.graphics.ImageBitmap imageResource(androidx.compose.ui.graphics.ImageBitmap.Companion, android.content.res.Resources res, @DrawableRes int id);
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.ImageBitmap imageResource(androidx.compose.ui.graphics.ImageBitmap.Companion, @DrawableRes int id);
+  }
+
+  public final class PainterResources_androidKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.painter.Painter painterResource(@DrawableRes int id);
+  }
+
+  public final class PrimitiveResources_androidKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static boolean booleanResource(@BoolRes int id);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static float dimensionResource(@DimenRes int id);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static int[] integerArrayResource(@ArrayRes int id);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static int integerResource(@IntegerRes int id);
+  }
+
+  public final class StringResources_androidKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static String pluralStringResource(@PluralsRes int id, int count);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static String pluralStringResource(@PluralsRes int id, int count, java.lang.Object... formatArgs);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static String![] stringArrayResource(@ArrayRes int id);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static String stringResource(@StringRes int id);
+    method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public static String stringResource(@StringRes int id, java.lang.Object... formatArgs);
+  }
+
+  public final class VectorResources_androidKt {
+    method @kotlin.jvm.Throws(exceptionClasses=XmlPullParserException::class) public static androidx.compose.ui.graphics.vector.ImageVector vectorResource(androidx.compose.ui.graphics.vector.ImageVector.Companion, optional android.content.res.Resources.Theme? theme, android.content.res.Resources res, int resId) throws org.xmlpull.v1.XmlPullParserException;
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.graphics.vector.ImageVector vectorResource(androidx.compose.ui.graphics.vector.ImageVector.Companion, @DrawableRes int id);
+  }
+
+}
+
+package androidx.compose.ui.semantics {
+
+  public final class AccessibilityAction<T extends kotlin.Function<? extends java.lang.Boolean>> {
+    ctor public AccessibilityAction(String? label, T? action);
+    method public T? getAction();
+    method public String? getLabel();
+    property public final T? action;
+    property public final String? label;
+  }
+
+  public final class CollectionInfo {
+    ctor public CollectionInfo(int rowCount, int columnCount);
+    method public int getColumnCount();
+    method public int getRowCount();
+    property public final int columnCount;
+    property public final int rowCount;
+  }
+
+  public final class CollectionItemInfo {
+    ctor public CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan);
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    property public final int columnIndex;
+    property public final int columnSpan;
+    property public final int rowIndex;
+    property public final int rowSpan;
+  }
+
+  public final class CustomAccessibilityAction {
+    ctor public CustomAccessibilityAction(String label, kotlin.jvm.functions.Function0<java.lang.Boolean> action);
+    method public kotlin.jvm.functions.Function0<java.lang.Boolean> getAction();
+    method public String getLabel();
+    property public final kotlin.jvm.functions.Function0<java.lang.Boolean> action;
+    property public final String label;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class LiveRegionMode {
+    field public static final androidx.compose.ui.semantics.LiveRegionMode.Companion Companion;
+  }
+
+  public static final class LiveRegionMode.Companion {
+    method public int getAssertive();
+    method public int getPolite();
+    property public final int Assertive;
+    property public final int Polite;
+  }
+
+  public final class ProgressBarRangeInfo {
+    ctor public ProgressBarRangeInfo(float current, kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> range, optional int steps);
+    method public float getCurrent();
+    method public kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> getRange();
+    method public int getSteps();
+    property public final float current;
+    property public final kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> range;
+    property public final int steps;
+    field public static final androidx.compose.ui.semantics.ProgressBarRangeInfo.Companion Companion;
+  }
+
+  public static final class ProgressBarRangeInfo.Companion {
+    method public androidx.compose.ui.semantics.ProgressBarRangeInfo getIndeterminate();
+    property public final androidx.compose.ui.semantics.ProgressBarRangeInfo Indeterminate;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class Role {
+    field public static final androidx.compose.ui.semantics.Role.Companion Companion;
+  }
+
+  public static final class Role.Companion {
+    method public int getButton();
+    method public int getCheckbox();
+    method public int getDropdownList();
+    method public int getImage();
+    method public int getRadioButton();
+    method public int getSwitch();
+    method public int getTab();
+    property public final int Button;
+    property public final int Checkbox;
+    property public final int DropdownList;
+    property public final int Image;
+    property public final int RadioButton;
+    property public final int Switch;
+    property public final int Tab;
+  }
+
+  public final class ScrollAxisRange {
+    ctor public ScrollAxisRange(kotlin.jvm.functions.Function0<java.lang.Float> value, kotlin.jvm.functions.Function0<java.lang.Float> maxValue, optional boolean reverseScrolling);
+    method public kotlin.jvm.functions.Function0<java.lang.Float> getMaxValue();
+    method public boolean getReverseScrolling();
+    method public kotlin.jvm.functions.Function0<java.lang.Float> getValue();
+    property public final kotlin.jvm.functions.Function0<java.lang.Float> maxValue;
+    property public final boolean reverseScrolling;
+    property public final kotlin.jvm.functions.Function0<java.lang.Float> value;
+  }
+
+  public final class SemanticsActions {
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getCollapse();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getCopyText();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction>> getCustomActions();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getCutText();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getDismiss();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getExpand();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.util.List<androidx.compose.ui.text.TextLayoutResult>,java.lang.Boolean>>> getGetTextLayoutResult();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>>> getInsertTextAtCursor();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getOnClick();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getOnLongClick();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPageDown();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPageLeft();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPageRight();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPageUp();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPasteText();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getPerformImeAction();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> getRequestFocus();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function2<java.lang.Float,java.lang.Float,java.lang.Boolean>>> getScrollBy();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Boolean>>> getScrollToIndex();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Boolean>>> getSetProgress();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function3<java.lang.Integer,java.lang.Integer,java.lang.Boolean,java.lang.Boolean>>> getSetSelection();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>>> getSetText();
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> Collapse;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> CopyText;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction>> CustomActions;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> CutText;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> Dismiss;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> Expand;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.util.List<androidx.compose.ui.text.TextLayoutResult>,java.lang.Boolean>>> GetTextLayoutResult;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>>> InsertTextAtCursor;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> OnClick;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> OnLongClick;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PageDown;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PageLeft;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PageRight;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PageUp;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PasteText;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> PerformImeAction;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function0<java.lang.Boolean>>> RequestFocus;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function2<java.lang.Float,java.lang.Float,java.lang.Boolean>>> ScrollBy;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Boolean>>> ScrollToIndex;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<java.lang.Float,java.lang.Boolean>>> SetProgress;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function3<java.lang.Integer,java.lang.Integer,java.lang.Boolean,java.lang.Boolean>>> SetSelection;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.AccessibilityAction<kotlin.jvm.functions.Function1<androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>>> SetText;
+    field public static final androidx.compose.ui.semantics.SemanticsActions INSTANCE;
+  }
+
+  public final class SemanticsConfiguration implements java.lang.Iterable<java.util.Map.Entry<? extends androidx.compose.ui.semantics.SemanticsPropertyKey<?>,?>> kotlin.jvm.internal.markers.KMappedMarker androidx.compose.ui.semantics.SemanticsPropertyReceiver {
+    ctor public SemanticsConfiguration();
+    method public operator <T> boolean contains(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+    method public androidx.compose.ui.semantics.SemanticsConfiguration copy();
+    method public operator <T> T get(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+    method public <T> T getOrElse(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public <T> T? getOrElseNullable(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, kotlin.jvm.functions.Function0<? extends T> defaultValue);
+    method public boolean isClearingSemantics();
+    method public boolean isMergingSemanticsOfDescendants();
+    method public java.util.Iterator<java.util.Map.Entry<androidx.compose.ui.semantics.SemanticsPropertyKey<?>,java.lang.Object>> iterator();
+    method public <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
+    method public void setClearingSemantics(boolean);
+    method public void setMergingSemanticsOfDescendants(boolean);
+    property public final boolean isClearingSemantics;
+    property public final boolean isMergingSemanticsOfDescendants;
+  }
+
+  public final class SemanticsConfigurationKt {
+    method public static <T> T? getOrNull(androidx.compose.ui.semantics.SemanticsConfiguration, androidx.compose.ui.semantics.SemanticsPropertyKey<T> key);
+  }
+
+  @kotlin.jvm.JvmDefaultWithCompatibility public interface SemanticsModifier extends androidx.compose.ui.Modifier.Element {
+    method @Deprecated public default int getId();
+    method public androidx.compose.ui.semantics.SemanticsConfiguration getSemanticsConfiguration();
+    property @Deprecated public default int id;
+    property public abstract androidx.compose.ui.semantics.SemanticsConfiguration semanticsConfiguration;
+  }
+
+  public final class SemanticsModifierKt {
+    method public static androidx.compose.ui.Modifier clearAndSetSemantics(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit> properties);
+    method public static androidx.compose.ui.Modifier semantics(androidx.compose.ui.Modifier, optional boolean mergeDescendants, kotlin.jvm.functions.Function1<? super androidx.compose.ui.semantics.SemanticsPropertyReceiver,kotlin.Unit> properties);
+  }
+
+  public final class SemanticsNode {
+    method public int getAlignmentLinePosition(androidx.compose.ui.layout.AlignmentLine alignmentLine);
+    method public androidx.compose.ui.geometry.Rect getBoundsInRoot();
+    method public androidx.compose.ui.geometry.Rect getBoundsInWindow();
+    method public java.util.List<androidx.compose.ui.semantics.SemanticsNode> getChildren();
+    method public androidx.compose.ui.semantics.SemanticsConfiguration getConfig();
+    method public int getId();
+    method public androidx.compose.ui.layout.LayoutInfo getLayoutInfo();
+    method public boolean getMergingEnabled();
+    method public androidx.compose.ui.semantics.SemanticsNode? getParent();
+    method public long getPositionInRoot();
+    method public long getPositionInWindow();
+    method public androidx.compose.ui.node.RootForTest? getRoot();
+    method public long getSize();
+    method public androidx.compose.ui.geometry.Rect getTouchBoundsInRoot();
+    method public boolean isRoot();
+    property public final androidx.compose.ui.geometry.Rect boundsInRoot;
+    property public final androidx.compose.ui.geometry.Rect boundsInWindow;
+    property public final java.util.List<androidx.compose.ui.semantics.SemanticsNode> children;
+    property public final androidx.compose.ui.semantics.SemanticsConfiguration config;
+    property public final int id;
+    property public final boolean isRoot;
+    property public final androidx.compose.ui.layout.LayoutInfo layoutInfo;
+    property public final boolean mergingEnabled;
+    property public final androidx.compose.ui.semantics.SemanticsNode? parent;
+    property public final long positionInRoot;
+    property public final long positionInWindow;
+    property public final androidx.compose.ui.node.RootForTest? root;
+    property public final long size;
+    property public final androidx.compose.ui.geometry.Rect touchBoundsInRoot;
+  }
+
+  public final class SemanticsOwner {
+    method public androidx.compose.ui.semantics.SemanticsNode getRootSemanticsNode();
+    method public androidx.compose.ui.semantics.SemanticsNode getUnmergedRootSemanticsNode();
+    property public final androidx.compose.ui.semantics.SemanticsNode rootSemanticsNode;
+    property public final androidx.compose.ui.semantics.SemanticsNode unmergedRootSemanticsNode;
+  }
+
+  public final class SemanticsOwnerKt {
+    method public static java.util.List<androidx.compose.ui.semantics.SemanticsNode> getAllSemanticsNodes(androidx.compose.ui.semantics.SemanticsOwner, boolean mergingEnabled);
+  }
+
+  public final class SemanticsProperties {
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.CollectionInfo> getCollectionInfo();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.CollectionItemInfo> getCollectionItemInfo();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> getContentDescription();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getDisabled();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.AnnotatedString> getEditableText();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getError();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getFocused();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getHeading();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ScrollAxisRange> getHorizontalScrollAxisRange();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.input.ImeAction> getImeAction();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Integer>> getIndexForKey();
+    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> getIsPopup();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getIsTraversalGroup();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.LiveRegionMode> getLiveRegion();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getPaneTitle();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getPassword();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> getProgressBarRangeInfo();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> getRole();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> getSelectableGroup();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getSelected();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getStateDescription();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> getTestTag();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.compose.ui.text.AnnotatedString>> getText();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.TextRange> getTextSelectionRange();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.state.ToggleableState> getToggleableState();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Float> getTraversalIndex();
+    method public androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ScrollAxisRange> getVerticalScrollAxisRange();
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.CollectionInfo> CollectionInfo;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.CollectionItemInfo> CollectionItemInfo;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<java.lang.String>> ContentDescription;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Disabled;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.AnnotatedString> EditableText;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> Error;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Focused;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Heading;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ScrollAxisRange> HorizontalScrollAxisRange;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.input.ImeAction> ImeAction;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Integer>> IndexForKey;
+    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> IsPopup;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> IsTraversalGroup;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.LiveRegionMode> LiveRegion;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> PaneTitle;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> Password;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ProgressBarRangeInfo> ProgressBarRangeInfo;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.Role> Role;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<kotlin.Unit> SelectableGroup;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> Selected;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> StateDescription;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.String> TestTag;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.util.List<androidx.compose.ui.text.AnnotatedString>> Text;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.text.TextRange> TextSelectionRange;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.state.ToggleableState> ToggleableState;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Float> TraversalIndex;
+    property public final androidx.compose.ui.semantics.SemanticsPropertyKey<androidx.compose.ui.semantics.ScrollAxisRange> VerticalScrollAxisRange;
+    field public static final androidx.compose.ui.semantics.SemanticsProperties INSTANCE;
+  }
+
+  @androidx.compose.ui.ExperimentalComposeUiApi public final class SemanticsPropertiesAndroid {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getTestTagsAsResourceId();
+    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> TestTagsAsResourceId;
+    field public static final androidx.compose.ui.semantics.SemanticsPropertiesAndroid INSTANCE;
+  }
+
+  public final class SemanticsPropertiesKt {
+    method public static void collapse(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void copyText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void cutText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void dialog(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void disabled(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void dismiss(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void error(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String description);
+    method public static void expand(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static androidx.compose.ui.semantics.CollectionInfo getCollectionInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.semantics.CollectionItemInfo getCollectionItemInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getContentDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction> getCustomActions(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.text.AnnotatedString getEditableText(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getFocused(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.semantics.ScrollAxisRange getHorizontalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method @Deprecated public static int getImeAction(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static int getLiveRegion(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getPaneTitle(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.semantics.ProgressBarRangeInfo getProgressBarRangeInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static int getRole(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static boolean getSelected(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getStateDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static String getTestTag(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.text.AnnotatedString getText(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void getTextLayoutResult(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super java.util.List<androidx.compose.ui.text.TextLayoutResult>,java.lang.Boolean>? action);
+    method public static long getTextSelectionRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.state.ToggleableState getToggleableState(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static float getTraversalIndex(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static androidx.compose.ui.semantics.ScrollAxisRange getVerticalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void heading(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void indexForKey(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Integer> mapping);
+    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 @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 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);
+    method public static void onLongClick(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void pageDown(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void pageLeft(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void pageRight(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void pageUp(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void password(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void pasteText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void performImeAction(androidx.compose.ui.semantics.SemanticsPropertyReceiver, int imeActionType, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void popup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void requestFocus(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
+    method public static void scrollBy(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function2<? super java.lang.Float,? super java.lang.Float,java.lang.Boolean>? action);
+    method public static void scrollToIndex(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super java.lang.Integer,java.lang.Boolean> action);
+    method public static void selectableGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method public static void setCollectionInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.CollectionInfo);
+    method public static void setCollectionItemInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.CollectionItemInfo);
+    method @Deprecated public static void setContainer(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
+    method public static void setContentDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String);
+    method public static void setCustomActions(androidx.compose.ui.semantics.SemanticsPropertyReceiver, java.util.List<androidx.compose.ui.semantics.CustomAccessibilityAction>);
+    method public static void setEditableText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.text.AnnotatedString);
+    method public static void setFocused(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
+    method public static void setHorizontalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.ScrollAxisRange);
+    method @Deprecated public static void setImeAction(androidx.compose.ui.semantics.SemanticsPropertyReceiver, int);
+    method public static void setLiveRegion(androidx.compose.ui.semantics.SemanticsPropertyReceiver, int);
+    method public static void setPaneTitle(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String);
+    method public static void setProgress(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super java.lang.Float,java.lang.Boolean>? action);
+    method public static void setProgressBarRangeInfo(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.ProgressBarRangeInfo);
+    method public static void setRole(androidx.compose.ui.semantics.SemanticsPropertyReceiver, int);
+    method public static void setSelected(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
+    method public static void setSelection(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function3<? super java.lang.Integer,? super java.lang.Integer,? super java.lang.Boolean,java.lang.Boolean>? action);
+    method public static void setStateDescription(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String);
+    method public static void setTestTag(androidx.compose.ui.semantics.SemanticsPropertyReceiver, String);
+    method public static void setText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.text.AnnotatedString);
+    method public static void setText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function1<? super androidx.compose.ui.text.AnnotatedString,java.lang.Boolean>? action);
+    method public static void setTextSelectionRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver, long);
+    method public static void setToggleableState(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.state.ToggleableState);
+    method public static void setTraversalGroup(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
+    method public static void setTraversalIndex(androidx.compose.ui.semantics.SemanticsPropertyReceiver, float);
+    method public static void setVerticalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.ScrollAxisRange);
+  }
+
+  public final class SemanticsProperties_androidKt {
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
+    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
+  }
+
+  public final class SemanticsPropertyKey<T> {
+    ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
+    method public String getName();
+    method public operator T getValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property);
+    method public T? merge(T? parentValue, T childValue);
+    method public operator void setValue(androidx.compose.ui.semantics.SemanticsPropertyReceiver thisRef, kotlin.reflect.KProperty<?> property, T value);
+    property public final String name;
+  }
+
+  public interface SemanticsPropertyReceiver {
+    method public operator <T> void set(androidx.compose.ui.semantics.SemanticsPropertyKey<T> key, T value);
+  }
+
+}
+
+package androidx.compose.ui.state {
+
+  public enum ToggleableState {
+    method public static androidx.compose.ui.state.ToggleableState valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.state.ToggleableState[] values();
+    enum_constant public static final androidx.compose.ui.state.ToggleableState Indeterminate;
+    enum_constant public static final androidx.compose.ui.state.ToggleableState Off;
+    enum_constant public static final androidx.compose.ui.state.ToggleableState On;
+  }
+
+  public final class ToggleableStateKt {
+    method public static androidx.compose.ui.state.ToggleableState ToggleableState(boolean value);
+  }
+
+}
+
+package androidx.compose.ui.text {
+
+  public final class TextMeasurerHelperKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.ui.text.TextMeasurer rememberTextMeasurer(optional int cacheSize);
+  }
+
+}
+
+package androidx.compose.ui.viewinterop {
+
+  public final class AndroidView_androidKt {
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method @androidx.compose.runtime.Composable @androidx.compose.ui.UiComposable public static <T extends android.view.View> void AndroidView(kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> factory, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit>? onReset, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onRelease, optional kotlin.jvm.functions.Function1<? super T,kotlin.Unit> update);
+    method public static kotlin.jvm.functions.Function1<android.view.View,kotlin.Unit> getNoOpUpdate();
+    property public static final kotlin.jvm.functions.Function1<android.view.View,kotlin.Unit> NoOpUpdate;
+  }
+
+}
+
+package androidx.compose.ui.window {
+
+  public final class AndroidDialog_androidKt {
+    method @androidx.compose.runtime.Composable public static void Dialog(kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.window.DialogProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class AndroidPopup_androidKt {
+    method @androidx.compose.runtime.Composable public static void Popup(optional androidx.compose.ui.Alignment alignment, optional long offset, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDismissRequest, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Popup(androidx.compose.ui.window.PopupPositionProvider popupPositionProvider, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onDismissRequest, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @org.jetbrains.annotations.TestOnly public static boolean isPopupLayout(android.view.View view, optional String? testTag);
+  }
+
+  @androidx.compose.runtime.Immutable public final class DialogProperties {
+    ctor public DialogProperties(optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy);
+    ctor public DialogProperties(optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean usePlatformDefaultWidth, optional boolean decorFitsSystemWindows);
+    method public boolean getDecorFitsSystemWindows();
+    method public boolean getDismissOnBackPress();
+    method public boolean getDismissOnClickOutside();
+    method public androidx.compose.ui.window.SecureFlagPolicy getSecurePolicy();
+    method public boolean getUsePlatformDefaultWidth();
+    property public final boolean decorFitsSystemWindows;
+    property public final boolean dismissOnBackPress;
+    property public final boolean dismissOnClickOutside;
+    property public final androidx.compose.ui.window.SecureFlagPolicy securePolicy;
+    property public final boolean usePlatformDefaultWidth;
+  }
+
+  public interface DialogWindowProvider {
+    method public android.view.Window getWindow();
+    property public abstract android.view.Window window;
+  }
+
+  @androidx.compose.runtime.Immutable public interface PopupPositionProvider {
+    method public long calculatePosition(androidx.compose.ui.unit.IntRect anchorBounds, long windowSize, androidx.compose.ui.unit.LayoutDirection layoutDirection, long popupContentSize);
+  }
+
+  @androidx.compose.runtime.Immutable public final class PopupProperties {
+    ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled);
+    ctor @androidx.compose.ui.ExperimentalComposeUiApi public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled, optional boolean usePlatformDefaultWidth);
+    method public boolean getClippingEnabled();
+    method public boolean getDismissOnBackPress();
+    method public boolean getDismissOnClickOutside();
+    method public boolean getExcludeFromSystemGesture();
+    method public boolean getFocusable();
+    method public androidx.compose.ui.window.SecureFlagPolicy getSecurePolicy();
+    method public boolean getUsePlatformDefaultWidth();
+    property public final boolean clippingEnabled;
+    property public final boolean dismissOnBackPress;
+    property public final boolean dismissOnClickOutside;
+    property public final boolean excludeFromSystemGesture;
+    property public final boolean focusable;
+    property public final androidx.compose.ui.window.SecureFlagPolicy securePolicy;
+    property public final boolean usePlatformDefaultWidth;
+  }
+
+  public enum SecureFlagPolicy {
+    method public static androidx.compose.ui.window.SecureFlagPolicy valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.compose.ui.window.SecureFlagPolicy[] values();
+    enum_constant public static final androidx.compose.ui.window.SecureFlagPolicy Inherit;
+    enum_constant public static final androidx.compose.ui.window.SecureFlagPolicy SecureOff;
+    enum_constant public static final androidx.compose.ui.window.SecureFlagPolicy SecureOn;
+  }
+
+}
+
diff --git a/compose/ui/ui/api/restricted_1.5.0-beta01.txt b/compose/ui/ui/api/restricted_1.5.0-beta01.txt
index d24ac94..c75c01f 100644
--- a/compose/ui/ui/api/restricted_1.5.0-beta01.txt
+++ b/compose/ui/ui/api/restricted_1.5.0-beta01.txt
@@ -112,21 +112,11 @@
   }
 
   public final class ComposedModifierKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, Object? key3, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, Object? key2, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object? key1, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, String fullyQualifiedName, Object![]? keys, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method public static androidx.compose.ui.Modifier composed(androidx.compose.ui.Modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.platform.InspectorInfo,kotlin.Unit> inspectorInfo, kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier,? extends androidx.compose.ui.Modifier> factory);
     method @Deprecated public static androidx.compose.ui.Modifier materialize(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
     method public static androidx.compose.ui.Modifier materializeModifier(androidx.compose.runtime.Composer, androidx.compose.ui.Modifier modifier);
   }
 
-  @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalComposeUiApi {
-  }
-
-  @kotlin.RequiresOptIn(message="Unstable API for use only between compose-ui modules sharing the same exact version, " + "subject to change without notice in major, minor, or patch releases.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface InternalComposeUiApi {
-  }
-
   @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public interface Modifier {
     method public boolean all(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
     method public boolean any(kotlin.jvm.functions.Function1<? super androidx.compose.ui.Modifier.Element,java.lang.Boolean> predicate);
@@ -159,7 +149,6 @@
     method public void onAttach();
     method public void onDetach();
     method public void onReset();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public final void sideEffect(kotlin.jvm.functions.Function0<kotlin.Unit> effect);
     property public final kotlinx.coroutines.CoroutineScope coroutineScope;
     property public final boolean isAttached;
     property public final androidx.compose.ui.Modifier.Node node;
@@ -186,77 +175,6 @@
 
 }
 
-package androidx.compose.ui.autofill {
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface Autofill {
-    method public void cancelAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
-    method public void requestAutofillForNode(androidx.compose.ui.autofill.AutofillNode autofillNode);
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillNode {
-    ctor public AutofillNode(optional java.util.List<? extends androidx.compose.ui.autofill.AutofillType> autofillTypes, optional androidx.compose.ui.geometry.Rect? boundingBox, kotlin.jvm.functions.Function1<? super java.lang.String,kotlin.Unit>? onFill);
-    method public java.util.List<androidx.compose.ui.autofill.AutofillType> getAutofillTypes();
-    method public androidx.compose.ui.geometry.Rect? getBoundingBox();
-    method public int getId();
-    method public kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? getOnFill();
-    method public void setBoundingBox(androidx.compose.ui.geometry.Rect?);
-    property public final java.util.List<androidx.compose.ui.autofill.AutofillType> autofillTypes;
-    property public final androidx.compose.ui.geometry.Rect? boundingBox;
-    property public final int id;
-    property public final kotlin.jvm.functions.Function1<java.lang.String,kotlin.Unit>? onFill;
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class AutofillTree {
-    ctor public AutofillTree();
-    method public java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> getChildren();
-    method public kotlin.Unit? performAutofill(int id, String value);
-    method public operator void plusAssign(androidx.compose.ui.autofill.AutofillNode autofillNode);
-    property public final java.util.Map<java.lang.Integer,androidx.compose.ui.autofill.AutofillNode> children;
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public enum AutofillType {
-    method public static androidx.compose.ui.autofill.AutofillType valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
-    method public static androidx.compose.ui.autofill.AutofillType[] values();
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressAuxiliaryDetails;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressCountry;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressLocality;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressRegion;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType AddressStreet;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateDay;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateFull;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateMonth;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType BirthDateYear;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDate;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationDay;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationMonth;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardExpirationYear;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardNumber;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType CreditCardSecurityCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType EmailAddress;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Gender;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewPassword;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType NewUsername;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Password;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFirstName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonFullName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonLastName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleInitial;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonMiddleName;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNamePrefix;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PersonNameSuffix;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneCountryCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumber;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberDevice;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PhoneNumberNational;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalAddress;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType PostalCodeExtended;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType SmsOtpCode;
-    enum_constant public static final androidx.compose.ui.autofill.AutofillType Username;
-  }
-
-}
-
 package androidx.compose.ui.draw {
 
   public final class AlphaKt {
@@ -359,22 +277,14 @@
 
   public static final class FocusDirection.Companion {
     method public int getDown();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public int getEnter();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public int getExit();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getIn();
     method public int getLeft();
     method public int getNext();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getOut();
     method public int getPrevious();
     method public int getRight();
     method public int getUp();
     property public final int Down;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Enter;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final int Exit;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int In;
     property public final int Left;
     property public final int Next;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Out;
     property public final int Previous;
     property public final int Right;
     property public final int Up;
@@ -444,8 +354,6 @@
     method public boolean getCanFocus();
     method public default androidx.compose.ui.focus.FocusRequester getDown();
     method public default androidx.compose.ui.focus.FocusRequester getEnd();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getEnter();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> getExit();
     method public default androidx.compose.ui.focus.FocusRequester getLeft();
     method public default androidx.compose.ui.focus.FocusRequester getNext();
     method public default androidx.compose.ui.focus.FocusRequester getPrevious();
@@ -455,8 +363,6 @@
     method public void setCanFocus(boolean);
     method public default void setDown(androidx.compose.ui.focus.FocusRequester);
     method public default void setEnd(androidx.compose.ui.focus.FocusRequester);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setEnter(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void setExit(kotlin.jvm.functions.Function1<? super androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester>);
     method public default void setLeft(androidx.compose.ui.focus.FocusRequester);
     method public default void setNext(androidx.compose.ui.focus.FocusRequester);
     method public default void setPrevious(androidx.compose.ui.focus.FocusRequester);
@@ -466,8 +372,6 @@
     property public abstract boolean canFocus;
     property public default androidx.compose.ui.focus.FocusRequester down;
     property public default androidx.compose.ui.focus.FocusRequester end;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> enter;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default kotlin.jvm.functions.Function1<androidx.compose.ui.focus.FocusDirection,androidx.compose.ui.focus.FocusRequester> exit;
     property public default androidx.compose.ui.focus.FocusRequester left;
     property public default androidx.compose.ui.focus.FocusRequester next;
     property public default androidx.compose.ui.focus.FocusRequester previous;
@@ -497,33 +401,10 @@
   }
 
   public static final class FocusRequester.Companion {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory createRefs();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.focus.FocusRequester getCancel();
     method public androidx.compose.ui.focus.FocusRequester getDefault();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.focus.FocusRequester Cancel;
     property public final androidx.compose.ui.focus.FocusRequester Default;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public static final class FocusRequester.Companion.FocusRequesterFactory {
-    method public operator androidx.compose.ui.focus.FocusRequester component1();
-    method public operator androidx.compose.ui.focus.FocusRequester component10();
-    method public operator androidx.compose.ui.focus.FocusRequester component11();
-    method public operator androidx.compose.ui.focus.FocusRequester component12();
-    method public operator androidx.compose.ui.focus.FocusRequester component13();
-    method public operator androidx.compose.ui.focus.FocusRequester component14();
-    method public operator androidx.compose.ui.focus.FocusRequester component15();
-    method public operator androidx.compose.ui.focus.FocusRequester component16();
-    method public operator androidx.compose.ui.focus.FocusRequester component2();
-    method public operator androidx.compose.ui.focus.FocusRequester component3();
-    method public operator androidx.compose.ui.focus.FocusRequester component4();
-    method public operator androidx.compose.ui.focus.FocusRequester component5();
-    method public operator androidx.compose.ui.focus.FocusRequester component6();
-    method public operator androidx.compose.ui.focus.FocusRequester component7();
-    method public operator androidx.compose.ui.focus.FocusRequester component8();
-    method public operator androidx.compose.ui.focus.FocusRequester component9();
-    field public static final androidx.compose.ui.focus.FocusRequester.Companion.FocusRequesterFactory INSTANCE;
-  }
-
   @Deprecated @kotlin.jvm.JvmDefaultWithCompatibility public interface FocusRequesterModifier extends androidx.compose.ui.Modifier.Element {
     method @Deprecated public androidx.compose.ui.focus.FocusRequester getFocusRequester();
     property @Deprecated public abstract androidx.compose.ui.focus.FocusRequester focusRequester;
@@ -945,7 +826,6 @@
 
   public interface InputModeManager {
     method public int getInputMode();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public boolean requestInputMode(int inputMode);
     property public abstract int inputMode;
   }
 
@@ -1581,16 +1461,6 @@
     method public static int getNativeKeyCode(long);
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftKeyboardInterceptionModifierNode extends androidx.compose.ui.node.DelegatableNode {
-    method public boolean onInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
-    method public boolean onPreInterceptKeyBeforeSoftKeyboard(android.view.KeyEvent event);
-  }
-
-  public final class SoftwareKeyboardInterceptionModifierKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onInterceptKeyBeforeSoftKeyboard);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onPreInterceptKeyBeforeSoftKeyboard(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.input.key.KeyEvent,java.lang.Boolean> onPreInterceptKeyBeforeSoftKeyboard);
-  }
-
 }
 
 package androidx.compose.ui.input.nestedscroll {
@@ -1627,10 +1497,8 @@
   public static final class NestedScrollSource.Companion {
     method public int getDrag();
     method public int getFling();
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public int getRelocate();
     property public final int Drag;
     property public final int Fling;
-    property @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final int Relocate;
   }
 
 }
@@ -1661,14 +1529,6 @@
     property @Deprecated public final boolean positionChange;
   }
 
-  @androidx.compose.runtime.Immutable @androidx.compose.ui.ExperimentalComposeUiApi public final class HistoricalChange {
-    ctor public HistoricalChange(long uptimeMillis, long position);
-    method public long getPosition();
-    method public long getUptimeMillis();
-    property public final long position;
-    property public final long uptimeMillis;
-  }
-
   @kotlin.jvm.JvmInline public final value class PointerButtons {
     ctor public PointerButtons(int packedValue);
   }
@@ -1798,14 +1658,11 @@
     ctor @Deprecated public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
     ctor public PointerInputChange(long id, long uptimeMillis, long position, boolean pressed, long previousUptimeMillis, long previousPosition, boolean previousPressed, boolean isInitiallyConsumed, optional int type, optional long scrollDelta);
     method public void consume();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
     method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional float pressure, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
     method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type);
     method @Deprecated public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, androidx.compose.ui.input.pointer.ConsumedData consumed, optional int type, optional long scrollDelta);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical, optional long scrollDelta);
     method public androidx.compose.ui.input.pointer.PointerInputChange copy(optional long id, optional long currentTime, optional long currentPosition, optional boolean currentPressed, optional long previousTime, optional long previousPosition, optional boolean previousPressed, optional int type, optional long scrollDelta);
     method @Deprecated public androidx.compose.ui.input.pointer.ConsumedData getConsumed();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> getHistorical();
     method public long getId();
     method public long getPosition();
     method public boolean getPressed();
@@ -1818,7 +1675,6 @@
     method public long getUptimeMillis();
     method public boolean isConsumed();
     property @Deprecated public final androidx.compose.ui.input.pointer.ConsumedData consumed;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final java.util.List<androidx.compose.ui.input.pointer.HistoricalChange> historical;
     property public final long id;
     property public final boolean isConsumed;
     property public final long position;
@@ -1862,11 +1718,6 @@
     property public abstract androidx.compose.ui.platform.ViewConfiguration viewConfiguration;
   }
 
-  public final class PointerInteropFilter_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier motionEventSpy(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,kotlin.Unit> watcher);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier pointerInteropFilter(androidx.compose.ui.Modifier, optional androidx.compose.ui.input.pointer.RequestDisallowInterceptTouchEvent? requestDisallowInterceptTouchEvent, kotlin.jvm.functions.Function1<? super android.view.MotionEvent,java.lang.Boolean> onTouchEvent);
-  }
-
   @kotlin.jvm.JvmInline public final value class PointerKeyboardModifiers {
     ctor public PointerKeyboardModifiers(int packedValue);
   }
@@ -1888,11 +1739,6 @@
     property public final int Unknown;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class RequestDisallowInterceptTouchEvent implements kotlin.jvm.functions.Function1<java.lang.Boolean,kotlin.Unit> {
-    ctor public RequestDisallowInterceptTouchEvent();
-    method public void invoke(boolean disallowIntercept);
-  }
-
   public final class SuspendingPointerInputFilterKt {
     method public static androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode SuspendingPointerInputModifierNode(kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> pointerInputHandler);
     method public static androidx.compose.ui.Modifier pointerInput(androidx.compose.ui.Modifier, Object? key1, Object? key2, kotlin.jvm.functions.Function2<? super androidx.compose.ui.input.pointer.PointerInputScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
@@ -1930,9 +1776,6 @@
 
   public final class VelocityTrackerKt {
     method public static void addPointerInputChange(androidx.compose.ui.input.pointer.util.VelocityTracker, androidx.compose.ui.input.pointer.PointerInputChange event);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getVelocityTrackerAddPointsFix();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setVelocityTrackerAddPointsFix(boolean);
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final boolean VelocityTrackerAddPointsFix;
   }
 
 }
@@ -2052,11 +1895,6 @@
     ctor public HorizontalAlignmentLine(kotlin.jvm.functions.Function2<? super java.lang.Integer,? super java.lang.Integer,java.lang.Integer> merger);
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface IntermediateMeasureScope extends androidx.compose.ui.layout.LookaheadScope kotlinx.coroutines.CoroutineScope androidx.compose.ui.layout.MeasureScope {
-    method public long getLookaheadSize();
-    property public abstract long lookaheadSize;
-  }
-
   public interface IntrinsicMeasurable {
     method public Object? getParentData();
     method public int maxIntrinsicHeight(int width);
@@ -2068,8 +1906,6 @@
 
   public interface IntrinsicMeasureScope extends androidx.compose.ui.unit.Density {
     method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead;
     property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
   }
 
@@ -2159,27 +1995,6 @@
     method public static androidx.compose.ui.Modifier layout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
   }
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public sealed interface LookaheadLayoutCoordinates extends androidx.compose.ui.layout.LayoutCoordinates {
-  }
-
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadLayoutScope {
-    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
-  }
-
-  @androidx.compose.ui.ExperimentalComposeUiApi public interface LookaheadScope {
-    method public androidx.compose.ui.layout.LayoutCoordinates getLookaheadScopeCoordinates(androidx.compose.ui.layout.Placeable.PlacementScope);
-    method @Deprecated public default androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function4<? super androidx.compose.ui.layout.MeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? super androidx.compose.ui.unit.IntSize,? extends androidx.compose.ui.layout.MeasureResult> measure);
-    method public default long localLookaheadPositionOf(androidx.compose.ui.layout.LayoutCoordinates, androidx.compose.ui.layout.LayoutCoordinates coordinates);
-    method @Deprecated public androidx.compose.ui.Modifier onPlaced(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,? super androidx.compose.ui.layout.LookaheadLayoutCoordinates,kotlin.Unit> onPlaced);
-    method public androidx.compose.ui.layout.LayoutCoordinates toLookaheadCoordinates(androidx.compose.ui.layout.LayoutCoordinates);
-  }
-
-  public final class LookaheadScopeKt {
-    method @Deprecated @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadLayout(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content, optional androidx.compose.ui.Modifier modifier, androidx.compose.ui.layout.MeasurePolicy measurePolicy);
-    method @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi @androidx.compose.ui.UiComposable public static void LookaheadScope(kotlin.jvm.functions.Function1<? super androidx.compose.ui.layout.LookaheadScope,kotlin.Unit> content);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier intermediateLayout(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function3<? super androidx.compose.ui.layout.IntermediateMeasureScope,? super androidx.compose.ui.layout.Measurable,? super androidx.compose.ui.unit.Constraints,? extends androidx.compose.ui.layout.MeasureResult> measure);
-  }
-
   public interface Measurable extends androidx.compose.ui.layout.IntrinsicMeasurable {
     method public androidx.compose.ui.layout.Placeable measure(long constraints);
   }
@@ -2318,24 +2133,6 @@
     property protected abstract int parentWidth;
   }
 
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi @kotlin.jvm.JvmDefaultWithCompatibility public interface RelocationModifier extends androidx.compose.ui.Modifier.Element {
-    method @Deprecated public androidx.compose.ui.geometry.Rect computeDestination(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.layout.LayoutCoordinates layoutCoordinates);
-    method @Deprecated public suspend Object? performRelocation(androidx.compose.ui.geometry.Rect source, androidx.compose.ui.geometry.Rect destination, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class RelocationModifierKt {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier onRelocationRequest(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function2<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.layout.LayoutCoordinates,androidx.compose.ui.geometry.Rect> onProvideDestination, kotlin.jvm.functions.Function3<? super androidx.compose.ui.geometry.Rect,? super androidx.compose.ui.geometry.Rect,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> onPerformRelocation);
-  }
-
-  @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public final class RelocationRequester {
-    ctor @Deprecated public RelocationRequester();
-    method @Deprecated public suspend Object? bringIntoView(optional androidx.compose.ui.geometry.Rect? rect, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
-  }
-
-  public final class RelocationRequesterModifierKt {
-    method @Deprecated @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier relocationRequester(androidx.compose.ui.Modifier, Object relocationRequester);
-  }
-
   public interface Remeasurement {
     method public void forceRemeasure();
   }
@@ -2427,10 +2224,6 @@
     method public void onModifierLocalsUpdated(androidx.compose.ui.modifier.ModifierLocalReadScope scope);
   }
 
-  public final class ModifierLocalConsumerKt {
-    method @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.ui.Modifier modifierLocalConsumer(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.modifier.ModifierLocalReadScope,kotlin.Unit> consumer);
-  }
-
   public final class ModifierLocalKt {
     method public static <T> androidx.compose.ui.modifier.ProvidableModifierLocal<T> modifierLocalOf(kotlin.jvm.functions.Function0<? extends T> defaultFactory);
   }
@@ -2460,10 +2253,6 @@
     property public abstract T value;
   }
 
-  public final class ModifierLocalProviderKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static <T> androidx.compose.ui.Modifier modifierLocalProvider(androidx.compose.ui.Modifier, androidx.compose.ui.modifier.ProvidableModifierLocal<T> key, kotlin.jvm.functions.Function0<? extends T> value);
-  }
-
   public interface ModifierLocalReadScope {
     method public <T> T getCurrent(androidx.compose.ui.modifier.ModifierLocal<T>);
   }
@@ -2558,13 +2347,6 @@
     method public void onGloballyPositioned(androidx.compose.ui.layout.LayoutCoordinates coordinates);
   }
 
-  @kotlin.RequiresOptIn(message="This API is internal to library.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.PROPERTY_GETTER, kotlin.annotation.AnnotationTarget.PROPERTY_SETTER}) public @interface InternalCoreApi {
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public sealed interface InteroperableComposeUiNode {
-    method public android.view.View? getInteropView();
-  }
-
   public interface LayoutAwareModifierNode extends androidx.compose.ui.node.DelegatableNode {
     method public default void onPlaced(androidx.compose.ui.layout.LayoutCoordinates coordinates);
     method public default void onRemeasured(long size);
@@ -2636,7 +2418,6 @@
     method public androidx.compose.ui.unit.Density getDensity();
     method public androidx.compose.ui.semantics.SemanticsOwner getSemanticsOwner();
     method public androidx.compose.ui.text.input.TextInputService getTextInputService();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default void measureAndLayoutForTest();
     method public boolean sendKeyEvent(android.view.KeyEvent keyEvent);
     property public abstract androidx.compose.ui.unit.Density density;
     property public abstract androidx.compose.ui.semantics.SemanticsOwner semanticsOwner;
@@ -2753,8 +2534,6 @@
 
   public final class CompositionLocalsKt {
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> getLocalAccessibilityManager();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> getLocalAutofill();
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> getLocalAutofillTree();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> getLocalClipboardManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> getLocalDensity();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> getLocalFocusManager();
@@ -2762,15 +2541,12 @@
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> getLocalHapticFeedback();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> getLocalInputModeManager();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> getLocalLayoutDirection();
-    method @androidx.compose.ui.text.ExperimentalTextApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> getLocalPlatformTextInputPluginRegistry();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> getLocalTextInputService();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> getLocalTextToolbar();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> getLocalUriHandler();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ViewConfiguration> getLocalViewConfiguration();
     method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.WindowInfo> getLocalWindowInfo();
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.AccessibilityManager> LocalAccessibilityManager;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.Autofill> LocalAutofill;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.autofill.AutofillTree> LocalAutofillTree;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.ClipboardManager> LocalClipboardManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Density> LocalDensity;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.focus.FocusManager> LocalFocusManager;
@@ -2778,7 +2554,6 @@
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.hapticfeedback.HapticFeedback> LocalHapticFeedback;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.input.InputModeManager> LocalInputModeManager;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.LayoutDirection> LocalLayoutDirection;
-    property @androidx.compose.ui.text.ExperimentalTextApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.PlatformTextInputPluginRegistry> LocalPlatformTextInputPluginRegistry;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.text.input.TextInputService> LocalTextInputService;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.TextToolbar> LocalTextToolbar;
     property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.platform.UriHandler> LocalUriHandler;
@@ -2850,24 +2625,10 @@
     property public Object? valueOverride;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class LocalSoftwareKeyboardController {
-    method @androidx.compose.runtime.Composable public androidx.compose.ui.platform.SoftwareKeyboardController? getCurrent();
-    method public infix androidx.compose.runtime.ProvidedValue<androidx.compose.ui.platform.SoftwareKeyboardController> provides(androidx.compose.ui.platform.SoftwareKeyboardController softwareKeyboardController);
-    property @androidx.compose.runtime.Composable @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.platform.SoftwareKeyboardController? current;
-    field public static final androidx.compose.ui.platform.LocalSoftwareKeyboardController INSTANCE;
-  }
-
   public final class NestedScrollInteropConnectionKt {
     method @androidx.compose.runtime.Composable public static androidx.compose.ui.input.nestedscroll.NestedScrollConnection rememberNestedScrollInteropConnection(optional android.view.View hostView);
   }
 
-  @androidx.compose.runtime.Stable @androidx.compose.ui.ExperimentalComposeUiApi public interface SoftwareKeyboardController {
-    method public void hide();
-    method @Deprecated public default void hideSoftwareKeyboard();
-    method public void show();
-    method @Deprecated public default void showSoftwareKeyboard();
-  }
-
   public final class TestTagKt {
     method @androidx.compose.runtime.Stable public static androidx.compose.ui.Modifier testTag(androidx.compose.ui.Modifier, String tag);
   }
@@ -2976,32 +2737,11 @@
   }
 
   @androidx.compose.runtime.Stable public interface WindowInfo {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public default int getKeyboardModifiers();
     method public boolean isWindowFocused();
     property public abstract boolean isWindowFocused;
-    property @androidx.compose.ui.ExperimentalComposeUiApi public default int keyboardModifiers;
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public fun interface WindowRecomposerFactory {
-    method public androidx.compose.runtime.Recomposer createRecomposer(android.view.View windowRootView);
-    field public static final androidx.compose.ui.platform.WindowRecomposerFactory.Companion Companion;
-  }
-
-  public static final class WindowRecomposerFactory.Companion {
-    method public androidx.compose.ui.platform.WindowRecomposerFactory getLifecycleAware();
-    property public final androidx.compose.ui.platform.WindowRecomposerFactory LifecycleAware;
-  }
-
-  @androidx.compose.ui.InternalComposeUiApi public final class WindowRecomposerPolicy {
-    method @kotlin.PublishedApi internal boolean compareAndSetFactory(androidx.compose.ui.platform.WindowRecomposerFactory expected, androidx.compose.ui.platform.WindowRecomposerFactory factory);
-    method @kotlin.PublishedApi internal androidx.compose.ui.platform.WindowRecomposerFactory getAndSetFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory);
-    method public void setFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory);
-    method public inline <R> R withFactory(androidx.compose.ui.platform.WindowRecomposerFactory factory, kotlin.jvm.functions.Function0<? extends R> block);
-    field public static final androidx.compose.ui.platform.WindowRecomposerPolicy INSTANCE;
   }
 
   public final class WindowRecomposer_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static androidx.compose.runtime.Recomposer createLifecycleAwareWindowRecomposer(android.view.View, optional kotlin.coroutines.CoroutineContext coroutineContext, optional androidx.lifecycle.Lifecycle? lifecycle);
     method public static androidx.compose.runtime.CompositionContext? findViewTreeCompositionContext(android.view.View);
     method public static androidx.compose.runtime.CompositionContext? getCompositionContext(android.view.View);
     method public static void setCompositionContext(android.view.View, androidx.compose.runtime.CompositionContext?);
@@ -3334,12 +3074,6 @@
     field public static final androidx.compose.ui.semantics.SemanticsProperties INSTANCE;
   }
 
-  @androidx.compose.ui.ExperimentalComposeUiApi public final class SemanticsPropertiesAndroid {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> getTestTagsAsResourceId();
-    property @androidx.compose.ui.ExperimentalComposeUiApi public final androidx.compose.ui.semantics.SemanticsPropertyKey<java.lang.Boolean> TestTagsAsResourceId;
-    field public static final androidx.compose.ui.semantics.SemanticsPropertiesAndroid INSTANCE;
-  }
-
   public final class SemanticsPropertiesKt {
     method public static void collapse(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
     method public static void copyText(androidx.compose.ui.semantics.SemanticsPropertyReceiver, optional String? label, kotlin.jvm.functions.Function0<java.lang.Boolean>? action);
@@ -3373,7 +3107,6 @@
     method public static void heading(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
     method public static void indexForKey(androidx.compose.ui.semantics.SemanticsPropertyReceiver, kotlin.jvm.functions.Function1<java.lang.Object,java.lang.Integer> mapping);
     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 @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 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);
@@ -3417,11 +3150,6 @@
     method public static void setVerticalScrollAxisRange(androidx.compose.ui.semantics.SemanticsPropertyReceiver, androidx.compose.ui.semantics.ScrollAxisRange);
   }
 
-  public final class SemanticsProperties_androidKt {
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static boolean getTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver);
-    method @androidx.compose.ui.ExperimentalComposeUiApi public static void setTestTagsAsResourceId(androidx.compose.ui.semantics.SemanticsPropertyReceiver, boolean);
-  }
-
   public final class SemanticsPropertyKey<T> {
     ctor public SemanticsPropertyKey(String name, optional kotlin.jvm.functions.Function2<? super T,? super T,? extends T> mergePolicy);
     method public String getName();
@@ -3510,7 +3238,6 @@
 
   @androidx.compose.runtime.Immutable public final class PopupProperties {
     ctor public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled);
-    ctor @androidx.compose.ui.ExperimentalComposeUiApi public PopupProperties(optional boolean focusable, optional boolean dismissOnBackPress, optional boolean dismissOnClickOutside, optional androidx.compose.ui.window.SecureFlagPolicy securePolicy, optional boolean excludeFromSystemGesture, optional boolean clippingEnabled, optional boolean usePlatformDefaultWidth);
     method public boolean getClippingEnabled();
     method public boolean getDismissOnBackPress();
     method public boolean getDismissOnClickOutside();
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 3ad4391..7622917 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 import static androidx.inspection.gradle.InspectionPluginKt.packageInspector
 
@@ -31,6 +32,7 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
 
     sourceSets {
         commonMain {
@@ -84,7 +86,7 @@
                 implementation(libs.kotlinCoroutinesAndroid)
 
                 implementation("androidx.activity:activity-ktx:1.7.0")
-                implementation(project(":core:core"))
+                implementation("androidx.core:core:1.11.0-beta02")
                 implementation('androidx.collection:collection:1.0.0')
                 implementation("androidx.customview:customview-poolingcontainer:1.0.0")
                 implementation("androidx.savedstate:savedstate-ktx:1.2.1")
@@ -197,7 +199,7 @@
         // version of foundation will be at least this version. This will prevent the bug in
         // foundation from occurring. This does _NOT_ require that the app have foundation as
         // a dependency.
-        implementation(project(":compose:foundation:foundation")) {
+        implementation("androidx.compose.foundation:foundation:1.4.0") {
             because 'prevents a critical bug in Text'
         }
     }
diff --git a/compose/ui/ui/integration-tests/ui-demos/lint-baseline.xml b/compose/ui/ui/integration-tests/ui-demos/lint-baseline.xml
new file mode 100644
index 0000000..d9b1b51
--- /dev/null
+++ b/compose/ui/ui/integration-tests/ui-demos/lint-baseline.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method pointerCounterGestureFilter has parameter &apos;onPointerCountChanged&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onPointerCountChanged: (Int) -> Unit"
+        errorLine2="                           ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setOnPointerCountChanged has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    lateinit var onPointerCountChanged: (resultingPointerCount: Int) -> Unit"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Unit> of &apos;getOnPointerCountChanged&apos;."
+        errorLine1="    lateinit var onPointerCountChanged: (resultingPointerCount: Int) -> Unit"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method RecyclingAndroidViewLazyColumn has parameter &apos;onChangeCheck&apos; with type Function2&lt;? super Integer, ? super Boolean, Unit>."
+        errorLine1="    onChangeCheck: (Int, Boolean) -> Unit"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt"/>
+    </issue>
+
+</issues>
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
index 60c9467..17e91b3 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
@@ -90,7 +90,6 @@
 }
 
 fun Modifier.pointerCounterGestureFilter(
-    @Suppress("PrimitiveInLambda")
     onPointerCountChanged: (Int) -> Unit
 ): Modifier =
     composed {
@@ -104,7 +103,6 @@
 
 internal class PointerCounterGestureFilter : PointerInputFilter() {
 
-    @Suppress("PrimitiveInLambda")
     lateinit var onPointerCountChanged: (resultingPointerCount: Int) -> Unit
 
     override fun onPointerEvent(
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
index 24d8ee3..6cfb3ae 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
@@ -78,7 +78,6 @@
 @Composable
 private fun RecyclingAndroidViewLazyColumn(
     checkedItems: Set<Int>,
-    @Suppress("PrimitiveInLambda")
     onChangeCheck: (Int, Boolean) -> Unit
 ) {
     var allocationCounter by remember { mutableIntStateOf(0) }
diff --git a/compose/ui/ui/lint-baseline.xml b/compose/ui/ui/lint-baseline.xml
index 4d3c0de..1bbc5bd 100644
--- a/compose/ui/ui/lint-baseline.xml
+++ b/compose/ui/ui/lint-baseline.xml
@@ -55,4 +55,328 @@
             file="src/commonMain/kotlin/androidx/compose/ui/platform/WindowInfo.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor AlignmentLine has parameter &apos;merger&apos; with type Function2&lt;? super Integer, ? super Integer, Integer>."
+        errorLine1="    internal val merger: (Int, Int) -> Int"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Integer, Integer, Integer> of &apos;getMerger$lint_module&apos;."
+        errorLine1="    internal val merger: (Int, Int) -> Int"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor VerticalAlignmentLine has parameter &apos;merger&apos; with type Function2&lt;? super Integer, ? super Integer, Integer>."
+        errorLine1="class VerticalAlignmentLine(merger: (Int, Int) -> Int) : AlignmentLine(merger)"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor HorizontalAlignmentLine has parameter &apos;merger&apos; with type Function2&lt;? super Integer, ? super Integer, Integer>."
+        errorLine1="class HorizontalAlignmentLine(merger: (Int, Int) -> Int) : AlignmentLine(merger)"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;setSelectionAction&apos; with type AccessibilityAction&lt;Function3&lt;? super Integer, ? super Integer, ? super Boolean, ? extends Boolean>>."
+        errorLine1="            val setSelectionAction ="
+        errorLine2="            ^">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollAction&apos; with type AccessibilityAction&lt;Function2&lt;? super Float, ? super Float, ? extends Boolean>>."
+        errorLine1="        val scrollAction = semanticsNode.unmergedConfig.getOrNull(SemanticsActions.ScrollBy)"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;setProgressAction&apos; with type AccessibilityAction&lt;Function1&lt;? super Float, ? extends Boolean>>."
+        errorLine1="                    val setProgressAction ="
+        errorLine2="                    ^">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollAction&apos; with type AccessibilityAction&lt;Function2&lt;? super Float, ? super Float, ? extends Boolean>>."
+        errorLine1="                val scrollAction ="
+        errorLine2="                ^">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;vare2b4ac12&apos; with type AccessibilityAction&lt;Function2&lt;? super Float, ? super Float, ? extends Boolean>>."
+        errorLine1="                    node.unmergedConfig.getOrNull(SemanticsActions.ScrollBy) ?: return false"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollAction&apos; with type AccessibilityAction&lt;Function2&lt;? super Float, ? super Float, ? extends Boolean>>."
+        errorLine1="                var scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeViewAccessibilityDelegateCompat.android.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;ComposeUiNode, Integer, Unit> of &apos;getSetCompositeKeyHash&apos;."
+        errorLine1="        val SetCompositeKeyHash: ComposeUiNode.(Int) -> Unit ="
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;factory&apos; with type Function3&lt;? super Modifier, ? super Composer, ? super Integer, ? extends Modifier>."
+        errorLine1="                @Suppress(&quot;UNCHECKED_CAST&quot;)"
+        errorLine2="                ^">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;FocusDirection, FocusRequester> of &apos;getEnter&apos;."
+        errorLine1="    var enter: (FocusDirection) -> FocusRequester"
+        errorLine2="        ~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setEnter has parameter &apos;_&apos; with type Function1&lt;? super FocusDirection, FocusRequester>."
+        errorLine1="        set(_) {}"
+        errorLine2="            ~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;FocusDirection, FocusRequester> of &apos;getExit&apos;."
+        errorLine1="    var exit: (FocusDirection) -> FocusRequester"
+        errorLine2="        ~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setExit has parameter &apos;_&apos; with type Function1&lt;? super FocusDirection, FocusRequester>."
+        errorLine1="        set(_) {}"
+        errorLine2="            ~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method withInfiniteAnimationFrameNanos has parameter &apos;onFrame&apos; with type Function1&lt;? super Long, ? extends R>."
+        errorLine1="internal suspend fun &lt;R> withInfiniteAnimationFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R ="
+        errorLine2="                                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor InputModeManagerImpl has parameter &apos;onRequestInputModeChange&apos; with type Function1&lt;? super InputMode, Boolean>."
+        errorLine1="    private val onRequestInputModeChange: (InputMode) -> Boolean"
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/input/InputModeManager.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type SemanticsPropertyKey&lt;Function1&lt;Object, Integer>> of &apos;getIndexForKey&apos;."
+        errorLine1="    val IndexForKey = SemanticsPropertyKey&lt;(Any) -> Int>(&quot;IndexForKey&quot;)"
+        errorLine2="        ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type SemanticsPropertyKey&lt;AccessibilityAction&lt;Function2&lt;Float, Float, Boolean>>> of &apos;getScrollBy&apos;."
+        errorLine1="    val ScrollBy = ActionPropertyKey&lt;(x: Float, y: Float) -> Boolean>(&quot;ScrollBy&quot;)"
+        errorLine2="        ~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type SemanticsPropertyKey&lt;AccessibilityAction&lt;Function1&lt;Integer, Boolean>>> of &apos;getScrollToIndex&apos;."
+        errorLine1="    val ScrollToIndex = ActionPropertyKey&lt;(Int) -> Boolean>(&quot;ScrollToIndex&quot;)"
+        errorLine2="        ~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type SemanticsPropertyKey&lt;AccessibilityAction&lt;Function1&lt;Float, Boolean>>> of &apos;getSetProgress&apos;."
+        errorLine1="    val SetProgress = ActionPropertyKey&lt;(progress: Float) -> Boolean>(&quot;SetProgress&quot;)"
+        errorLine2="        ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type SemanticsPropertyKey&lt;AccessibilityAction&lt;Function3&lt;Integer, Integer, Boolean, Boolean>>> of &apos;getSetSelection&apos;."
+        errorLine1="    val SetSelection = ActionPropertyKey&lt;(Int, Int, Boolean) -> Boolean>(&quot;SetSelection&quot;)"
+        errorLine2="        ~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor ScrollAxisRange has parameter &apos;value&apos; with type Function0&lt;Float>."
+        errorLine1="    val value: () -> Float,"
+        errorLine2="               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function0&lt;Float> of &apos;getValue&apos;."
+        errorLine1="    val value: () -> Float,"
+        errorLine2="               ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor ScrollAxisRange has parameter &apos;maxValue&apos; with type Function0&lt;Float>."
+        errorLine1="    val maxValue: () -> Float,"
+        errorLine2="                  ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function0&lt;Float> of &apos;getMaxValue&apos;."
+        errorLine1="    val maxValue: () -> Float,"
+        errorLine2="                  ~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method indexForKey has parameter &apos;mapping&apos; with type Function1&lt;Object, Integer>."
+        errorLine1="fun SemanticsPropertyReceiver.indexForKey(mapping: (Any) -> Int) {"
+        errorLine2="                                                   ~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method scrollBy has parameter &apos;action&apos; with type Function2&lt;? super Float, ? super Float, Boolean>."
+        errorLine1="    action: ((x: Float, y: Float) -> Boolean)?"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method scrollToIndex has parameter &apos;action&apos; with type Function1&lt;? super Integer, Boolean>."
+        errorLine1="    action: (Int) -> Boolean"
+        errorLine2="            ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setProgress has parameter &apos;action&apos; with type Function1&lt;? super Float, Boolean>."
+        errorLine1="fun SemanticsPropertyReceiver.setProgress(label: String? = null, action: ((Float) -> Boolean)?) {"
+        errorLine2="                                                                         ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setSelection has parameter &apos;action&apos; with type Function3&lt;? super Integer, ? super Integer, ? super Boolean, Boolean>."
+        errorLine1="    action: ((startIndex: Int, endIndex: Int, relativeToOriginalText: Boolean) -> Boolean)?"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberVectorPainter has parameter &apos;content&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="    content: @Composable @VectorComposable (viewportWidth: Float, viewportHeight: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberVectorPainter has parameter &apos;content&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="    content: @Composable @VectorComposable (viewportWidth: Float, viewportHeight: Float) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method composeVector has parameter &apos;composable&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="        composable: @Composable (viewportWidth: Float, viewportHeight: Float) -> Unit"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method RenderVector$lint_module has parameter &apos;content&apos; with type Function2&lt;? super Float, ? super Float, Unit>."
+        errorLine1="        content: @Composable (viewportWidth: Float, viewportHeight: Float) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt"/>
+    </issue>
+
 </issues>
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
index 8d0c63d..b7dc4cc 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
@@ -482,6 +482,97 @@
         assertThat(cursorAnchorInfo.editorBoundsInfo).isNull()
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testLineBounds() {
+        val fontSize = 10.sp
+        val fontSizeInPx = with(defaultDensity) { fontSize.toPx() }
+        // 6 lines of text
+        val textFieldValue = TextFieldValue("a\nbb\nccc\ndddd\neeeee\nffffff")
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text, fontSize = fontSize)
+        // Lines 2, 3, 4 are visible
+        val innerTextFieldBounds =
+            Rect(
+                0f,
+                textLayoutResult.getLineTop(2) + 1f,
+                fontSizeInPx,
+                textLayoutResult.getLineBottom(4) - 1f
+            )
+
+        val cursorAnchorInfo =
+            CursorAnchorInfo.Builder()
+                .build(
+                    textFieldValue,
+                    textLayoutResult,
+                    matrix,
+                    innerTextFieldBounds = innerTextFieldBounds,
+                    decorationBoxBounds = innerTextFieldBounds
+                )
+
+        assertThat(cursorAnchorInfo.visibleLineBounds.size).isEqualTo(3)
+        // Line 2 "ccc" has 3 characters
+        assertThat(cursorAnchorInfo.visibleLineBounds[0])
+            .isEqualTo(
+                RectF(
+                    0f,
+                    textLayoutResult.getLineTop(2),
+                    3 * fontSizeInPx,
+                    textLayoutResult.getLineBottom(2)
+                )
+            )
+        // Line 3 "dddd" has 4 characters
+        assertThat(cursorAnchorInfo.visibleLineBounds[1])
+            .isEqualTo(
+                RectF(
+                    0f,
+                    textLayoutResult.getLineTop(3),
+                    4 * fontSizeInPx,
+                    textLayoutResult.getLineBottom(3)
+                )
+            )
+        // Line 4 "eeeee" has 5 characters
+        assertThat(cursorAnchorInfo.visibleLineBounds[2])
+            .isEqualTo(
+                RectF(
+                    0f,
+                    textLayoutResult.getLineTop(4),
+                    5 * fontSizeInPx,
+                    textLayoutResult.getLineBottom(4)
+                )
+            )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testLineBoundsNotIncludedWhenIncludeLineBoundsFalse() {
+        val fontSize = 10.sp
+        val fontSizeInPx = with(defaultDensity) { fontSize.toPx() }
+        // 6 lines of text
+        val textFieldValue = TextFieldValue("a\nbb\nccc\ndddd\neeeee\nffffff")
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text, fontSize = fontSize)
+        // Lines 2, 3, 4 are visible
+        val innerTextFieldBounds =
+            Rect(
+                0f,
+                textLayoutResult.getLineTop(2) + 1f,
+                fontSizeInPx,
+                textLayoutResult.getLineBottom(4) - 1f
+            )
+
+        val cursorAnchorInfo =
+            CursorAnchorInfo.Builder()
+                .build(
+                    textFieldValue,
+                    textLayoutResult,
+                    matrix,
+                    innerTextFieldBounds = innerTextFieldBounds,
+                    decorationBoxBounds = innerTextFieldBounds,
+                    includeLineBounds = false
+                )
+
+        assertThat(cursorAnchorInfo.visibleLineBounds.size).isEqualTo(0)
+    }
+
     private fun getTextLayoutResult(
         text: String,
         fontSize: TextUnit = 12.sp,
@@ -524,7 +615,8 @@
     matrix: Matrix,
     includeInsertionMarker: Boolean = true,
     includeCharacterBounds: Boolean = true,
-    includeEditorBounds: Boolean = true
+    includeEditorBounds: Boolean = true,
+    includeLineBounds: Boolean = true
 ): CursorAnchorInfo {
     val innerTextFieldBounds =
         Rect(0f, 0f, textLayoutResult.size.width.toFloat(), textLayoutResult.size.height.toFloat())
@@ -536,6 +628,7 @@
         decorationBoxBounds = innerTextFieldBounds,
         includeInsertionMarker = includeInsertionMarker,
         includeCharacterBounds = includeCharacterBounds,
-        includeEditorBounds = includeEditorBounds
+        includeEditorBounds = includeEditorBounds,
+        includeLineBounds = includeLineBounds
     )
 }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
index ed4776e..545bd5d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
@@ -16,8 +16,10 @@
 
 package androidx.compose.ui.input
 
+import android.os.Build
 import android.view.KeyEvent
 import android.view.inputmethod.CorrectionInfo
+import android.view.inputmethod.InputConnection
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.CommitTextCommand
 import androidx.compose.ui.text.input.DeleteSurroundingTextCommand
@@ -31,6 +33,7 @@
 import androidx.compose.ui.text.input.SetSelectionCommand
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertTrue
@@ -151,6 +154,101 @@
         assertThat(ic.getSelectedText(0)).isEqualTo("Hello, World")
     }
 
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.S_V2)
+    @Test
+    fun requestCursorUpdates_preT() {
+        ic.requestCursorUpdates(
+            InputConnection.CURSOR_UPDATE_IMMEDIATE or InputConnection.CURSOR_UPDATE_MONITOR
+        )
+
+        verify(mCallback)
+            .onRequestCursorAnchorInfo(
+                immediate = true,
+                monitor = true,
+                includeInsertionMarker = true,
+                includeCharacterBounds = true,
+                includeEditorBounds = false,
+                includeLineBounds = false
+            )
+    }
+
+    @SdkSuppress(
+        minSdkVersion = Build.VERSION_CODES.TIRAMISU,
+        maxSdkVersion = Build.VERSION_CODES.TIRAMISU
+    )
+    @Test
+    fun requestCursorUpdates_T_filterFlags() {
+        ic.requestCursorUpdates(
+            InputConnection.CURSOR_UPDATE_MONITOR or
+                InputConnection.CURSOR_UPDATE_FILTER_EDITOR_BOUNDS
+        )
+
+        verify(mCallback)
+            .onRequestCursorAnchorInfo(
+                immediate = false,
+                monitor = true,
+                includeInsertionMarker = false,
+                includeCharacterBounds = false,
+                includeEditorBounds = true,
+                includeLineBounds = false
+            )
+    }
+
+    @SdkSuppress(
+        minSdkVersion = Build.VERSION_CODES.TIRAMISU,
+        maxSdkVersion = Build.VERSION_CODES.TIRAMISU
+    )
+    @Test
+    fun requestCursorUpdates_T_noFilterFlags() {
+        ic.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)
+
+        verify(mCallback)
+            .onRequestCursorAnchorInfo(
+                immediate = true,
+                monitor = false,
+                includeInsertionMarker = true,
+                includeCharacterBounds = true,
+                includeEditorBounds = true,
+                includeLineBounds = false
+            )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun requestCursorUpdates_atLeastU_filterFlags() {
+        ic.requestCursorUpdates(
+            InputConnection.CURSOR_UPDATE_MONITOR or
+                InputConnection.CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS or
+                InputConnection.CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS
+        )
+
+        verify(mCallback)
+            .onRequestCursorAnchorInfo(
+                immediate = false,
+                monitor = true,
+                includeInsertionMarker = false,
+                includeCharacterBounds = true,
+                includeEditorBounds = false,
+                includeLineBounds = true
+            )
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun requestCursorUpdates_atLeastU_noFilterFlags() {
+        ic.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)
+
+        verify(mCallback)
+            .onRequestCursorAnchorInfo(
+                immediate = true,
+                monitor = false,
+                includeInsertionMarker = true,
+                includeCharacterBounds = true,
+                includeEditorBounds = true,
+                includeLineBounds = true
+            )
+    }
+
     @Test
     fun commitTextTest() {
         val captor = argumentCaptor<List<EditCommand>>()
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidCursorAnchorInfoTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidCursorAnchorInfoTest.kt
new file mode 100644
index 0000000..d4a44fb
--- /dev/null
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidCursorAnchorInfoTest.kt
@@ -0,0 +1,411 @@
+/*
+ * 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.ui.input
+
+import android.graphics.Matrix
+import android.view.Choreographer
+import android.view.View
+import android.view.inputmethod.CursorAnchorInfo
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputConnection
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.MultiParagraph
+import androidx.compose.ui.text.TextLayoutInput
+import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.font.createFontFamilyResolver
+import androidx.compose.ui.text.font.toFontFamily
+import androidx.compose.ui.text.input.ImeOptions
+import androidx.compose.ui.text.input.InputMethodManager
+import androidx.compose.ui.text.input.RecordingInputConnection
+import androidx.compose.ui.text.input.TextFieldValue
+import androidx.compose.ui.text.input.TextInputServiceAndroid
+import androidx.compose.ui.text.input.asExecutor
+import androidx.compose.ui.text.input.build
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.sp
+import androidx.test.espresso.Espresso
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.fonts.R
+import kotlin.math.ceil
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TextInputServiceAndroidCursorAnchorInfoTest {
+    private val context = InstrumentationRegistry.getInstrumentation().context
+    private val defaultDensity = Density(density = 1f)
+    private val fontFamilyMeasureFont =
+        Font(resId = R.font.sample_font, weight = FontWeight.Normal, style = FontStyle.Normal)
+            .toFontFamily()
+
+    private lateinit var textInputService: TextInputServiceAndroid
+    private lateinit var inputMethodManager: InputMethodManager
+    private lateinit var inputConnection: RecordingInputConnection
+
+    private val builder = CursorAnchorInfo.Builder()
+    private val matrix = Matrix()
+
+    @Before
+    fun setup() {
+        val view = View(InstrumentationRegistry.getInstrumentation().context)
+        inputMethodManager = mock() { on { isActive() } doReturn true }
+        // Choreographer must be retrieved on main thread.
+        val choreographer = Espresso.onIdle { Choreographer.getInstance() }
+        textInputService =
+            TextInputServiceAndroid(
+                view,
+                inputMethodManager,
+                inputCommandProcessorExecutor = choreographer.asExecutor()
+            )
+        textInputService.startInput(
+            value = TextFieldValue(""),
+            imeOptions = ImeOptions.Default,
+            onEditCommand = {},
+            onImeActionPerformed = {}
+        )
+        inputConnection =
+            textInputService.createInputConnection(EditorInfo()) as RecordingInputConnection
+    }
+
+    @Test
+    fun requestCursorUpdates_immediate() {
+        val textFieldValue =
+            TextFieldValue("abc", selection = TextRange(2), composition = TextRange(1, 2))
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text)
+        var textLayoutPositionInWindow = Offset(1f, 1f)
+        val innerTextFieldBounds = Rect.Zero
+        val decorationBoxBounds = Rect.Zero
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        inputConnection.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)
+
+        // Immediate update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected)
+
+        clearInvocations(inputMethodManager)
+        textLayoutPositionInWindow = Offset(2f, 2f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // No further updates since monitoring is off
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+    }
+
+    @Test
+    fun requestCursorUpdates_immediate_beforeUpdateTextLayoutResult() {
+        val textFieldValue =
+            TextFieldValue("abc", selection = TextRange(2), composition = TextRange(1, 2))
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        inputConnection.requestCursorUpdates(InputConnection.CURSOR_UPDATE_IMMEDIATE)
+
+        // No immediate update until updateTextLayoutResult call
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text)
+        var textLayoutPositionInWindow = Offset(1f, 1f)
+        val innerTextFieldBounds = Rect.Zero
+        val decorationBoxBounds = Rect.Zero
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // Immediate update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected)
+
+        clearInvocations(inputMethodManager)
+        textLayoutPositionInWindow = Offset(2f, 2f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // No further updates since monitoring is off
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+    }
+
+    @Test
+    fun requestCursorUpdates_monitor() {
+        var textFieldValue =
+            TextFieldValue("abc", selection = TextRange(2), composition = TextRange(1, 2))
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text)
+        var textLayoutPositionInWindow = Offset(1f, 1f)
+        val innerTextFieldBounds = Rect.Zero
+        val decorationBoxBounds = Rect.Zero
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        inputConnection.requestCursorUpdates(InputConnection.CURSOR_UPDATE_MONITOR)
+
+        // No immediate update
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+
+        clearInvocations(inputMethodManager)
+        textLayoutPositionInWindow = Offset(2f, 2f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // Monitoring update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected)
+
+        clearInvocations(inputMethodManager)
+        textFieldValue = TextFieldValue("ac")
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        // No monitoring update until updateTextLayoutResult call
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+
+        clearInvocations(inputMethodManager)
+        textLayoutPositionInWindow = Offset(3f, 3f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // Monitoring update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected2 =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected2)
+    }
+
+    @Test
+    fun requestCursorUpdates_immediateAndMonitor() {
+        val textFieldValue =
+            TextFieldValue("abc", selection = TextRange(2), composition = TextRange(1, 2))
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text)
+        var textLayoutPositionInWindow = Offset(1f, 1f)
+        val innerTextFieldBounds = Rect.Zero
+        val decorationBoxBounds = Rect.Zero
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        inputConnection.requestCursorUpdates(
+            InputConnection.CURSOR_UPDATE_IMMEDIATE or InputConnection.CURSOR_UPDATE_MONITOR
+        )
+
+        // Immediate update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected)
+
+        clearInvocations(inputMethodManager)
+        textLayoutPositionInWindow = Offset(2f, 2f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // Monitoring update
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow.x, textLayoutPositionInWindow.y)
+        val expected2 =
+            builder.build(
+                textFieldValue,
+                textLayoutResult,
+                matrix,
+                innerTextFieldBounds,
+                decorationBoxBounds
+            )
+        verify(inputMethodManager).updateCursorAnchorInfo(expected2)
+    }
+
+    @Test
+    fun requestCursorUpdates_cancel() {
+        val textFieldValue =
+            TextFieldValue("abc", selection = TextRange(2), composition = TextRange(1, 2))
+        textInputService.updateState(oldValue = textFieldValue, newValue = textFieldValue)
+
+        val textLayoutResult = getTextLayoutResult(textFieldValue.text)
+        var textLayoutPositionInWindow = Offset(1f, 1f)
+        val innerTextFieldBounds = Rect.Zero
+        val decorationBoxBounds = Rect.Zero
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        inputConnection.requestCursorUpdates(
+            InputConnection.CURSOR_UPDATE_IMMEDIATE or InputConnection.CURSOR_UPDATE_MONITOR
+        )
+
+        // Immediate update
+        verify(inputMethodManager).updateCursorAnchorInfo(any())
+
+        clearInvocations(inputMethodManager)
+        inputConnection.requestCursorUpdates(0) // cancel updates
+
+        // No immediate update
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+
+        textLayoutPositionInWindow = Offset(2f, 2f)
+        textInputService.updateTextLayoutResult(
+            textFieldValue = textFieldValue,
+            textLayoutResult = textLayoutResult,
+            textLayoutPositionInWindow = textLayoutPositionInWindow,
+            innerTextFieldBounds = innerTextFieldBounds,
+            decorationBoxBounds = decorationBoxBounds
+        )
+
+        // No monitoring update
+        verify(inputMethodManager, never()).updateCursorAnchorInfo(any())
+    }
+
+    private fun getTextLayoutResult(text: String): TextLayoutResult {
+        val width = 1000
+        val fontFamilyResolver = createFontFamilyResolver(context)
+
+        val input =
+            TextLayoutInput(
+                text = AnnotatedString(text),
+                style = TextStyle(fontFamily = fontFamilyMeasureFont, fontSize = 12.sp),
+                placeholders = listOf(),
+                maxLines = Int.MAX_VALUE,
+                softWrap = true,
+                overflow = TextOverflow.Visible,
+                density = defaultDensity,
+                layoutDirection = LayoutDirection.Ltr,
+                fontFamilyResolver = fontFamilyResolver,
+                constraints = Constraints(maxWidth = width)
+            )
+
+        val paragraph =
+            MultiParagraph(
+                annotatedString = input.text,
+                style = input.style,
+                constraints = Constraints(maxWidth = width),
+                density = input.density,
+                fontFamilyResolver = fontFamilyResolver
+            )
+
+        return TextLayoutResult(input, paragraph, IntSize(width, ceil(paragraph.height).toInt()))
+    }
+}
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
index 675867d..764e75d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/TestUtils.kt
@@ -297,7 +297,7 @@
     init {
         updateCoordinator(coordinator)
         if (coordinator.isAttached) {
-            attach()
+            markAsAttached()
         }
     }
 
@@ -307,7 +307,7 @@
             coordinator.isAttached = false
         }
         if (isAttached) {
-            detach()
+            markAsDetached()
         }
     }
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
index a1e73ac..6e3afac 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
@@ -62,6 +62,7 @@
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
+import androidx.compose.ui.draw.clipToBounds
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Matrix
@@ -2145,6 +2146,85 @@
         }
     }
 
+    @OptIn(ExperimentalComposeUiApi::class)
+    @Test
+    fun lookaheadSizeTrackedWhenModifierChanges() {
+        var expanded by mutableStateOf(true)
+        val lookaheadHeight = mutableListOf(0, 0, 0)
+        rule.setContent {
+            CompositionLocalProvider(LocalDensity provides Density(1f)) {
+                LookaheadScope {
+                    Layout(content = {
+                        repeat(3) {
+                            Column(Modifier.layout { measurable, constraints ->
+                                measurable.measure(constraints).run {
+                                    layout(width, height) { place(0, 0) }
+                                }
+                            }) {
+                                Box(
+                                    Modifier
+                                        .requiredHeight(100.dp)
+                                        .fillMaxWidth()
+                                ) {
+                                    Text("$it")
+                                }
+                                // Bring in a new modifier while setting the size to 0.
+                                Box(
+                                    (if (!expanded) Modifier.clipToBounds() else Modifier)
+                                        .then(Modifier.layout { measurable, constraints ->
+                                            measurable.measure(constraints).run {
+                                                val (w, h) = if (isLookingAhead) {
+                                                    if (!expanded) IntSize.Zero else IntSize(
+                                                        width,
+                                                        height
+                                                    )
+                                                } else {
+                                                    IntSize(width, height)
+                                                }
+                                                layout(w, h) {
+                                                    place(0, 0)
+                                                }
+                                            }
+                                        })
+                                ) {
+                                    Box(
+                                        Modifier
+                                            .requiredHeight(100.dp)
+                                            .fillMaxWidth()
+                                    )
+                                }
+                            }
+                        }
+                    }) { measurables, constraints ->
+                        measurables.map { it.measure(constraints) }.run {
+                            layout(this[0].width, this[0].height * 3) {
+                                var h = 0
+                                forEachIndexed { id, placeable ->
+                                    if (isLookingAhead) {
+                                        lookaheadHeight[id] = placeable.height
+                                    }
+                                    placeable.place(0, h)
+                                    h += placeable.height
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        repeat(3) {
+            assertEquals(200, lookaheadHeight[it])
+        }
+        rule.runOnIdle {
+            expanded = false
+        }
+        rule.waitForIdle()
+        repeat(3) {
+            assertEquals(100, lookaheadHeight[it])
+        }
+    }
+
     @Test
     fun forceMeasureSubtreeWhileLookaheadMeasureRequestedFromSubtree() {
         var iterations by mutableStateOf(0)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAncestorsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAncestorsTest.kt
index 79f3158..103de5d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAncestorsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAncestorsTest.kt
@@ -153,10 +153,10 @@
             }
         }
         rule.runOnIdle {
-            ancestor3.detach()
-            ancestor4.detach()
-            localAncestor1.detach()
-            localAncestor3.detach()
+            ancestor3.markAsDetached()
+            ancestor4.markAsDetached()
+            localAncestor1.markAsDetached()
+            localAncestor3.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAttachOrderTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAttachOrderTest.kt
new file mode 100644
index 0000000..c9a48d3
--- /dev/null
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeAttachOrderTest.kt
@@ -0,0 +1,302 @@
+/*
+ * 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.ui.node
+
+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.padding
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private class LoggerNode(var log: MutableList<String>, name: String) : Modifier.Node() {
+    var name: String = name
+        set(value) {
+            log.add("update($field -> $value)")
+            field = value
+        }
+    override fun onAttach() {
+        log.add("attach($name)")
+    }
+
+    override fun onDetach() {
+        log.add("detach($name)")
+    }
+}
+
+private class LoggerElement(
+    val log: MutableList<String>,
+    val name: String,
+) : ModifierNodeElement<LoggerNode>() {
+    override fun create(): LoggerNode = LoggerNode(log, name)
+
+    override fun hashCode(): Int = name.hashCode()
+
+    override fun equals(other: Any?): Boolean {
+        return other is LoggerElement && other.name == name
+    }
+
+    override fun update(node: LoggerNode) {
+        node.name = name
+    }
+}
+
+private fun Modifier.logger(log: MutableList<String>, name: String) =
+    this then LoggerElement(log, name)
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ModifierNodeAttachOrderTest {
+    @get:Rule
+    val rule = createComposeRule()
+
+    @Test
+    fun attachOrderInitialComposition() {
+        // Arrange.
+        val log = mutableListOf<String>()
+        val a = LoggerNode(log, "a")
+        val b = LoggerNode(log, "b")
+        val c = LoggerNode(log, "c")
+        val d = LoggerNode(log, "d")
+
+        rule.setContent {
+            Box(modifierOf(a, b)) {
+                Box(modifierOf(c, d))
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(a)",
+                "attach(b)",
+                "attach(c)",
+                "attach(d)",
+            )
+        }
+    }
+
+    @Test
+    fun attachOrderUpdate() {
+        // Arrange.
+        val log = mutableListOf<String>()
+        val padding = Modifier.padding(0)
+        val a = LoggerNode(log, "a")
+        val b = LoggerNode(log, "b")
+        val c = LoggerNode(log, "c")
+        val d = LoggerNode(log, "d")
+
+        var parentChain by mutableStateOf<Modifier>(padding)
+        var childChain by mutableStateOf<Modifier>(padding)
+
+        rule.setContent {
+            Box(parentChain) {
+                Box(childChain)
+            }
+        }
+
+        rule.runOnIdle {
+            parentChain = Modifier
+                .elementOf(a)
+                .then(padding)
+                .elementOf(b)
+            childChain = Modifier
+                .elementOf(c)
+                .then(padding)
+                .elementOf(d)
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(a)",
+                "attach(b)",
+                "attach(c)",
+                "attach(d)",
+            )
+        }
+    }
+
+    @Test
+    fun attachOrderWhenMiddleIsRemoved() {
+        // Arrange.
+        val log = mutableListOf<String>()
+        var parentChain by mutableStateOf<Modifier>(
+            Modifier
+                .logger(log, "a")
+                .logger(log, "b")
+                .logger(log, "c")
+        )
+
+        rule.setContent {
+            Box(parentChain)
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(a)",
+                "attach(b)",
+                "attach(c)",
+            )
+            log.clear()
+        }
+
+        rule.runOnIdle {
+            parentChain = Modifier
+                .logger(log, "a")
+                .logger(log, "c")
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "detach(c)",
+                "update(b -> c)",
+            )
+            log.clear()
+        }
+
+        rule.runOnIdle {
+            parentChain = Modifier
+                .logger(log, "a")
+                .logger(log, "b")
+                .logger(log, "c")
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(c)",
+                "update(c -> b)",
+            )
+            log.clear()
+        }
+    }
+
+    @Test
+    fun addMultipleNodesInMiddle() {
+        // Arrange.
+        val log = mutableListOf<String>()
+        var parentChain by mutableStateOf<Modifier>(
+            Modifier
+                .logger(log, "a")
+                .padding(10)
+                .padding(10)
+                .logger(log, "z")
+        )
+
+        rule.setContent {
+            Box(parentChain)
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(a)",
+                "attach(z)",
+            )
+            log.clear()
+        }
+
+        rule.runOnIdle {
+            parentChain = Modifier
+                .logger(log, "a")
+                .padding(10)
+                .logger(log, "b")
+                .logger(log, "c")
+                .padding(10)
+                .logger(log, "z")
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(c)",
+                "attach(b)",
+            )
+            log.clear()
+        }
+    }
+
+    @Test
+    fun addMultipleNodesInMiddleMultipleLayouts() {
+        // Arrange.
+        val log = mutableListOf<String>()
+        var parentChain by mutableStateOf<Modifier>(
+            Modifier
+                .logger(log, "a")
+                .padding(10)
+                .padding(10)
+                .logger(log, "d")
+        )
+
+        var childChain by mutableStateOf<Modifier>(
+            Modifier
+                .logger(log, "e")
+                .padding(10)
+                .padding(10)
+                .logger(log, "h")
+        )
+
+        rule.setContent {
+            Box(parentChain) {
+                Box(childChain)
+            }
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                "attach(a)",
+                "attach(d)",
+                "attach(e)",
+                "attach(h)",
+            )
+            log.clear()
+        }
+
+        rule.runOnIdle {
+            parentChain = Modifier
+                .logger(log, "a")
+                .padding(10)
+                .logger(log, "b")
+                .logger(log, "c")
+                .padding(10)
+                .logger(log, "d")
+
+            childChain = Modifier
+                .logger(log, "e")
+                .padding(10)
+                .logger(log, "f")
+                .logger(log, "g")
+                .padding(10)
+                .logger(log, "h")
+        }
+
+        rule.runOnIdle {
+            assertThat(log).containsExactly(
+                // parent updates first
+                "attach(c)",
+                "attach(b)",
+                // then child
+                "attach(g)",
+                "attach(f)",
+            )
+            log.clear()
+        }
+    }
+}
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeChildTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeChildTest.kt
index 2442af3..47f895f 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeChildTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeChildTest.kt
@@ -151,7 +151,7 @@
             )
         }
         rule.runOnIdle {
-            child1.detach()
+            child1.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeNearestAncestorTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeNearestAncestorTest.kt
index cbf1f92..49f666f 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeNearestAncestorTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeNearestAncestorTest.kt
@@ -146,7 +146,7 @@
             )
         }
         rule.runOnIdle {
-            ancestor1.detach()
+            ancestor1.markAsDetached()
         }
 
         // Act.
@@ -175,7 +175,7 @@
             }
         }
         rule.runOnIdle {
-            localAncestor.detach()
+            localAncestor.markAsDetached()
         }
 
         // Act.
@@ -202,7 +202,7 @@
             }
         }
         rule.runOnIdle {
-            ancestor1.detach()
+            ancestor1.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitAncestorsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitAncestorsTest.kt
index 5ff5683..efcf7d6 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitAncestorsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitAncestorsTest.kt
@@ -179,10 +179,10 @@
             }
         }
         rule.runOnIdle {
-            ancestor2.detach()
-            ancestor3.detach()
-            localParent1.detach()
-            localParent3.detach()
+            ancestor2.markAsDetached()
+            ancestor3.markAsDetached()
+            localParent1.markAsDetached()
+            localParent3.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitChildrenTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitChildrenTest.kt
index 51e7f41..1efc8c7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitChildrenTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitChildrenTest.kt
@@ -152,7 +152,7 @@
             )
         }
         rule.runOnIdle {
-            child1.detach()
+            child1.markAsDetached()
         }
 
         // Act.
@@ -187,8 +187,8 @@
             }
         }
         rule.runOnIdle {
-            child1.detach()
-            child3.detach()
+            child1.markAsDetached()
+            child3.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalAncestorsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalAncestorsTest.kt
index d4ae52b..e65f572 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalAncestorsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalAncestorsTest.kt
@@ -172,8 +172,8 @@
             )
         }
         rule.runOnIdle {
-            ancestor1.detach()
-            ancestor3.detach()
+            ancestor1.markAsDetached()
+            ancestor3.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalDescendantsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalDescendantsTest.kt
index b6b7b5f..be99799 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalDescendantsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitLocalDescendantsTest.kt
@@ -173,8 +173,8 @@
             )
         }
         rule.runOnIdle {
-            child1.detach()
-            child3.detach()
+            child1.markAsDetached()
+            child3.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSelfAndChildrenTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSelfAndChildrenTest.kt
index 89c7f63..60325f5 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSelfAndChildrenTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSelfAndChildrenTest.kt
@@ -270,9 +270,9 @@
             }
         }
         rule.runOnIdle {
-            child1.detach()
-            child2.detach()
-            child6.detach()
+            child1.markAsDetached()
+            child2.markAsDetached()
+            child6.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeIfTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeIfTest.kt
index 4508164..2dda0cd 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeIfTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeIfTest.kt
@@ -202,8 +202,8 @@
             }
         }
         rule.runOnIdle {
-            node2.detach()
-            node6.detach()
+            node2.markAsDetached()
+            node6.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeTest.kt
index 1a45eb5f..53bf71c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModifierNodeVisitSubtreeTest.kt
@@ -145,7 +145,7 @@
             )
         }
         rule.runOnIdle {
-            localChild1.detach()
+            localChild1.markAsDetached()
         }
 
         // Act.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/MyersDiffTests.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/MyersDiffTests.kt
index 856b882..edf4fce 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/MyersDiffTests.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/MyersDiffTests.kt
@@ -22,6 +22,68 @@
 class MyersDiffTests {
 
     @Test
+    fun testDiffWithRemovesAtStart() {
+        val a = listOf(0, 0, 0, 0, 0, 1, 2)
+        val b = listOf(1, 2, 3)
+        val (c, log) = executeListDiff(a, b)
+        assertEquals(b, c)
+        assertEquals(
+            """
+            Remove(0 at 0)
+            Remove(0 at 0)
+            Remove(0 at 0)
+            Remove(0 at 0)
+            Remove(0 at 0)
+            Equals(x = 5, y = 0)
+            Equals(x = 6, y = 1)
+            Insert(3 at 2)
+            """.trimIndent(),
+            log.joinToString("\n")
+        )
+    }
+
+    @Test
+    fun testDiffWithRemovesAtEnd() {
+        val a = listOf(0, 1, 2, 3, 4)
+        val b = listOf(0, 1, 2)
+        val (c, log) = executeListDiff(a, b)
+        assertEquals(b, c)
+        assertEquals(
+            """
+            Equals(x = 0, y = 0)
+            Equals(x = 1, y = 1)
+            Equals(x = 2, y = 2)
+            Remove(3 at 3)
+            Remove(4 at 3)
+            """.trimIndent(),
+            log.joinToString("\n")
+        )
+    }
+
+    @Test
+    fun testDiffWithInsertsAtEnd() {
+        val a = listOf(0, 1, 2)
+        val b = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
+        val (c, log) = executeListDiff(a, b)
+        assertEquals(b, c)
+        assertEquals(
+            """
+            Remove(0 at 0)
+            Equals(x = 1, y = 0)
+            Equals(x = 2, y = 1)
+            Insert(3 at 2)
+            Insert(4 at 3)
+            Insert(5 at 4)
+            Insert(6 at 5)
+            Insert(7 at 6)
+            Insert(8 at 7)
+            Insert(9 at 8)
+            """.trimIndent(),
+            log.joinToString("\n")
+        )
+    }
+
+    @Test
     fun testDiff() {
         val a = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
         val b = listOf(0, 1, 2, 3, 4, 6, 7, 8, 9, 10)
@@ -29,17 +91,17 @@
         assertEquals(b, c)
         assertEquals(
             """
-            Equals(x = 10, y = 9)
-            Equals(x = 9, y = 8)
-            Equals(x = 8, y = 7)
-            Equals(x = 7, y = 6)
-            Equals(x = 6, y = 5)
-            Remove(5)
-            Equals(x = 4, y = 4)
-            Equals(x = 3, y = 3)
-            Equals(x = 2, y = 2)
-            Equals(x = 1, y = 1)
             Equals(x = 0, y = 0)
+            Equals(x = 1, y = 1)
+            Equals(x = 2, y = 2)
+            Equals(x = 3, y = 3)
+            Equals(x = 4, y = 4)
+            Remove(5 at 5)
+            Equals(x = 6, y = 5)
+            Equals(x = 7, y = 6)
+            Equals(x = 8, y = 7)
+            Equals(x = 9, y = 8)
+            Equals(x = 10, y = 9)
             """.trimIndent(),
             log.joinToString("\n")
         )
@@ -60,14 +122,14 @@
             "aaaa",
             "bbbb",
             """
-            Remove(3)
-            Remove(2)
-            Remove(1)
-            Remove(0)
+            Remove(a at 0)
+            Remove(a at 0)
+            Remove(a at 0)
+            Remove(a at 0)
             Insert(b at 0)
-            Insert(b at 0)
-            Insert(b at 0)
-            Insert(b at 0)
+            Insert(b at 1)
+            Insert(b at 2)
+            Insert(b at 3)
             """.trimIndent()
         )
 
@@ -98,14 +160,14 @@
             return x[oldIndex] == y[newIndex]
         }
 
-        override fun insert(atIndex: Int, newIndex: Int) {
-            log.add("Insert(${y[newIndex]} at $atIndex)")
-            result.add(atIndex, y[newIndex])
+        override fun insert(newIndex: Int) {
+            log.add("Insert(${y[newIndex]} at $newIndex)")
+            result.add(newIndex, y[newIndex])
         }
 
-        override fun remove(oldIndex: Int) {
-            log.add("Remove($oldIndex)")
-            result.removeAt(oldIndex)
+        override fun remove(atIndex: Int, oldIndex: Int) {
+            log.add("Remove(${x[oldIndex]} at $atIndex)")
+            result.removeAt(atIndex)
         }
 
         override fun same(oldIndex: Int, newIndex: Int) {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTester.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTester.kt
index c96f1d2..bd20a93 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTester.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTester.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.node
 
+import androidx.compose.ui.MockOwner
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.InspectorInfo
 import com.google.common.base.Objects
@@ -31,7 +32,7 @@
     fun assertElementDiff(expected: String) {
         Assert.assertEquals(
             expected,
-            oplog.reversed().joinToString("\n") {
+            oplog.joinToString("\n") {
                 it.elementDiffString()
             }
         )
@@ -59,6 +60,18 @@
 
     val aggregateChildMasks: List<Int> get() = nodes.map { it.aggregateChildKindSet }
 
+    fun attach(): NodeChainTester {
+        check(!layoutNode.isAttached)
+        layoutNode.attach(MockOwner())
+        return this
+    }
+
+    fun detach(): NodeChainTester {
+        check(layoutNode.isAttached)
+        layoutNode.detach()
+        return this
+    }
+
     fun clearLog(): NodeChainTester {
         log.clear()
         return this
@@ -69,10 +82,21 @@
         return this
     }
 
+    fun validateAttached(): NodeChainTester {
+        chain.head.visitSubtree(Nodes.Any) {
+            check(it.isAttached)
+        }
+        return this
+    }
+
     fun withModifiers(vararg modifiers: Modifier): NodeChainTester {
         chain.updateFrom(modifierOf(*modifiers))
         return this
     }
+    fun withModifierNodes(vararg nodes: Modifier.Node): NodeChainTester {
+        chain.updateFrom(modifierOf(*nodes))
+        return this
+    }
 
     fun assertStringEquals(expected: String): NodeChainTester {
         Assert.assertEquals(expected, chain.toString())
@@ -98,10 +122,9 @@
         newIndex: Int,
         prev: Modifier.Element,
         next: Modifier.Element,
-        before: Modifier.Node,
-        after: Modifier.Node
+        node: Modifier.Node,
     ) {
-        log.op(DiffOp.Same(oldIndex, newIndex, prev, next, before, after, true))
+        log.op(DiffOp.Same(oldIndex, newIndex, prev, next, node, true))
     }
 
     override fun nodeReused(
@@ -111,7 +134,7 @@
         next: Modifier.Element,
         node: Modifier.Node
     ) {
-        log.op(DiffOp.Same(oldIndex, newIndex, prev, next, node, node, false))
+        log.op(DiffOp.Same(oldIndex, newIndex, prev, next, node, false))
     }
 
     override fun nodeInserted(
@@ -144,15 +167,13 @@
         private val newIndex: Int,
         private val beforeEl: Modifier.Element,
         private val afterEl: Modifier.Element,
-        private val beforeEntity: Modifier.Node,
-        private val afterEntity: Modifier.Node,
+        private val node: Modifier.Node,
         val updated: Boolean,
     ) : DiffOp(beforeEl, if (updated) "*" else " ", "Same") {
         override fun debug() = """
             <$opString>
                 $beforeEl @ $oldIndex = $afterEl @ $newIndex
-                before = $beforeEntity
-                after = $afterEntity
+                node: $node
                 updated? = $updated
             </$opString>
         """.trimIndent()
@@ -196,6 +217,25 @@
     return result
 }
 
+fun modifierOf(vararg nodes: Modifier.Node): Modifier {
+    var result: Modifier = Modifier
+    for (n in nodes) {
+        result = result.then(NodeModifierElementNode(n))
+    }
+    return result
+}
+
+internal open class NodeModifierElementNode(val node: Modifier.Node) :
+    ModifierNodeElement<Modifier.Node>() {
+    override fun create(): Modifier.Node = node
+    override fun update(node: Modifier.Node) { }
+    override fun hashCode(): Int = node.hashCode()
+    override fun equals(other: Any?): Boolean {
+        if (other !is NodeModifierElementNode) return false
+        return other.node === node
+    }
+}
+
 fun reusableModifier(name: String): Modifier.Element = object : Modifier.Element {
     override fun toString(): String = name
 }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTests.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTests.kt
index 958ec8f..ecac318 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTests.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/NodeChainTests.kt
@@ -21,7 +21,58 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
+private class AttachedStateDebuggerNode() : Modifier.Node() {
+
+    var localIsAttached: Boolean = false
+    fun validateHierarchy() {
+        check(isAttached)
+        visitAncestors(Nodes.Any) {
+            check(it.isAttached)
+        }
+        visitSubtree(Nodes.Any) {
+            check(it.isAttached)
+        }
+    }
+    override fun onAttach() {
+        localIsAttached = true
+        validateHierarchy()
+    }
+
+    override fun onDetach() {
+        localIsAttached = false
+        validateHierarchy()
+    }
+}
+
 class NodeChainTests {
+    @Test
+    fun testAttachDetach() {
+        val a = AttachedStateDebuggerNode()
+        val b = AttachedStateDebuggerNode()
+        chainTester()
+            .withModifierNodes(a, b)
+            .attach()
+            .validateAttached()
+
+        check(a.localIsAttached)
+        check(b.localIsAttached)
+        a.validateHierarchy()
+        b.validateHierarchy()
+    }
+
+    @Test
+    fun testAttachDetach2() {
+        val a = object : NodeModifierElementNode(object : Modifier.Node() {}) {}
+        val b = object : NodeModifierElementNode(object : Modifier.Node() {}) {}
+        val c = object : NodeModifierElementNode(AttachedStateDebuggerNode()) {}
+
+        chainTester()
+            .withModifiers(a)
+            .attach()
+            .validateAttached()
+            .withModifiers(c, a, b)
+            .validateAttached()
+    }
 
     @Test
     fun testInsertsAndDeletesAtTail() {
@@ -146,6 +197,7 @@
         val b = modifierB()
         val modifierInfo = chainTester()
             .withModifiers(a, b)
+            .attach()
             .chain
             .getModifierInfo()
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
index 960ddd4..f3ea72c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
@@ -49,6 +49,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.round
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
@@ -153,6 +154,7 @@
     }
 
     // Make sure that the position in the window changes when the decor view's scroll changes.
+    @FlakyTest(bugId = 283784222)
     @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun positionInWindowOnScrollWindow() {
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 cf1b675..eba5a74 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
@@ -982,7 +982,6 @@
                 getAccessibilitySelectionStart(semanticsNode),
                 getAccessibilitySelectionEnd(semanticsNode)
             )
-            @Suppress("PrimitiveInLambda")
             val setSelectionAction =
                 semanticsNode.unmergedConfig.getOrNull(SemanticsActions.SetSelection)
             // ACTION_SET_SELECTION should be provided even when SemanticsActions.SetSelection
@@ -1080,10 +1079,8 @@
             return value() > 0f && !reverseScrolling || value() < maxValue() && reverseScrolling
         }
 
-        @Suppress("PrimitiveInLambda")
         val xScrollState =
             semanticsNode.unmergedConfig.getOrNull(SemanticsProperties.HorizontalScrollAxisRange)
-        @Suppress("PrimitiveInLambda")
         val scrollAction = semanticsNode.unmergedConfig.getOrNull(SemanticsActions.ScrollBy)
         if (xScrollState != null && scrollAction != null) {
             // Talkback defines SCROLLABLE_ROLE_FILTER_FOR_DIRECTION_NAVIGATION, so we need to
@@ -1688,10 +1685,8 @@
                 val scrollVertical = scrollUp || scrollDown || scrollForward || scrollBackward
 
                 if (scrollForward || scrollBackward) {
-                    @Suppress("PrimitiveInLambda")
                     val rangeInfo =
                         node.unmergedConfig.getOrNull(SemanticsProperties.ProgressBarRangeInfo)
-                    @Suppress("PrimitiveInLambda")
                     val setProgressAction =
                         node.unmergedConfig.getOrNull(SemanticsActions.SetProgress)
                     if (rangeInfo != null && setProgressAction != null) {
@@ -1715,9 +1710,7 @@
                     return amount < 0 && value() > 0 || amount > 0 && value() < maxValue()
                 }
 
-                @Suppress("PrimitiveInLambda")
                 val viewport = node.layoutInfo.coordinates.boundsInParent().size
-                @Suppress("PrimitiveInLambda")
                 val scrollAction =
                     node.unmergedConfig.getOrNull(SemanticsActions.ScrollBy) ?: return false
 
@@ -1848,9 +1841,7 @@
 
             android.R.id.accessibilityActionShowOnScreen -> {
                 // TODO(b/190865803): Consider scrolling nested containers instead of only the first one.
-                @Suppress("PrimitiveInLambda")
                 var scrollableAncestor: SemanticsNode? = node.parent
-                @Suppress("PrimitiveInLambda")
                 var scrollAction = scrollableAncestor?.config?.getOrNull(SemanticsActions.ScrollBy)
                 while (scrollableAncestor != null) {
                     if (scrollAction != null) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoBuilder.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoBuilder.kt
index fd3d4e5..bb53826 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoBuilder.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoBuilder.kt
@@ -43,6 +43,7 @@
  * @param includeInsertionMarker whether to include insertion marker info in the CursorAnchorInfo
  * @param includeCharacterBounds whether to include character bounds info in the CursorAnchorInfo
  * @param includeEditorBounds whether to include editor bounds info in the CursorAnchorInfo
+ * @param includeLineBounds whether to include line bounds info in the CursorAnchorInfo
  */
 internal fun CursorAnchorInfo.Builder.build(
     textFieldValue: TextFieldValue,
@@ -52,7 +53,8 @@
     decorationBoxBounds: Rect,
     includeInsertionMarker: Boolean = true,
     includeCharacterBounds: Boolean = true,
-    includeEditorBounds: Boolean = true
+    includeEditorBounds: Boolean = true,
+    includeLineBounds: Boolean = true
 ): CursorAnchorInfo {
     reset()
 
@@ -88,6 +90,14 @@
         CursorAnchorInfoApi33Helper.setEditorBoundsInfo(this, decorationBoxBounds)
     }
 
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && includeLineBounds) {
+        CursorAnchorInfoApi34Helper.addVisibleLineBounds(
+            this,
+            textLayoutResult,
+            innerTextFieldBounds
+        )
+    }
+
     return build()
 }
 
@@ -176,6 +186,31 @@
         )
 }
 
+@RequiresApi(34)
+private object CursorAnchorInfoApi34Helper {
+    @JvmStatic
+    @DoNotInline
+    fun addVisibleLineBounds(
+        builder: CursorAnchorInfo.Builder,
+        textLayoutResult: TextLayoutResult,
+        innerTextFieldBounds: Rect
+    ): CursorAnchorInfo.Builder {
+        if (!innerTextFieldBounds.isEmpty) {
+            val firstLine = textLayoutResult.getLineForVerticalPosition(innerTextFieldBounds.top)
+            val lastLine = textLayoutResult.getLineForVerticalPosition(innerTextFieldBounds.bottom)
+            for (index in firstLine..lastLine) {
+                builder.addVisibleLineBounds(
+                    textLayoutResult.getLineLeft(index),
+                    textLayoutResult.getLineTop(index),
+                    textLayoutResult.getLineRight(index),
+                    textLayoutResult.getLineBottom(index)
+                )
+            }
+        }
+        return builder
+    }
+}
+
 /**
  * Whether the point specified by the given offset lies inside or on an edge of this rectangle.
  *
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoController.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoController.kt
new file mode 100644
index 0000000..e386aa98
--- /dev/null
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/CursorAnchorInfoController.kt
@@ -0,0 +1,148 @@
+/*
+ * 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.ui.text.input
+
+import android.graphics.Matrix
+import android.view.inputmethod.CursorAnchorInfo
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.text.TextLayoutResult
+
+internal class CursorAnchorInfoController(private val inputMethodManager: InputMethodManager) {
+    private var monitorEnabled = false
+    private var hasPendingImmediateRequest = false
+
+    private var includeInsertionMarker = false
+    private var includeCharacterBounds = false
+    private var includeEditorBounds = false
+    private var includeLineBounds = false
+
+    private var textFieldValue: TextFieldValue? = null
+    private var textLayoutResult: TextLayoutResult? = null
+    private var textLayoutPositionInWindow: Offset? = null
+    private var innerTextFieldBounds: Rect? = null
+    private var decorationBoxBounds: Rect? = null
+
+    private val builder = CursorAnchorInfo.Builder()
+    private val matrix = Matrix()
+
+    /**
+     * Requests [CursorAnchorInfo] updates to be provided to the [InputMethodManager].
+     *
+     * Combinations of [immediate] and [monitor] are used to specify when to provide updates. If
+     * these are both false, then no further updates will be provided.
+     *
+     * @param immediate whether to update with the current [CursorAnchorInfo] immediately, or as
+     *   soon as available
+     * @param monitor whether to provide [CursorAnchorInfo] updates for all future layout or
+     *   position changes
+     * @param includeInsertionMarker whether to include insertion marker (i.e. cursor) location
+     *   information
+     * @param includeCharacterBounds whether to include character bounds information for the
+     *   composition range
+     * @param includeEditorBounds whether to include editor bounds information
+     * @param includeLineBounds whether to include line bounds information
+     */
+    fun requestUpdate(
+        immediate: Boolean,
+        monitor: Boolean,
+        includeInsertionMarker: Boolean,
+        includeCharacterBounds: Boolean,
+        includeEditorBounds: Boolean,
+        includeLineBounds: Boolean
+    ) {
+        this.includeInsertionMarker = includeInsertionMarker
+        this.includeCharacterBounds = includeCharacterBounds
+        this.includeEditorBounds = includeEditorBounds
+        this.includeLineBounds = includeLineBounds
+
+        if (immediate) {
+            hasPendingImmediateRequest = true
+            if (textFieldValue != null) {
+                updateCursorAnchorInfo()
+            }
+        }
+        monitorEnabled = monitor
+    }
+
+    /**
+     * Notify the controller of layout and position changes.
+     *
+     * @param textFieldValue the text field's [TextFieldValue]
+     * @param textLayoutResult the text field's [TextLayoutResult]
+     * @param textLayoutPositionInWindow position of the text field relative to the window
+     * @param innerTextFieldBounds visible bounds of the text field in local coordinates, or an
+     *   empty rectangle if the text field is not visible
+     * @param decorationBoxBounds visible bounds of the decoration box in local coordinates, or an
+     *   empty rectangle if the decoration box is not visible
+     */
+    fun updateTextLayoutResult(
+        textFieldValue: TextFieldValue,
+        textLayoutResult: TextLayoutResult,
+        textLayoutPositionInWindow: Offset,
+        innerTextFieldBounds: Rect,
+        decorationBoxBounds: Rect
+    ) {
+        this.textFieldValue = textFieldValue
+        this.textLayoutResult = textLayoutResult
+        this.textLayoutPositionInWindow = textLayoutPositionInWindow
+        this.innerTextFieldBounds = innerTextFieldBounds
+        this.decorationBoxBounds = decorationBoxBounds
+
+        if (hasPendingImmediateRequest || monitorEnabled) {
+            updateCursorAnchorInfo()
+        }
+    }
+
+    /**
+     * Invalidate the last received layout and position data.
+     *
+     * This should be called when the [TextFieldValue] has changed, so the last received layout and
+     * position data is no longer valid. [CursorAnchorInfo] updates will not be sent until new
+     * layout and position data is received.
+     */
+    fun invalidate() {
+        textFieldValue = null
+        textLayoutResult = null
+        textLayoutPositionInWindow = null
+        innerTextFieldBounds = null
+        decorationBoxBounds = null
+    }
+
+    private fun updateCursorAnchorInfo() {
+        if (!inputMethodManager.isActive()) return
+
+        matrix.reset()
+        matrix.postTranslate(textLayoutPositionInWindow!!.x, textLayoutPositionInWindow!!.y)
+
+        inputMethodManager.updateCursorAnchorInfo(
+            builder.build(
+                textFieldValue!!,
+                textLayoutResult!!,
+                matrix,
+                innerTextFieldBounds!!,
+                decorationBoxBounds!!,
+                includeInsertionMarker,
+                includeCharacterBounds,
+                includeEditorBounds,
+                includeLineBounds
+            )
+        )
+
+        hasPendingImmediateRequest = false
+    }
+}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputEventCallback2.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputEventCallback2.android.kt
index 36a4079..84b9702 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputEventCallback2.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputEventCallback2.android.kt
@@ -42,6 +42,20 @@
     fun onKeyEvent(event: KeyEvent)
 
     /**
+     * Called when IME requests cursor information updates.
+     *
+     * @see CursorAnchorInfoController.requestUpdate
+     */
+    fun onRequestCursorAnchorInfo(
+        immediate: Boolean,
+        monitor: Boolean,
+        includeInsertionMarker: Boolean,
+        includeCharacterBounds: Boolean,
+        includeEditorBounds: Boolean,
+        includeLineBounds: Boolean
+    )
+
+    /**
      * Called when IME closed the input connection.
      *
      * @param ic a closed input connection
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputMethodManager.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputMethodManager.kt
index 4bb1b10..32c9fc7 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputMethodManager.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/InputMethodManager.kt
@@ -19,10 +19,13 @@
 import android.content.Context
 import android.util.Log
 import android.view.View
+import android.view.inputmethod.CursorAnchorInfo
 import android.view.inputmethod.ExtractedText
 import androidx.core.view.SoftwareKeyboardControllerCompat
 
 internal interface InputMethodManager {
+    fun isActive(): Boolean
+
     fun restartInput()
 
     fun showSoftInput()
@@ -40,6 +43,8 @@
         compositionStart: Int,
         compositionEnd: Int
     )
+
+    fun updateCursorAnchorInfo(cursorAnchorInfo: CursorAnchorInfo)
 }
 
 /**
@@ -56,6 +61,8 @@
     private val softwareKeyboardControllerCompat =
         SoftwareKeyboardControllerCompat(view)
 
+    override fun isActive(): Boolean = imm.isActive(view)
+
     override fun restartInput() {
         imm.restartInput(view)
     }
@@ -87,4 +94,8 @@
     ) {
         imm.updateSelection(view, selectionStart, selectionEnd, compositionStart, compositionEnd)
     }
+
+    override fun updateCursorAnchorInfo(cursorAnchorInfo: CursorAnchorInfo) {
+        imm.updateCursorAnchorInfo(view, cursorAnchorInfo)
+    }
 }
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/RecordingInputConnection.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/RecordingInputConnection.android.kt
index f234d53..dfa347d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/RecordingInputConnection.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/RecordingInputConnection.android.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.text.input
 
+import android.os.Build
 import android.os.Bundle
 import android.os.Handler
 import android.text.TextUtils
@@ -257,9 +258,57 @@
     }
 
     override fun requestCursorUpdates(cursorUpdateMode: Int): Boolean = ensureActive {
-        if (DEBUG) { logDebug("requestCursorUpdates($cursorUpdateMode)") }
-        Log.w(TAG, "requestCursorUpdates is not supported")
-        return false
+        val immediate = cursorUpdateMode and InputConnection.CURSOR_UPDATE_IMMEDIATE != 0
+        val monitor = cursorUpdateMode and InputConnection.CURSOR_UPDATE_MONITOR != 0
+        if (DEBUG) {
+            logDebug(
+                "requestCursorUpdates($cursorUpdateMode=[immediate:$immediate, monitor: $monitor])"
+            )
+        }
+
+        // Before Android T, filter flags are not used, and insertion marker and character bounds
+        // info are always included.
+        var includeInsertionMarker = true
+        var includeCharacterBounds = true
+        var includeEditorBounds = false
+        var includeLineBounds = false
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            includeInsertionMarker =
+                cursorUpdateMode and InputConnection.CURSOR_UPDATE_FILTER_INSERTION_MARKER != 0
+            includeCharacterBounds =
+                cursorUpdateMode and InputConnection.CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS != 0
+            includeEditorBounds =
+                cursorUpdateMode and InputConnection.CURSOR_UPDATE_FILTER_EDITOR_BOUNDS != 0
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                includeLineBounds =
+                    cursorUpdateMode and InputConnection.CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS !=
+                        0
+            }
+            // If no filter flags are used, then all info should be included.
+            if (
+                !includeInsertionMarker &&
+                    !includeCharacterBounds &&
+                    !includeEditorBounds &&
+                    !includeLineBounds
+            ) {
+                includeInsertionMarker = true
+                includeCharacterBounds = true
+                includeEditorBounds = true
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                    includeLineBounds = true
+                }
+            }
+        }
+
+        eventCallback.onRequestCursorAnchorInfo(
+            immediate,
+            monitor,
+            includeInsertionMarker,
+            includeCharacterBounds,
+            includeEditorBounds,
+            includeLineBounds
+        )
+        return true
     }
 
     override fun getExtractedText(request: ExtractedTextRequest?, flags: Int): ExtractedText {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
index 411909b..448968d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroid.android.kt
@@ -28,8 +28,10 @@
 import android.view.inputmethod.EditorInfo
 import android.view.inputmethod.InputConnection
 import androidx.compose.runtime.collection.mutableVectorOf
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.text.ExperimentalTextApi
+import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.TextRange
 import androidx.compose.ui.text.input.TextInputServiceAndroid.TextInputCommand.HideKeyboard
 import androidx.compose.ui.text.input.TextInputServiceAndroid.TextInputCommand.ShowKeyboard
@@ -92,6 +94,8 @@
 
     private var focusedRect: AndroidRect? = null
 
+    private val cursorAnchorInfoController = CursorAnchorInfoController(inputMethodManager)
+
     /**
      * A channel that is used to debounce rapid operations such as showing/hiding the keyboard and
      * starting/stopping input, so we can make the minimal number of calls on the
@@ -136,6 +140,24 @@
                     baseInputConnection.sendKeyEvent(event)
                 }
 
+                override fun onRequestCursorAnchorInfo(
+                    immediate: Boolean,
+                    monitor: Boolean,
+                    includeInsertionMarker: Boolean,
+                    includeCharacterBounds: Boolean,
+                    includeEditorBounds: Boolean,
+                    includeLineBounds: Boolean
+                ) {
+                    cursorAnchorInfoController.requestUpdate(
+                        immediate,
+                        monitor,
+                        includeInsertionMarker,
+                        includeCharacterBounds,
+                        includeEditorBounds,
+                        includeLineBounds
+                    )
+                }
+
                 override fun onConnectionClosed(ic: RecordingInputConnection) {
                     for (i in 0 until ics.size) {
                         if (ics[i].get() == ic) {
@@ -322,6 +344,7 @@
         for (i in 0 until ics.size) {
             ics[i].get()?.mTextFieldValue = newValue
         }
+        cursorAnchorInfoController.invalidate()
 
         if (oldValue == newValue) {
             if (DEBUG) {
@@ -382,6 +405,22 @@
         }
     }
 
+    override fun updateTextLayoutResult(
+        textFieldValue: TextFieldValue,
+        textLayoutResult: TextLayoutResult,
+        textLayoutPositionInWindow: Offset,
+        innerTextFieldBounds: Rect,
+        decorationBoxBounds: Rect
+    ) {
+        cursorAnchorInfoController.updateTextLayoutResult(
+            textFieldValue,
+            textLayoutResult,
+            textLayoutPositionInWindow,
+            innerTextFieldBounds,
+            decorationBoxBounds
+        )
+    }
+
     /** Immediately restart the IME connection, bypassing the [textInputCommandQueue]. */
     private fun restartInputImmediately() {
         if (DEBUG) Log.d(TAG, "$DEBUG_CLASS.restartInputImmediately")
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
index 8f7a334..cf111e5 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposedModifier.kt
@@ -265,7 +265,7 @@
     val result = modifier.foldIn<Modifier>(Modifier) { acc, element ->
         acc.then(
             if (element is ComposedModifier) {
-                @Suppress("UNCHECKED_CAST", "PrimitiveInLambda")
+                @Suppress("UNCHECKED_CAST")
                 val factory = element.factory as Modifier.(Composer, Int) -> Modifier
                 val composedMod = factory(Modifier, this, 0)
                 materialize(composedMod)
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
index f81c807..5616a28 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
@@ -211,8 +211,9 @@
 
         // NOTE: We use an aggregate mask that or's all of the type masks of the children of the
         // chain so that we can quickly prune a subtree. This INCLUDES the kindSet of this node
-        // as well
-        internal var aggregateChildKindSet: Int = 0
+        // as well. Initialize this to "every node" so that before it is set it doesn't
+        // accidentally cause a truncated traversal.
+        internal var aggregateChildKindSet: Int = 0.inv()
         internal var parent: Node? = null
         internal var child: Node? = null
         internal var ownerScope: ObserverNodeOwnerScope? = null
@@ -257,17 +258,25 @@
         @Suppress("NOTHING_TO_INLINE")
         internal inline fun isKind(kind: NodeKind<*>) = kindSet and kind.mask != 0
 
-        internal open fun attach() {
+        internal open fun markAsAttached() {
             check(!isAttached) { "node attached multiple times" }
             check(coordinator != null) { "attach invoked on a node without a coordinator" }
             isAttached = true
+        }
+
+        internal open fun runAttachLifecycle() {
+            check(isAttached) { "Must run markAsAttached() prior to runAttachLifecycle" }
             onAttach()
         }
 
-        internal open fun detach() {
+        internal open fun runDetachLifecycle() {
             check(isAttached) { "node detached multiple times" }
             check(coordinator != null) { "detach invoked on a node without a coordinator" }
             onDetach()
+        }
+
+        internal open fun markAsDetached() {
+            check(isAttached) { "Cannot detach a node that is not attached" }
             isAttached = false
 
             scope?.let {
@@ -286,6 +295,12 @@
          * part of the UI tree.
          * When called, `node` is guaranteed to be non-null. You can call sideEffect,
          * coroutineScope, etc.
+         * This is not guaranteed to get called at a time where the rest of the Modifier.Nodes in
+         * the hierarchy are "up to date". For instance, at the time of calling onAttach for this
+         * node, another node may be in the tree that will be detached by the time Compose has
+         * finished applying changes. As a result, if you need to guarantee that the state of the
+         * tree is "final" for this round of changes, you should use the [sideEffect] API to
+         * schedule the calculation to be done at that time.
          */
         open fun onAttach() {}
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt
index fe71a18..4aa9f83 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusProperties.kt
@@ -129,9 +129,7 @@
     @set:ExperimentalComposeUiApi
     @ExperimentalComposeUiApi
     var enter: (FocusDirection) -> FocusRequester
-        @Suppress("PrimitiveInLambda")
         get() = { FocusRequester.Default }
-        @Suppress("PrimitiveInLambda")
         set(_) {}
 
     /**
@@ -153,9 +151,7 @@
     @set:ExperimentalComposeUiApi
     @ExperimentalComposeUiApi
     var exit: (FocusDirection) -> FocusRequester
-        @Suppress("PrimitiveInLambda")
         get() = { FocusRequester.Default }
-        @Suppress("PrimitiveInLambda")
         set(_) {}
 }
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
index 4c31619..58b3cd3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
@@ -79,7 +79,6 @@
     name: String = RootGroupName,
     tintColor: Color = Color.Unspecified,
     tintBlendMode: BlendMode = BlendMode.SrcIn,
-    @Suppress("PrimitiveInLambda")
     content: @Composable @VectorComposable (viewportWidth: Float, viewportHeight: Float) -> Unit
 ): VectorPainter =
     rememberVectorPainter(
@@ -123,7 +122,6 @@
     tintColor: Color = Color.Unspecified,
     tintBlendMode: BlendMode = BlendMode.SrcIn,
     autoMirror: Boolean = false,
-    @Suppress("PrimitiveInLambda")
     content: @Composable @VectorComposable (viewportWidth: Float, viewportHeight: Float) -> Unit
 ): VectorPainter {
     val density = LocalDensity.current
@@ -200,7 +198,6 @@
 
     private fun composeVector(
         parent: CompositionContext,
-        @Suppress("PrimitiveInLambda")
         composable: @Composable (viewportWidth: Float, viewportHeight: Float) -> Unit
     ): Composition {
         val existing = composition
@@ -226,7 +223,6 @@
         name: String,
         viewportWidth: Float,
         viewportHeight: Float,
-        @Suppress("PrimitiveInLambda")
         content: @Composable (viewportWidth: Float, viewportHeight: Float) -> Unit
     ) {
         vector.apply {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/InputModeManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/InputModeManager.kt
index d1e5d2c..f6a6fe2 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/InputModeManager.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/InputModeManager.kt
@@ -67,7 +67,6 @@
 
 internal class InputModeManagerImpl(
     initialInputMode: InputMode,
-    @Suppress("PrimitiveInLambda")
     private val onRequestInputModeChange: (InputMode) -> Boolean
 ) : InputModeManager {
     override var inputMode: InputMode by mutableStateOf(initialInputMode)
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollNode.kt
index 94e74df..8a1337e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/nestedscroll/NestedScrollNode.kt
@@ -128,9 +128,10 @@
     }
 
     override fun onAttach() {
-        assert(resolvedDispatcher.modifierLocalNode == null) {
-            "This dispatcher should only be used by a single Modifier.nestedScroll."
-        }
+        // NOTE: It is possible for the dispatcher of a yet-to-be-removed node above this one in the
+        // chain is being used here where the dispatcher's modifierLocalNode will not be null. As a
+        // result, we should not check to see if the dispatcher's node is null, we should just set
+        // it assuming that it is not going to be used by the previous node anymore.
         updateDispatcherFields()
     }
 
@@ -149,7 +150,10 @@
     }
 
     private fun resetDispatcherFields() {
-        resolvedDispatcher.modifierLocalNode = null
+        // only null this out if the modifier local node is what we set it to, since it is possible
+        // it has already been reused in a different node
+        if (resolvedDispatcher.modifierLocalNode === this)
+            resolvedDispatcher.modifierLocalNode = null
     }
 
     internal fun updateNode(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt
index dbc7f30..593831d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/AlignmentLine.kt
@@ -52,7 +52,6 @@
  */
 @Immutable
 sealed class AlignmentLine(
-    @Suppress("PrimitiveInLambda")
     internal val merger: (Int, Int) -> Int
 ) {
     companion object {
@@ -80,7 +79,6 @@
  *
  * @param merger How to merge two alignment line values defined by different children
  */
-@Suppress("PrimitiveInLambda")
 class VerticalAlignmentLine(merger: (Int, Int) -> Int) : AlignmentLine(merger)
 
 /**
@@ -96,7 +94,6 @@
  *
  * @param merger How to merge two alignment line values defined by different children
  */
-@Suppress("PrimitiveInLambda")
 class HorizontalAlignmentLine(merger: (Int, Int) -> Int) : AlignmentLine(merger)
 
 /**
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
index 263068d..4b840ca 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
@@ -24,6 +24,7 @@
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.ReusableContentHost
 import androidx.compose.runtime.SideEffect
+import androidx.compose.runtime.collection.mutableVectorOf
 import androidx.compose.runtime.currentComposer
 import androidx.compose.runtime.currentCompositeKeyHash
 import androidx.compose.runtime.getValue
@@ -48,6 +49,7 @@
 import androidx.compose.ui.platform.createSubcomposition
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastForEach
 
 /**
  * Analogue of [Layout] which allows to subcompose the actual content during the measuring stage
@@ -358,7 +360,6 @@
  * when a new SubcomposeLayoutState is applied to SubcomposeLayout and even when the
  * SubcomposeLayout's LayoutNode is reused via the ReusableComposeNode mechanism.
  */
-@OptIn(ExperimentalComposeUiApi::class)
 internal class LayoutNodeSubcompositionsState(
     private val root: LayoutNode,
     slotReusePolicy: SubcomposeSlotReusePolicy
@@ -374,19 +375,22 @@
             }
         }
 
-    val isInLookaheadScope: Boolean
-        get() = root.lookaheadRoot != null
-
     private var currentIndex = 0
-    private val nodeToNodeState = mutableMapOf<LayoutNode, NodeState>()
+    private var currentPostLookaheadIndex = 0
+    private val nodeToNodeState = hashMapOf<LayoutNode, NodeState>()
 
     // this map contains active slotIds (without precomposed or reusable nodes)
-    private val slotIdToNode = mutableMapOf<Any?, LayoutNode>()
+    private val slotIdToNode = hashMapOf<Any?, LayoutNode>()
     private val scope = Scope()
     private val postLookaheadMeasureScope = PostLookaheadMeasureScopeImpl()
 
-    private val precomposeMap = mutableMapOf<Any?, LayoutNode>()
+    private val precomposeMap = hashMapOf<Any?, LayoutNode>()
     private val reusableSlotIdsSet = SubcomposeSlotReusePolicy.SlotIdsSet()
+    // SlotHandles precomposed in the post-lookahead pass.
+    private val postLookaheadPrecomposeSlotHandleMap = mutableMapOf<Any?, PrecomposedSlotHandle>()
+    // Slot ids _composed_ in post-lookahead. The valid slot ids are stored between 0 and
+    // currentPostLookaheadIndex - 1, beyond index currentPostLookaheadIndex are obsolete ids.
+    private val postLookaheadComposedSlotIds = mutableVectorOf<Any?>()
 
     /**
      * `root.foldedChildren` list consist of:
@@ -423,13 +427,16 @@
             }
         }
 
-        val itemIndex = root.foldedChildren.indexOf(node)
-        require(itemIndex >= currentIndex) {
-            "Key \"$slotId\" was already used. If you are using LazyColumn/Row please make " +
-                "sure you provide a unique key for each item."
-        }
-        if (currentIndex != itemIndex) {
-            move(itemIndex, currentIndex)
+        if (root.foldedChildren.getOrNull(currentIndex) !== node) {
+            // the node has a new index in the list
+            val itemIndex = root.foldedChildren.indexOf(node)
+            require(itemIndex >= currentIndex) {
+                "Key \"$slotId\" was already used. If you are using LazyColumn/Row please make " +
+                    "sure you provide a unique key for each item."
+            }
+            if (currentIndex != itemIndex) {
+                move(itemIndex, currentIndex)
+            }
         }
         currentIndex++
 
@@ -544,14 +551,15 @@
     }
 
     fun makeSureStateIsConsistent() {
-        require(nodeToNodeState.size == root.foldedChildren.size) {
+        val childrenCount = root.foldedChildren.size
+        require(nodeToNodeState.size == childrenCount) {
             "Inconsistency between the count of nodes tracked by the state " +
                 "(${nodeToNodeState.size}) and the children count on the SubcomposeLayout" +
-                " (${root.foldedChildren.size}). Are you trying to use the state of the" +
+                " ($childrenCount). Are you trying to use the state of the" +
                 " disposed SubcomposeLayout?"
         }
-        require(root.foldedChildren.size - reusableCount - precomposedCount >= 0) {
-            "Incorrect state. Total children ${root.foldedChildren.size}. Reusable children " +
+        require(childrenCount - reusableCount - precomposedCount >= 0) {
+            "Incorrect state. Total children $childrenCount. Reusable children " +
                 "$reusableCount. Precomposed children $precomposedCount"
         }
         require(precomposeMap.size == precomposedCount) {
@@ -622,32 +630,51 @@
                 scope.density = density
                 scope.fontScale = fontScale
                 if (!isLookingAhead && root.lookaheadRoot != null) {
-                    return with(postLookaheadMeasureScope) {
-                        block(constraints)
+                    currentPostLookaheadIndex = 0
+                    val result = postLookaheadMeasureScope.block(constraints)
+                    val indexAfterMeasure = currentPostLookaheadIndex
+                    return createMeasureResult(result) {
+                        currentPostLookaheadIndex = indexAfterMeasure
+                        result.placeChildren()
+                        // dispose
+                        disposeUnusedSlotsInPostLookahead()
                     }
                 } else {
                     currentIndex = 0
                     val result = scope.block(constraints)
                     val indexAfterMeasure = currentIndex
-                    return object : MeasureResult {
-                        override val width: Int
-                            get() = result.width
-                        override val height: Int
-                            get() = result.height
-                        override val alignmentLines: Map<AlignmentLine, Int>
-                            get() = result.alignmentLines
-
-                        override fun placeChildren() {
-                            currentIndex = indexAfterMeasure
-                            result.placeChildren()
-                            disposeOrReuseStartingFromIndex(currentIndex)
-                        }
+                    return createMeasureResult(result) {
+                        currentIndex = indexAfterMeasure
+                        result.placeChildren()
+                        disposeOrReuseStartingFromIndex(currentIndex)
                     }
                 }
             }
         }
     }
 
+    private fun disposeUnusedSlotsInPostLookahead() {
+        postLookaheadPrecomposeSlotHandleMap.entries.removeAll { (slotId, handle) ->
+            val id = postLookaheadComposedSlotIds.indexOf(slotId)
+            if (id < 0 || id >= currentPostLookaheadIndex) {
+                // Slot was not used in the latest pass of post-lookahead.
+                handle.dispose()
+                true
+            } else {
+                false
+            }
+        }
+    }
+
+    private inline fun createMeasureResult(
+        result: MeasureResult,
+        crossinline placeChildrenBlock: () -> Unit
+    ) = object : MeasureResult by result {
+        override fun placeChildren() {
+            placeChildrenBlock()
+        }
+    }
+
     private val NoIntrinsicsMessage = "Asking for intrinsic measurements of SubcomposeLayout " +
         "layouts is not supported. This includes components that are built on top of " +
         "SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate " +
@@ -661,6 +688,8 @@
     fun precompose(slotId: Any?, content: @Composable () -> Unit): PrecomposedSlotHandle {
         makeSureStateIsConsistent()
         if (!slotIdToNode.containsKey(slotId)) {
+            // Yield ownership of PrecomposedHandle from postLookahead to the caller of precompose
+            postLookaheadPrecomposeSlotHandleMap.remove(slotId)
             val node = precomposeMap.getOrPut(slotId) {
                 val reusedNode = takeNodeFromReusables(slotId)
                 if (reusedNode != null) {
@@ -785,8 +814,46 @@
          * the subcomposition that happened in the lookahead pass. If [slotId] was not subcomposed
          * in the lookahead pass, [subcompose] will return an [emptyList].
          */
-        override fun subcompose(slotId: Any?, content: @Composable () -> Unit): List<Measurable> =
-            slotIdToNode[slotId]?.childMeasurables ?: emptyList()
+        override fun subcompose(slotId: Any?, content: @Composable () -> Unit): List<Measurable> {
+            val measurables = slotIdToNode[slotId]?.childMeasurables
+            if (measurables != null) {
+                return measurables
+            }
+            return postLookaheadSubcompose(slotId, content)
+        }
+    }
+
+    private fun postLookaheadSubcompose(
+        slotId: Any?,
+        content: @Composable () -> Unit
+    ): List<Measurable> {
+        require(postLookaheadComposedSlotIds.size >= currentPostLookaheadIndex) {
+            "Error: currentPostLookaheadIndex cannot be greater than the size of the" +
+                "postLookaheadComposedSlotIds list."
+        }
+        if (postLookaheadComposedSlotIds.size == currentPostLookaheadIndex) {
+            postLookaheadComposedSlotIds.add(slotId)
+        } else {
+            postLookaheadComposedSlotIds[currentPostLookaheadIndex] = slotId
+        }
+        currentPostLookaheadIndex++
+        if (!precomposeMap.contains(slotId)) {
+            // Not composed yet
+            precompose(slotId, content).also {
+                postLookaheadPrecomposeSlotHandleMap[slotId] = it
+            }
+            if (root.layoutState == LayoutState.LayingOut) {
+                root.requestLookaheadRelayout(true)
+            } else {
+                root.requestLookaheadRemeasure(true)
+            }
+        }
+
+        return precomposeMap[slotId]?.run {
+            measurePassDelegate.childDelegates.also {
+                it.fastForEach { delegate -> delegate.markDetachedFromParentLookaheadPass() }
+            }
+        } ?: emptyList()
     }
 }
 
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/BackwardsCompatNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/BackwardsCompatNode.kt
index 07b1b3c..179c56f 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/BackwardsCompatNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/BackwardsCompatNode.kt
@@ -135,15 +135,12 @@
         check(isAttached) { "initializeModifier called on unattached node" }
         val element = element
         if (isKind(Nodes.Locals)) {
+            if (element is ModifierLocalConsumer) {
+                sideEffect { updateModifierLocalConsumer() }
+            }
             if (element is ModifierLocalProvider<*>) {
                 updateModifierLocalProvider(element)
             }
-            if (element is ModifierLocalConsumer) {
-                if (duringAttach)
-                    updateModifierLocalConsumer()
-                else
-                    sideEffect { updateModifierLocalConsumer() }
-            }
         }
         if (isKind(Nodes.Draw)) {
             if (element is DrawCacheModifier) {
@@ -154,7 +151,7 @@
             }
         }
         if (isKind(Nodes.Layout)) {
-            val isChainUpdate = requireLayoutNode().nodes.tail.isAttached
+            val isChainUpdate = isChainUpdate()
             if (isChainUpdate) {
                 val coordinator = coordinator!!
                 coordinator as LayoutModifierNodeCoordinator
@@ -173,14 +170,14 @@
             if (element is OnRemeasuredModifier) {
                 // if the modifier was added but layout has already happened and might not change,
                 // we want to call remeasured in case layout doesn't happen again
-                val isChainUpdate = requireLayoutNode().nodes.tail.isAttached
+                val isChainUpdate = isChainUpdate()
                 if (isChainUpdate) {
                     requireLayoutNode().invalidateMeasurements()
                 }
             }
             if (element is OnPlacedModifier) {
                 lastOnPlacedCoordinates = null
-                val isChainUpdate = requireLayoutNode().nodes.tail.isAttached
+                val isChainUpdate = isChainUpdate()
                 if (isChainUpdate) {
                     requireOwner().registerOnLayoutCompletedListener(
                         object : Owner.OnLayoutCompletedListener {
@@ -198,7 +195,7 @@
             // if the modifier was added but layout has already happened and might not change,
             // we want to call remeasured in case layout doesn't happen again
             if (element is OnGloballyPositionedModifier) {
-                val isChainUpdate = requireLayoutNode().nodes.tail.isAttached
+                val isChainUpdate = isChainUpdate()
                 if (isChainUpdate) {
                     requireLayoutNode().invalidateMeasurements()
                 }
@@ -295,7 +292,7 @@
             // do nothing and wait for the child consumers to read us. We infer this by
             // checking to see if the tail node is attached or not. If it is not, then the node
             // chain is being attached for the first time.
-            val isChainUpdate = requireLayoutNode().nodes.tail.isAttached
+            val isChainUpdate = isChainUpdate()
             if (isChainUpdate) {
                 requireOwner()
                     .modifierLocalManager
@@ -455,3 +452,8 @@
         modifier.populateFocusOrder(FocusOrder(focusProperties))
     }
 }
+
+private fun BackwardsCompatNode.isChainUpdate(): Boolean {
+    val tailNode = requireLayoutNode().nodes.tail as TailModifierNode
+    return tailNode.attachHasBeenRun
+}
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
index 33762b2..f55bfb5 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ComposeUiNode.kt
@@ -55,7 +55,7 @@
         val SetViewConfiguration: ComposeUiNode.(ViewConfiguration) -> Unit =
             { this.viewConfiguration = it }
         @get:ExperimentalComposeUiApi
-        @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET", "PrimitiveInLambda")
+        @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
         @ExperimentalComposeUiApi
         val SetCompositeKeyHash: ComposeUiNode.(Int) -> Unit =
             { this.compositeKeyHash = it }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingNode.kt
index b011798e..5bc8a37 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatingNode.kt
@@ -112,7 +112,8 @@
             } else {
                 updateCoordinator(coordinator)
             }
-            delegateNode.attach()
+            delegateNode.markAsAttached()
+            delegateNode.runAttachLifecycle()
             autoInvalidateInsertedNode(delegateNode)
         }
         return delegatableNode
@@ -135,7 +136,8 @@
                 // remove from delegate chain
                 if (it.isAttached) {
                     autoInvalidateRemovedNode(it)
-                    it.detach()
+                    it.runDetachLifecycle()
+                    it.markAsDetached()
                 }
                 it.setAsDelegateTo(it) // sets "node" back to itself
                 it.aggregateChildKindSet = 0
@@ -236,21 +238,35 @@
         }
     }
 
-    override fun attach() {
-        super.attach()
+    override fun markAsAttached() {
+        super.markAsAttached()
         forEachImmediateDelegate {
             it.updateCoordinator(coordinator)
             // NOTE: it might already be attached if the delegate was delegated to inside of
             // onAttach()
             if (!it.isAttached) {
-                it.attach()
+                it.markAsAttached()
             }
         }
     }
 
-    override fun detach() {
-        forEachImmediateDelegate { it.detach() }
-        super.detach()
+    override fun runAttachLifecycle() {
+        forEachImmediateDelegate {
+            it.runAttachLifecycle()
+        }
+        super.runAttachLifecycle()
+    }
+
+    override fun runDetachLifecycle() {
+        super.runDetachLifecycle()
+        forEachImmediateDelegate {
+            it.runDetachLifecycle()
+        }
+    }
+
+    override fun markAsDetached() {
+        forEachImmediateDelegate { it.markAsDetached() }
+        super.markAsDetached()
     }
 
     override fun reset() {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerNodeCoordinator.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerNodeCoordinator.kt
index 9407b95..edb902f 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerNodeCoordinator.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/InnerNodeCoordinator.kt
@@ -29,15 +29,35 @@
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.IntOffset
 
+internal class TailModifierNode : Modifier.Node() {
+    init {
+        // aggregateChildKindSet defaults to all bits being set, and is expected to be set later.
+        // We can deterministically set the tail's because the tail will never have children by
+        // definition.
+        aggregateChildKindSet = 0
+    }
+    // BackwardsCompatNode uses this to determine if it is in a "chain update" or not. If attach
+    // has been run on the tail node, then we can assume that it is a chain update. Importantly,
+    // this is different than using isAttached.
+    var attachHasBeenRun = false
+    override fun toString(): String {
+        return "<tail>"
+    }
+
+    override fun onAttach() {
+        attachHasBeenRun = true
+    }
+
+    override fun onDetach() {
+        attachHasBeenRun = false
+    }
+}
+
 internal class InnerNodeCoordinator(
     layoutNode: LayoutNode
 ) : NodeCoordinator(layoutNode) {
     @OptIn(ExperimentalComposeUiApi::class)
-    override val tail: Modifier.Node = object : Modifier.Node() {
-        override fun toString(): String {
-            return "<tail>"
-        }
-    }
+    override val tail = TailModifierNode()
 
     init {
         @OptIn(ExperimentalComposeUiApi::class)
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
index 0ce26d26..a8e56fc 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
@@ -474,10 +474,11 @@
             // is a virtual lookahead root
             lookaheadRoot = _foldedParent?.lookaheadRoot ?: lookaheadRoot
         }
-        nodes.attach()
+        nodes.markAsAttached()
         _foldedChildren.forEach { child ->
             child.attach(owner)
         }
+        nodes.runAttachLifecycle()
 
         invalidateMeasurements()
         parent?.invalidateMeasurements()
@@ -513,15 +514,18 @@
         if (nodes.has(Nodes.Semantics)) {
             invalidateSemantics()
         }
-        nodes.detach()
+        nodes.runDetachLifecycle()
+        ignoreRemeasureRequests {
+            _foldedChildren.forEach { child ->
+                child.detach()
+            }
+        }
+        nodes.markAsDetached()
         owner.onDetach(this)
         this.owner = null
 
         lookaheadRoot = null
         depth = 0
-        _foldedChildren.forEach { child ->
-            child.detach()
-        }
         measurePassDelegate.onNodeDetached()
         lookaheadPassDelegate?.onNodeDetached()
     }
@@ -1321,8 +1325,9 @@
             resetModifierState()
         }
         // resetModifierState detaches all nodes, so we need to re-attach them upon reuse.
-        nodes.attach()
         semanticsId = generateSemanticsId()
+        nodes.markAsAttached()
+        nodes.runAttachLifecycle()
     }
 
     override fun onDeactivate() {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeLayoutDelegate.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeLayoutDelegate.kt
index d58eef5..75aaace 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeLayoutDelegate.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNodeLayoutDelegate.kt
@@ -47,6 +47,13 @@
         get() = measurePassDelegate.width
 
     /**
+     * This gets set to true via [MeasurePassDelegate.markDetachedFromParentLookaheadPass] and
+     * automatically gets unset in `measure` when the measure call comes from parent with
+     * layoutState being LookaheadMeasuring or LookaheadLayingOut.
+     */
+    private var detachedFromParentLookaheadPass: Boolean = false
+
+    /**
      * The layout state the node is currently in.
      *
      * The mutation of [layoutState] is confined to [LayoutNodeLayoutDelegate], and is therefore
@@ -332,6 +339,10 @@
                 return _childDelegates.asMutableList()
             }
 
+        internal fun markDetachedFromParentLookaheadPass() {
+            detachedFromParentLookaheadPass = true
+        }
+
         var layingOutChildren = false
             private set
 
@@ -1135,6 +1146,10 @@
         }
 
         override fun measure(constraints: Constraints): Placeable {
+            if (layoutNode.parent?.layoutState == LayoutState.LookaheadMeasuring ||
+                layoutNode.parent?.layoutState == LayoutState.LookaheadLayingOut) {
+                detachedFromParentLookaheadPass = false
+            }
             trackLookaheadMeasurementByParent(layoutNode)
             if (layoutNode.intrinsicsUsageByParent == LayoutNode.UsageByParent.NotUsed) {
                 // This LayoutNode may have asked children for intrinsics. If so, we should
@@ -1191,14 +1206,19 @@
                 forEachChildAlignmentLinesOwner {
                     it.alignmentLines.usedDuringParentMeasurement = false
                 }
+                // Copy out the previous size before performing lookahead measure. If never
+                // measured, set the last size to negative instead of Zero in anticipation for zero
+                // being a valid lookahead size.
+                val lastLookaheadSize = if (measuredOnce)
+                    measuredSize
+                else
+                    IntSize(Int.MIN_VALUE, Int.MIN_VALUE)
                 measuredOnce = true
                 val lookaheadDelegate = outerCoordinator.lookaheadDelegate
                 check(lookaheadDelegate != null) {
                     "Lookahead result from lookaheadRemeasure cannot be null"
                 }
 
-                // Copy out the previous size before perform lookahead measure
-                val lastLookaheadSize = IntSize(lookaheadDelegate.width, lookaheadDelegate.height)
                 performLookaheadMeasure(constraints)
                 measuredSize = IntSize(lookaheadDelegate.width, lookaheadDelegate.height)
                 val sizeChanged = lastLookaheadSize.width != lookaheadDelegate.width ||
@@ -1482,7 +1502,7 @@
      * has a lookahead root.
      */
     private fun LayoutNode.isOutMostLookaheadRoot(): Boolean =
-        lookaheadRoot != null && parent?.lookaheadRoot == null
+        lookaheadRoot != null && (parent?.lookaheadRoot == null || detachedFromParentLookaheadPass)
 
     /**
      * Performs measure with the given constraints and perform necessary state mutations before
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
index 4ebfe68..4e2ee0f 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutTreeConsistencyChecker.kt
@@ -65,6 +65,7 @@
             // remeasure or relayout is scheduled
             if (measurePending) {
                 return relayoutNodes.contains(this) ||
+                    layoutState == LayoutNode.LayoutState.LookaheadMeasuring ||
                     parent?.measurePending == true ||
                     parent?.lookaheadMeasurePending == true ||
                     parentLayoutState == LayoutNode.LayoutState.Measuring
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MyersDiff.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MyersDiff.kt
index 2721353..959cdf4 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MyersDiff.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/MyersDiff.kt
@@ -22,8 +22,8 @@
 
 internal interface DiffCallback {
     fun areItemsTheSame(oldIndex: Int, newIndex: Int): Boolean
-    fun insert(atIndex: Int, newIndex: Int)
-    fun remove(oldIndex: Int)
+    fun insert(newIndex: Int)
+    fun remove(atIndex: Int, oldIndex: Int)
     fun same(oldIndex: Int, newIndex: Int)
 }
 
@@ -104,45 +104,37 @@
 }
 
 private fun applyDiff(
-    oldSize: Int,
-    newSize: Int,
     diagonals: IntStack,
     callback: DiffCallback,
 ) {
-    var posX = oldSize
-    var posY = newSize
-    while (diagonals.isNotEmpty()) {
-        var i = diagonals.pop() // diagonal size
-        val endY = diagonals.pop()
-        val endX = diagonals.pop()
-        while (posX > endX) {
-            posX--
-            callback.remove(posX)
+    var posX = 0
+    var posY = 0
+    var i = 0
+
+    while (i < diagonals.size) {
+        val startX = diagonals[i] - diagonals[i + 2]
+        val startY = diagonals[i + 1] - diagonals[i + 2]
+        var len = diagonals[i + 2] // diagonal size
+        i += 3
+        while (posX < startX) {
+            callback.remove(posY, posX)
+            posX++
         }
-        while (posY > endY) {
-            posY--
-            callback.insert(posX, posY)
+        while (posY < startY) {
+            callback.insert(posY)
+            posY++
         }
-        while (i-- > 0) {
-            posX--
-            posY--
+        while (len-- > 0) {
             callback.same(posX, posY)
+            posX++
+            posY++
         }
     }
-    // the last remaining diagonals are just remove/insert until we hit zero
-    while (posX > 0) {
-        posX--
-        callback.remove(posX)
-    }
-    while (posY > 0) {
-        posY--
-        callback.insert(posX, posY)
-    }
 }
 
 internal fun executeDiff(oldSize: Int, newSize: Int, callback: DiffCallback) {
     val diagonals = calculateDiff(oldSize, newSize, callback)
-    applyDiff(oldSize, newSize, diagonals, callback)
+    applyDiff(diagonals, callback)
 }
 
 /**
@@ -420,6 +412,9 @@
     private var stack = IntArray(initialCapacity)
     private var lastIndex = 0
 
+    operator fun get(index: Int): Int = stack[index]
+    val size: Int get() = lastIndex
+
     fun pushRange(
         oldStart: Int,
         oldEnd: Int,
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
index c48e1d8..f6a0aea 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
@@ -49,20 +49,33 @@
         this.logger = logger
     }
 
-    private fun padChain() {
-        check(head !== SentinelHead) { "padChain encountered an invalid head" }
+    /**
+     * Takes the current "head" of the chain and adds a sentinel node as its parent in order to make
+     * the diffing process a bit easier to work with. This function will return the new "sentinel
+     * head", and keep [head] pointing to the actual head.
+     *
+     * TODO: Now that we run the diff from head to tail, this may not be as helpful as it once was.
+     *  Consider removing this and trimChain entirely. If we don't, we should at least refactor to
+     *  make SentinelHead not a shared global mutable object, and instead just allocate one per
+     *  owner or one per chain.
+     */
+    private fun padChain(): Modifier.Node {
+        check(head !== SentinelHead) { "padChain called on already padded chain" }
         val currentHead = head
         currentHead.parent = SentinelHead
         SentinelHead.child = currentHead
-        head = SentinelHead
+        return SentinelHead
     }
 
-    private fun trimChain() {
-        check(head === SentinelHead) { "trimChain encountered an invalid head" }
-        head = SentinelHead.child ?: tail
-        head.parent = null
+    private fun trimChain(paddedHead: Modifier.Node): Modifier.Node {
+        check(paddedHead === SentinelHead) { "trimChain called on already trimmed chain" }
+        val result = SentinelHead.child ?: tail
+        result.parent = null
         SentinelHead.child = null
-        check(head !== SentinelHead) { "trimChain did not update the head" }
+        SentinelHead.aggregateChildKindSet = 0.inv()
+        SentinelHead.updateCoordinator(null)
+        check(result !== SentinelHead) { "trimChain did not update the head" }
+        return result
     }
 
     /**
@@ -79,10 +92,6 @@
      * insertions and deletions.
      */
     internal fun updateFrom(m: Modifier) {
-        // If we run the diff and there are no new nodes created, then we don't need to loop through
-        // and run the attach cycle on them. We simply keep track of this during the diff to avoid
-        // this overhead at the end if we can, since it should be fairly common.
-        var attachNeeded = false
         // If we run the diff and there are no structural changes, we can avoid looping through the
         // list and updating the coordinators. We simply keep track of this during the diff to avoid
         // this overhead at the end if we can, since it should be fairly common. Note that this is
@@ -93,147 +102,124 @@
         // Use the node chain itself as a head/tail temporarily to prevent pruning the linkedlist
         // to the point where we don't have reference to it. We need to undo this at the end of
         // this method.
-        padChain()
+        val paddedHead = padChain()
         // to avoid allocating vectors every time modifier is set, we have two vectors that we
         // reuse over time. Since the common case is the modifier chains will be of equal length,
-        // these vectors should be sized appropriately
-        val before = current ?: MutableVector(capacity = 0)
+        // these vectors should be sized appropriately. The "before" list is nullable, since many
+        // layout nodes will never have modifier set more than once, so we avoid allocating the
+        // vector in those cases.
+        var before = current
+        val beforeSize = before?.size ?: 0
         val after = m.fillVector(buffer ?: mutableVectorOf())
-        if (after.size == before.size) {
+        var i = 0
+        if (after.size == beforeSize) {
             // assume if the sizes are the same, that we are in a common case of no structural
             // changes we will attempt an O(n) fast-path diff and exit if a diff is detected, and
             // do the O(N^2) diff beyond that point
-            val size = before.size
-            // for the linear diff we want to start with the "unpadded" tail
-            var node: Modifier.Node? = tail.parent
-            var i = size - 1
-            var aggregateChildKindSet = 0
-            while (node != null && i >= 0) {
+            // NOTE: we do not need to sync coordinators here since if any modifiers are added or
+            // removed we will break into a structural update.
+            var node: Modifier.Node? = paddedHead.child
+            while (node != null && i < beforeSize) {
+                checkNotNull(before) { "expected prior modifier list to be non-empty" }
                 val prev = before[i]
                 val next = after[i]
                 when (actionForModifiers(prev, next)) {
                     ActionReplace -> {
-                        // TODO(lmr): we could avoid running the diff if i = 0, since that would
-                        //  always be simple remove + insert
                         // structural change!
                         // back up one for the structural diff algorithm. This should be safe since
                         // our chain is padded with the EmptyHead/EmptyTail nodes
                         logger?.linearDiffAborted(i, prev, next, node)
-                        i++
-                        node = node.child
+                        node = node.parent
                         break
                     }
                     ActionUpdate -> {
                         // this is "the same" modifier, but some things have changed so we want to
                         // reuse the node but also update it
-                        val beforeUpdate = node
-                        node = updateNode(prev, next, beforeUpdate)
-                        logger?.nodeUpdated(i, i, prev, next, beforeUpdate, node)
+                        updateNode(prev, next, node)
+                        logger?.nodeUpdated(i, i, prev, next, node)
                     }
                     ActionReuse -> {
                         logger?.nodeReused(i, i, prev, next, node)
                         // no need to do anything, this is "the same" modifier
                     }
                 }
-                // if the node is new, we need to run attach on it
-                if (!node.isAttached) attachNeeded = true
-
-                aggregateChildKindSet = aggregateChildKindSet or node.kindSet
-                node.aggregateChildKindSet = aggregateChildKindSet
-
-                node = node.parent
-                i--
+                // NOTE: We do not need to check if the node is attached since these are all updated
+                // or reused modifiers only
+                node = node.child
+                i++
             }
-
-            if (i > 0) {
-                checkNotNull(node) { "structuralUpdate requires a non-null tail" }
-                attachNeeded = true
+            if (i < beforeSize) {
                 coordinatorSyncNeeded = true
+                checkNotNull(before) { "expected prior modifier list to be non-empty" }
+                checkNotNull(node) { "structuralUpdate requires a non-null tail" }
                 // there must have been a structural change
-                // we only need to diff what is left of the list, so we use `i` as the "beforeSize"
-                // and "afterSize"
+                // we only need to diff what is left of the list, so we use `i` to determine how
+                // much of the list is left.
                 structuralUpdate(
+                    i,
                     before,
-                    i,
                     after,
-                    i,
-                    // its important that the node we pass in here has an accurate
-                    // "aggregateChildMask"
                     node,
+                    layoutNode.isAttached,
                 )
             }
-        } else if (before.size == 0) {
+        } else if (!layoutNode.isAttached && beforeSize == 0) {
             // common case where we are initializing the chain and the previous size is zero. In
             // this case we just do all inserts. Since this is so common, we add a fast path here
-            // for this condition.
-            attachNeeded = true
+            // for this condition. Since the layout node is not attached, the inserted nodes will
+            // not get eagerly attached, which means we can avoid dealing with the coordinator sync
+            // until the end, which keeps this code path much simpler.
             coordinatorSyncNeeded = true
-            var i = after.size - 1
-            var aggregateChildKindSet = 0
-            var node = tail
-            while (i >= 0) {
+            var node = paddedHead
+            while (i < after.size) {
                 val next = after[i]
-                val child = node
-                node = createAndInsertNodeAsParent(next, child)
-                logger?.nodeInserted(0, i, next, child, node)
-                aggregateChildKindSet = aggregateChildKindSet or node.kindSet
-                node.aggregateChildKindSet = aggregateChildKindSet
-                i--
+                val parent = node
+                node = createAndInsertNodeAsChild(next, parent)
+                logger?.nodeInserted(0, i, next, parent, node)
+                i++
             }
+            syncAggregateChildKindSet()
         } else if (after.size == 0) {
+            checkNotNull(before) { "expected prior modifier list to be non-empty" }
             // common case where we we are removing all the modifiers.
-            coordinatorSyncNeeded = true
-            var i = before.size - 1
-            // for the linear traversal we want to start with the "unpadded" tail
-            var node: Modifier.Node? = tail.parent
-            while (node != null && i >= 0) {
+            var node = paddedHead.child
+            while (node != null && i < before.size) {
                 logger?.nodeRemoved(i, before[i], node)
-                val parent = node.parent
-                detachAndRemoveNode(node)
-                node = parent
-                i--
+                node = detachAndRemoveNode(node).child
+                i++
             }
+            innerCoordinator.wrappedBy = layoutNode.parent?.innerCoordinator
+            outerCoordinator = innerCoordinator
         } else {
-            attachNeeded = true
             coordinatorSyncNeeded = true
+            before = before ?: MutableVector()
             structuralUpdate(
+                0,
                 before,
-                before.size,
                 after,
-                after.size,
-                tail,
+                paddedHead,
+                layoutNode.isAttached,
             )
         }
         current = after
         // clear the before vector to allow old modifiers to be Garbage Collected
-        buffer = before.also { it.clear() }
-        trimChain()
-
+        buffer = before?.also { it.clear() }
+        head = trimChain(paddedHead)
         if (coordinatorSyncNeeded) {
             syncCoordinators()
         }
-        if (attachNeeded && layoutNode.isAttached) {
-            attach()
-        }
     }
 
+    /**
+     * This will "reset" all of the nodes in the chain. This includes both calling the reset
+     * lifecycles, calling the detach lifecycles, and calling [markAsDetached].
+     */
     internal fun resetState() {
-        val current = current
-        if (current == null) {
-            // We have no modifiers set so there is nothing to reset.
-            return
+        tailToHead {
+            if (it.isAttached) it.reset()
         }
-        val size = current.size
-        var node: Modifier.Node? = tail.parent
-        var i = size - 1
-        while (node != null && i >= 0) {
-            if (node.isAttached) {
-                node.reset()
-                node.detach()
-            }
-            node = node.parent
-            i--
-        }
+        runDetachLifecycle()
+        markAsDetached()
     }
 
     fun syncCoordinators() {
@@ -265,22 +251,54 @@
         outerCoordinator = coordinator
     }
 
-    fun attach() {
+    /**
+     * Ensures that the current []aggregateChildKindSet] value for each of the modifier nodes are
+     * set correctly. We must do this after every diff where a node was inserted or deleted. We can
+     * safely avoid it in the (relatively common) case of the chain getting updated but not changing
+     * structurally.
+     */
+    private fun syncAggregateChildKindSet() {
+        var node: Modifier.Node? = tail.parent
+        var aggregateChildKindSet = 0
+        while (node != null && node !== SentinelHead) {
+            aggregateChildKindSet = aggregateChildKindSet or node.kindSet
+            node.aggregateChildKindSet = aggregateChildKindSet
+            node = node.parent
+        }
+    }
+
+    /**
+     * Runs through all nodes in the chain and calls [markAsAttached]. This will ensure that the
+     * node has a coordinator and is marked as attached, but the node will not yet be notified that
+     * this happened. As a result, [runAttachLifecycle] is expected to be called afterwards to
+     * notify the node that it is attached. These are separated to ensure that when the attach
+     * lifecycle is called, all nodes in the hierarchy are marked as attached.
+     */
+    fun markAsAttached() {
         headToTail {
-            if (!it.isAttached) {
-                it.attach()
-                if (it.insertedNodeAwaitingAttachForInvalidation) {
-                    autoInvalidateInsertedNode(it)
-                }
-                if (it.updatedNodeAwaitingAttachForInvalidation) {
-                    autoInvalidateUpdatedNode(it)
-                }
-                // when we attach with performInvalidations == false no separate
-                // invalidations needed as the whole LayoutNode is attached to the tree.
-                // it will cause all the needed invalidations.
-                it.insertedNodeAwaitingAttachForInvalidation = false
-                it.updatedNodeAwaitingAttachForInvalidation = false
+            it.markAsAttached()
+        }
+    }
+
+    /**
+     * Runs through all nodes in the chain and calls the attach lifecycle. It also runs
+     * invalidations as a result of the attach, if needed.
+     */
+    fun runAttachLifecycle() {
+        headToTail {
+            it.runAttachLifecycle()
+            if (it.insertedNodeAwaitingAttachForInvalidation) {
+                autoInvalidateInsertedNode(it)
             }
+            if (it.updatedNodeAwaitingAttachForInvalidation) {
+                autoInvalidateUpdatedNode(it)
+            }
+            // when we attach with performInvalidations == false no separate
+            // invalidations needed as the whole LayoutNode is attached to the tree.
+            // it will cause all the needed invalidations.
+            // TODO: can we get rid of these now?
+            it.insertedNodeAwaitingAttachForInvalidation = false
+            it.updatedNodeAwaitingAttachForInvalidation = false
         }
     }
 
@@ -326,84 +344,128 @@
         return infoList.asMutableList()
     }
 
-    internal fun detach() {
-        // NOTE(lmr): Currently this implementation allows for nodes to be
-        // attached/detached/attached. We need to decide if that's what we want. If we
-        // don't, the commented out implementation below it might be better.
+    internal fun markAsDetached() {
         tailToHead {
-            if (it.isAttached) it.detach()
+            if (it.isAttached) it.markAsDetached()
         }
-//        tailToHead {
-//            if (it.isAttached) it.detach()
-//            it.child?.parent = null
-//            it.child = null
-//        }
-//        current?.clear()
+    }
+
+    internal fun runDetachLifecycle() {
+        tailToHead {
+            if (it.isAttached) it.runDetachLifecycle()
+        }
     }
 
     private fun getDiffer(
-        tail: Modifier.Node,
+        head: Modifier.Node,
+        offset: Int,
         before: MutableVector<Modifier.Element>,
         after: MutableVector<Modifier.Element>,
+        shouldAttachOnInsert: Boolean,
     ): Differ {
         val current = cachedDiffer
         @Suppress("IfThenToElvis")
         return if (current == null) {
             Differ(
-                tail,
-                tail.aggregateChildKindSet,
+                head,
+                offset,
                 before,
                 after,
+                // TODO: is this always true?
+                shouldAttachOnInsert,
             ).also { cachedDiffer = it }
         } else {
             current.also {
-                it.node = tail
-                it.aggregateChildKindSet = tail.aggregateChildKindSet
+                it.node = head
+                it.offset = offset
                 it.before = before
                 it.after = after
+                it.shouldAttachOnInsert = shouldAttachOnInsert
             }
         }
     }
 
+    private fun propagateCoordinator(start: Modifier.Node, coordinator: NodeCoordinator) {
+        var node = start.parent
+        while (node != null) {
+            if (node === SentinelHead) {
+                coordinator.wrappedBy = layoutNode.parent?.innerCoordinator
+                outerCoordinator = coordinator
+                break
+            }
+            if (node.isKind(Nodes.Layout)) break
+            node.updateCoordinator(coordinator)
+            node = node.parent
+        }
+    }
+
     private inner class Differ(
         var node: Modifier.Node,
-        var aggregateChildKindSet: Int,
+        var offset: Int,
         var before: MutableVector<Modifier.Element>,
         var after: MutableVector<Modifier.Element>,
+        var shouldAttachOnInsert: Boolean,
     ) : DiffCallback {
         override fun areItemsTheSame(oldIndex: Int, newIndex: Int): Boolean {
-            return actionForModifiers(before[oldIndex], after[newIndex]) != ActionReplace
+            return actionForModifiers(
+                before[offset + oldIndex],
+                after[offset + newIndex]
+            ) != ActionReplace
         }
 
-        override fun insert(atIndex: Int, newIndex: Int) {
-            val child = node
-            node = createAndInsertNodeAsParent(after[newIndex], child)
-            check(!node.isAttached) { "createAndInsertNodeAsParent called on an attached node" }
-            node.insertedNodeAwaitingAttachForInvalidation = true
-            logger?.nodeInserted(atIndex, newIndex, after[newIndex], child, node)
-            aggregateChildKindSet = aggregateChildKindSet or node.kindSet
-            node.aggregateChildKindSet = aggregateChildKindSet
+        override fun insert(newIndex: Int) {
+            val index = offset + newIndex
+            val parent = node
+            node = createAndInsertNodeAsChild(after[index], parent)
+            logger?.nodeInserted(index, index, after[index], parent, node)
+
+            if (shouldAttachOnInsert) {
+                val childCoordinator = node.child!!.coordinator!!
+                val layoutmod = node.asLayoutModifierNode()
+                if (layoutmod != null) {
+                    val thisCoordinator = LayoutModifierNodeCoordinator(layoutNode, layoutmod)
+                    node.updateCoordinator(thisCoordinator)
+                    propagateCoordinator(node, thisCoordinator)
+                    thisCoordinator.wrappedBy = childCoordinator.wrappedBy
+                    thisCoordinator.wrapped = childCoordinator
+                    childCoordinator.wrappedBy = thisCoordinator
+                } else {
+                    node.updateCoordinator(childCoordinator)
+                }
+                node.markAsAttached()
+                node.runAttachLifecycle()
+                autoInvalidateInsertedNode(node)
+            } else {
+                node.insertedNodeAwaitingAttachForInvalidation = true
+            }
         }
 
-        override fun remove(oldIndex: Int) {
-            node = node.parent!!
-            logger?.nodeRemoved(oldIndex, before[oldIndex], node)
-            node = detachAndRemoveNode(node)
+        override fun remove(atIndex: Int, oldIndex: Int) {
+            val toRemove = node.child!!
+            logger?.nodeRemoved(oldIndex, before[offset + oldIndex], toRemove)
+            if (toRemove.isKind(Nodes.Layout)) {
+                val removedCoordinator = toRemove.coordinator!!
+                // parent might be null
+                val parentCoordinator = removedCoordinator.wrappedBy
+                // child should never be null because of innerCoordinator
+                val childCoordinator = removedCoordinator.wrapped!!
+                parentCoordinator?.wrapped = childCoordinator
+                childCoordinator.wrappedBy = parentCoordinator
+                propagateCoordinator(node, childCoordinator)
+            }
+            node = detachAndRemoveNode(toRemove)
         }
 
         override fun same(oldIndex: Int, newIndex: Int) {
-            node = node.parent!!
-            val prev = before[oldIndex]
-            val next = after[newIndex]
+            node = node.child!!
+            val prev = before[offset + oldIndex]
+            val next = after[offset + newIndex]
             if (prev != next) {
-                val beforeUpdate = node
-                node = updateNode(prev, next, beforeUpdate)
-                logger?.nodeUpdated(oldIndex, newIndex, prev, next, beforeUpdate, node)
+                updateNode(prev, next, node)
+                logger?.nodeUpdated(offset + oldIndex, offset + newIndex, prev, next, node)
             } else {
-                logger?.nodeReused(oldIndex, newIndex, prev, next, node)
+                logger?.nodeReused(offset + oldIndex, offset + newIndex, prev, next, node)
             }
-            aggregateChildKindSet = aggregateChildKindSet or node.kindSet
-            node.aggregateChildKindSet = aggregateChildKindSet
         }
     }
 
@@ -420,8 +482,7 @@
             newIndex: Int,
             prev: Modifier.Element,
             next: Modifier.Element,
-            before: Modifier.Node,
-            after: Modifier.Node
+            node: Modifier.Node,
         )
 
         fun nodeReused(
@@ -457,47 +518,15 @@
      * expected to have an up to date [aggregateChildKindSet].
      */
     private fun structuralUpdate(
+        offset: Int,
         before: MutableVector<Modifier.Element>,
-        beforeSize: Int,
         after: MutableVector<Modifier.Element>,
-        afterSize: Int,
         tail: Modifier.Node,
+        shouldAttachOnInsert: Boolean,
     ) {
-        executeDiff(beforeSize, afterSize, getDiffer(tail, before, after))
-    }
-
-    /**
-     * This method takes [prev] in the current linked list, and swaps it with [next], ensuring that
-     * all the parent/child relationships are maintained.
-     *
-     * For example:
-     *
-     *      Head... -> parent -> prev -> child -> ...Tail
-     *
-     *  gets transformed into a list of the following shape:
-     *
-     *      Head... -> parent -> next -> child -> ...Tail
-     *
-     * @return This method returns the updated [next] node, for convenience
-     */
-    private fun replaceNode(prev: Modifier.Node, next: Modifier.Node): Modifier.Node {
-        val parent = prev.parent
-        if (parent != null) {
-            next.parent = parent
-            parent.child = next
-            prev.parent = null
-        }
-        val child = prev.child
-        if (child != null) {
-            next.child = child
-            child.parent = next
-            prev.child = null
-        }
-        // NOTE: it is important that during a "replace", we keep the same coordinator as before
-        //  as there is a chance that at the end of the diff we won't iterate through the chain and
-        //  update all of the coordinators assuming there were no structural changes detected
-        next.updateCoordinator(prev.coordinator)
-        return next
+        val differ = getDiffer(tail, offset, before, after, shouldAttachOnInsert)
+        executeDiff(before.size - offset, after.size - offset, differ)
+        syncAggregateChildKindSet()
     }
 
     private fun detachAndRemoveNode(node: Modifier.Node): Modifier.Node {
@@ -506,7 +535,8 @@
             // regardless of whether or not it was a ModifierNodeElement with autoInvalidate
             // true, or a BackwardsCompatNode, etc.
             autoInvalidateRemovedNode(node)
-            node.detach()
+            node.runDetachLifecycle()
+            node.markAsDetached()
         }
         return removeNode(node)
     }
@@ -521,7 +551,7 @@
      *
      *      Head... -> parent -> child -> ...Tail
      *
-     *  @return The child of the removed [node]
+     *  @return The parent of the removed [node]
      */
     private fun removeNode(node: Modifier.Node): Modifier.Node {
         val child = node.child
@@ -534,7 +564,7 @@
             parent.child = child
             node.parent = null
         }
-        return child!!
+        return parent!!
     }
 
     private fun createAndInsertNodeAsParent(
@@ -575,11 +605,51 @@
         return node
     }
 
+    private fun createAndInsertNodeAsChild(
+        element: Modifier.Element,
+        parent: Modifier.Node,
+    ): Modifier.Node {
+        val node = when (element) {
+            is ModifierNodeElement<*> -> element.create().also {
+                it.kindSet = calculateNodeKindSetFromIncludingDelegates(it)
+            }
+            else -> BackwardsCompatNode(element)
+        }
+        check(!node.isAttached) {
+            "A ModifierNodeElement cannot return an already attached node from create() "
+        }
+        node.insertedNodeAwaitingAttachForInvalidation = true
+        return insertChild(node, parent)
+    }
+
+    /**
+     * This inserts [node] as the child of [parent] in the current linked list.
+     * For example:
+     *
+     *      Head... -> parent -> ...Tail
+     *
+     *  gets transformed into a list of the following shape:
+     *
+     *      Head... -> parent -> node -> ...Tail
+     *
+     *  @return The inserted [node]
+     */
+    private fun insertChild(node: Modifier.Node, parent: Modifier.Node): Modifier.Node {
+        val theChild = parent.child
+        if (theChild != null) {
+            theChild.parent = node
+            node.child = theChild
+        }
+        parent.child = node
+        node.parent = parent
+        return node
+    }
+
     private fun updateNode(
         prev: Modifier.Element,
         next: Modifier.Element,
         node: Modifier.Node
-    ): Modifier.Node {
+    ) {
         when {
             prev is ModifierNodeElement<*> && next is ModifierNodeElement<*> -> {
                 next.updateUnsafe(node)
@@ -591,7 +661,6 @@
                 } else {
                     node.updatedNodeAwaitingAttachForInvalidation = true
                 }
-                return node
             }
             node is BackwardsCompatNode -> {
                 node.element = next
@@ -601,7 +670,6 @@
                 } else {
                     node.updatedNodeAwaitingAttachForInvalidation = true
                 }
-                return node
             }
             else -> error("Unknown Modifier.Node type")
         }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
index 0c04a09..31c7c4c 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeKind.kt
@@ -286,7 +286,7 @@
             else -> node.invalidateFocusProperties()
         }
     }
-    if (Nodes.FocusEvent in selfKindSet && node is FocusEventModifierNode && phase != Removed) {
+    if (Nodes.FocusEvent in selfKindSet && node is FocusEventModifierNode) {
         node.invalidateFocusEvent()
     }
 }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
index 8426062..25b5cd5 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
@@ -59,10 +59,7 @@
  * to go moving APIs around now if we might change them anyway. b/230369229 tracks cleaning up this
  * clipboard inheritance.
  */
-internal suspend fun <R> withInfiniteAnimationFrameNanos(
-    @Suppress("PrimitiveInLambda")
-    onFrame: (frameTimeNanos: Long) -> R
-): R =
+internal suspend fun <R> withInfiniteAnimationFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R =
     when (val policy = coroutineContext[InfiniteAnimationPolicy]) {
         null -> withFrameNanos(onFrame)
         else -> policy.onInfiniteOperation { withFrameNanos(onFrame) }
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 eb7967b..96d0e6b 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
@@ -249,7 +249,6 @@
     /**
      * @see SemanticsPropertyReceiver.indexForKey
      */
-    @Suppress("PrimitiveInLambda")
     val IndexForKey = SemanticsPropertyKey<(Any) -> Int>("IndexForKey")
 }
 
@@ -281,25 +280,21 @@
     /**
      * @see SemanticsPropertyReceiver.scrollBy
      */
-    @Suppress("PrimitiveInLambda")
     val ScrollBy = ActionPropertyKey<(x: Float, y: Float) -> Boolean>("ScrollBy")
 
     /**
      * @see SemanticsPropertyReceiver.scrollToIndex
      */
-    @Suppress("PrimitiveInLambda")
     val ScrollToIndex = ActionPropertyKey<(Int) -> Boolean>("ScrollToIndex")
 
     /**
      * @see SemanticsPropertyReceiver.setProgress
      */
-    @Suppress("PrimitiveInLambda")
     val SetProgress = ActionPropertyKey<(progress: Float) -> Boolean>("SetProgress")
 
     /**
      * @see SemanticsPropertyReceiver.setSelection
      */
-    @Suppress("PrimitiveInLambda")
     val SetSelection = ActionPropertyKey<(Int, Int, Boolean) -> Boolean>("SetSelection")
 
     /**
@@ -622,9 +617,7 @@
  * mean bottom, when `false`, 0 [value] will mean top
  */
 class ScrollAxisRange(
-    @Suppress("PrimitiveInLambda")
     val value: () -> Float,
-    @Suppress("PrimitiveInLambda")
     val maxValue: () -> Float,
     val reverseScrolling: Boolean = false
 ) {
@@ -1032,10 +1025,7 @@
  * The index of an item identified by a given key. The key is usually defined during the creation
  * of the container. If the key did not match any of the items' keys, the [mapping] must return -1.
  */
-fun SemanticsPropertyReceiver.indexForKey(
-    @Suppress("PrimitiveInLambda")
-    mapping: (Any) -> Int
-) {
+fun SemanticsPropertyReceiver.indexForKey(mapping: (Any) -> Int) {
     this[SemanticsProperties.IndexForKey] = mapping
 }
 
@@ -1102,7 +1092,6 @@
  */
 fun SemanticsPropertyReceiver.scrollBy(
     label: String? = null,
-    @Suppress("PrimitiveInLambda")
     action: ((x: Float, y: Float) -> Boolean)?
 ) {
     this[SemanticsActions.ScrollBy] = AccessibilityAction(label, action)
@@ -1115,7 +1104,6 @@
  */
 fun SemanticsPropertyReceiver.scrollToIndex(
     label: String? = null,
-    @Suppress("PrimitiveInLambda")
     action: (Int) -> Boolean
 ) {
     this[SemanticsActions.ScrollToIndex] = AccessibilityAction(label, action)
@@ -1129,11 +1117,7 @@
  * @param label Optional label for this action.
  * @param action Action to be performed when the [SemanticsActions.SetProgress] is called.
  */
-fun SemanticsPropertyReceiver.setProgress(
-    label: String? = null,
-    @Suppress("PrimitiveInLambda")
-    action: ((Float) -> Boolean)?
-) {
+fun SemanticsPropertyReceiver.setProgress(label: String? = null, action: ((Float) -> Boolean)?) {
     this[SemanticsActions.SetProgress] = AccessibilityAction(label, action)
 }
 
@@ -1253,7 +1237,6 @@
  */
 fun SemanticsPropertyReceiver.setSelection(
     label: String? = null,
-    @Suppress("PrimitiveInLambda")
     action: ((startIndex: Int, endIndex: Int, relativeToOriginalText: Boolean) -> Boolean)?
 ) {
     this[SemanticsActions.SetSelection] = AccessibilityAction(label, action)
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
index 793d11e..9b88092 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
@@ -609,7 +609,8 @@
         assert(c.node === a)
 
         // detached now, nodes should still point to a
-        chain.detach()
+        chain.runDetachLifecycle()
+        chain.markAsDetached()
 
         assert(!a.isAttached)
         assert(!b.isAttached)
@@ -619,7 +620,8 @@
         assert(b.node === a)
         assert(c.node === a)
 
-        chain.attach()
+        chain.markAsAttached()
+        chain.runAttachLifecycle()
 
         // attached now, nodes should still point to a
         assert(a.isAttached)
@@ -672,7 +674,8 @@
         assert(a.node === a)
         assert(b.node === a)
 
-        chain.detach()
+        chain.runDetachLifecycle()
+        chain.markAsDetached()
 
         // detached AND undelegated now
         assert(!a.isAttached)
@@ -681,7 +684,8 @@
         assert(a.node === a)
         assert(b.node === b)
 
-        chain.attach()
+        chain.markAsAttached()
+        chain.runAttachLifecycle()
 
         // attached and delegated now
         assert(a.isAttached)
@@ -716,7 +720,8 @@
         assert(a.node === a)
         assert(b.node === a)
 
-        chain.detach()
+        chain.runDetachLifecycle()
+        chain.markAsDetached()
 
         // detached now, still delegated
         assert(!a.isAttached)
@@ -725,7 +730,8 @@
         assert(a.node === a)
         assert(b.node === a)
 
-        chain.attach()
+        chain.markAsAttached()
+        chain.runAttachLifecycle()
 
         // attached, still delegated
         assert(a.isAttached)
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
index 4fd72dc..c50568b 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/input/TextInputServiceAndroidCommandDebouncingTest.kt
@@ -17,6 +17,7 @@
 package androidx.compose.ui.text.input
 
 import android.view.View
+import android.view.inputmethod.CursorAnchorInfo
 import android.view.inputmethod.ExtractedText
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.Executor
@@ -270,6 +271,8 @@
         var showSoftInputCalls = 0
         var hideSoftInputCalls = 0
 
+        override fun isActive(): Boolean = true
+
         override fun restartInput() {
             restartCalls++
         }
@@ -292,5 +295,8 @@
             compositionEnd: Int
         ) {
         }
+
+        override fun updateCursorAnchorInfo(cursorAnchorInfo: CursorAnchorInfo) {
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle b/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
index 4412d11..7078017 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
+++ b/constraintlayout/constraintlayout-compose/integration-tests/demos/build.gradle
@@ -37,3 +37,4 @@
 android {
     namespace "androidx.constraintlayout.compose.demos"
 }
+
diff --git a/constraintlayout/constraintlayout-compose/lint-baseline.xml b/constraintlayout/constraintlayout-compose/lint-baseline.xml
index b08ac1e..32d1e09 100644
--- a/constraintlayout/constraintlayout-compose/lint-baseline.xml
+++ b/constraintlayout/constraintlayout-compose/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanInlineOptIn"
@@ -20,33 +20,6 @@
     </issue>
 
     <issue
-        id="IllegalExperimentalApiUsage"
-        message="`Experimental` and `RequiresOptIn` APIs may only be used within the same-version group where they were defined."
-        errorLine1="@OptIn(ExperimentalComposeUiApi::class)"
-        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/Motion.kt"/>
-    </issue>
-
-    <issue
-        id="IllegalExperimentalApiUsage"
-        message="`Experimental` and `RequiresOptIn` APIs may only be used within the same-version group where they were defined."
-        errorLine1="@OptIn(ExperimentalComposeUiApi::class)"
-        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/Motion.kt"/>
-    </issue>
-
-    <issue
-        id="IllegalExperimentalApiUsage"
-        message="`Experimental` and `RequiresOptIn` APIs may only be used within the same-version group where they were defined."
-        errorLine1="@OptIn(ExperimentalComposeApi::class)"
-        errorLine2="~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/androidMain/kotlin/androidx/constraintlayout/compose/TransitionHandler.kt"/>
-    </issue>
-
-    <issue
         id="ComposableLambdaParameterNaming"
         message="Composable lambda parameter should be named `content`"
         errorLine1="fun ItemHolder(i: Int, slotPrefix: String, showSlot: Boolean, function: @Composable () -> Unit) {"
@@ -73,4 +46,94 @@
             file="src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setThresholds$lint_module has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Float, Float, Float> of &apos;getThresholds$lint_module&apos;."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method computeTarget has parameter &apos;thresholds&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    thresholds: (Float, Float) -> Float,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable (index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsWithProperties has parameter &apos;itemContent&apos; with type Function2&lt;? super Integer, ? super State&lt;MotionProperties>, Unit>."
+        errorLine1="        itemContent: @Composable ("
+        errorLine2="                     ^">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setItemsProvider has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    var itemsProvider: @Composable ((index: Int) -> Unit)? = null"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Unit> of &apos;getItemsProvider&apos;."
+        errorLine1="    var itemsProvider: @Composable ((index: Int) -> Unit)? = null"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setItemsProviderWithProperties has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Integer, ? super State&lt;MotionProperties>, Unit>."
+        errorLine1="    var itemsProviderWithProperties: @Composable ((index: Int,"
+        errorLine2="    ^">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Integer, State&lt;MotionProperties>, Unit> of &apos;getItemsProviderWithProperties&apos;."
+        errorLine1="    var itemsProviderWithProperties: @Composable ((index: Int,"
+        errorLine2="                                     ^">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method fromState has parameter &apos;onUpdate&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="            onUpdate: (newProgress: Float) -> Unit"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt"/>
+    </issue>
+
 </issues>
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
index 592c3f2..61b5811 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
@@ -318,12 +318,11 @@
 interface MotionCarouselScope {
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable (index: Int) -> Unit
     )
 
     @OptIn(ExperimentalMotionApi::class)
-    @Suppress("UnavailableSymbol", "PrimitiveInLambda")
+    @Suppress("UnavailableSymbol")
     fun itemsWithProperties(
         count: Int,
         @Suppress("HiddenTypeParameter")
@@ -376,16 +375,13 @@
 private class MotionCarouselScopeImpl() : MotionCarouselScope, MotionItemsProvider {
 
     var itemsCount = 0
-    @Suppress("PrimitiveInLambda")
     var itemsProvider: @Composable ((index: Int) -> Unit)? = null
-    @Suppress("PrimitiveInLambda")
     var itemsProviderWithProperties: @Composable ((index: Int,
         properties: androidx.compose.runtime.State<MotionProperties>) -> Unit)? =
         null
 
     override fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable (index: Int) -> Unit
     ) {
         itemsCount = count
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
index 40590f8..d1aff18 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
@@ -1081,7 +1081,6 @@
 
         fun fromState(
             progressState: State<Float>,
-            @Suppress("PrimitiveInLambda")
             onUpdate: (newProgress: Float) -> Unit
         ): MotionProgress =
             object : MotionProgress {
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
index 57d2fbd..a0bb06f 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
@@ -187,7 +187,6 @@
         }
     }
 
-    @Suppress("PrimitiveInLambda")
     internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
 
     internal var velocityThreshold by mutableFloatStateOf(0f)
@@ -743,7 +742,6 @@
     offset: Float,
     lastValue: Float,
     anchors: Set<Float>,
-    @Suppress("PrimitiveInLambda")
     thresholds: (Float, Float) -> Float,
     velocity: Float,
     velocityThreshold: Float
diff --git a/constraintlayout/constraintlayout/api/api_lint.ignore b/constraintlayout/constraintlayout/api/api_lint.ignore
index 1f05e12..422e6ca 100644
--- a/constraintlayout/constraintlayout/api/api_lint.ignore
+++ b/constraintlayout/constraintlayout/api/api_lint.ignore
@@ -217,24 +217,6 @@
     Invalid nullability on parameter `target` in method `onNestedFling`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.constraintlayout.motion.widget.MotionLayout#onNestedPreFling(android.view.View, float, float) parameter #0:
     Invalid nullability on parameter `target` in method `onNestedPreFling`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.utils.widget.ImageFilterButton#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.utils.widget.ImageFilterView#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.utils.widget.MockView#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.utils.widget.MotionButton#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.utils.widget.MotionLabel#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.widget.ConstraintHelper#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.widget.Guideline#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.widget.Placeholder#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.constraintlayout.widget.ReactiveGuide#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 
 
 KotlinOperator: androidx.constraintlayout.motion.utils.ViewTimeCycle#get(float, long, android.view.View, androidx.constraintlayout.core.motion.utils.KeyCache):
@@ -349,6 +331,8 @@
     Missing nullability on method `getSpans` return
 MissingNullability: androidx.constraintlayout.helper.widget.Grid#init(android.util.AttributeSet) parameter #0:
     Missing nullability on parameter `attrs` in method `init`
+MissingNullability: androidx.constraintlayout.helper.widget.Grid#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.helper.widget.Grid#setColumnWeights(String) parameter #0:
     Missing nullability on parameter `columnWeights` in method `setColumnWeights`
 MissingNullability: androidx.constraintlayout.helper.widget.Grid#setRowWeights(String) parameter #0:
@@ -1089,6 +1073,8 @@
     Missing nullability on parameter `context` in method `ImageFilterButton`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterButton#ImageFilterButton(android.content.Context, android.util.AttributeSet, int) parameter #1:
     Missing nullability on parameter `attrs` in method `ImageFilterButton`
+MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterButton#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterButton#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
     Missing nullability on parameter `drawable` in method `setImageDrawable`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterView#ImageFilterView(android.content.Context) parameter #0:
@@ -1101,6 +1087,8 @@
     Missing nullability on parameter `context` in method `ImageFilterView`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterView#ImageFilterView(android.content.Context, android.util.AttributeSet, int) parameter #1:
     Missing nullability on parameter `attrs` in method `ImageFilterView`
+MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterView#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterView#setAltImageDrawable(android.graphics.drawable.Drawable) parameter #0:
     Missing nullability on parameter `altDrawable` in method `setAltImageDrawable`
 MissingNullability: androidx.constraintlayout.utils.widget.ImageFilterView#setImageDrawable(android.graphics.drawable.Drawable) parameter #0:
@@ -1117,6 +1105,8 @@
     Missing nullability on parameter `attrs` in method `MockView`
 MissingNullability: androidx.constraintlayout.utils.widget.MockView#mText:
     Missing nullability on field `mText` in class `class androidx.constraintlayout.utils.widget.MockView`
+MissingNullability: androidx.constraintlayout.utils.widget.MockView#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionButton#MotionButton(android.content.Context) parameter #0:
     Missing nullability on parameter `context` in method `MotionButton`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionButton#MotionButton(android.content.Context, android.util.AttributeSet) parameter #0:
@@ -1127,6 +1117,8 @@
     Missing nullability on parameter `context` in method `MotionButton`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionButton#MotionButton(android.content.Context, android.util.AttributeSet, int) parameter #1:
     Missing nullability on parameter `attrs` in method `MotionButton`
+MissingNullability: androidx.constraintlayout.utils.widget.MotionButton#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#MotionLabel(android.content.Context) parameter #0:
     Missing nullability on parameter `context` in method `MotionLabel`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#MotionLabel(android.content.Context, android.util.AttributeSet) parameter #0:
@@ -1135,6 +1127,8 @@
     Missing nullability on parameter `context` in method `MotionLabel`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#getTypeface():
     Missing nullability on method `getTypeface` return
+MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#setText(CharSequence) parameter #0:
     Missing nullability on parameter `text` in method `setText`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionLabel#setTypeface(android.graphics.Typeface) parameter #0:
@@ -1149,6 +1143,8 @@
     Missing nullability on parameter `context` in method `MotionTelltales`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionTelltales#MotionTelltales(android.content.Context, android.util.AttributeSet, int) parameter #1:
     Missing nullability on parameter `attrs` in method `MotionTelltales`
+MissingNullability: androidx.constraintlayout.utils.widget.MotionTelltales#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.utils.widget.MotionTelltales#setText(CharSequence) parameter #0:
     Missing nullability on parameter `text` in method `setText`
 MissingNullability: androidx.constraintlayout.widget.Barrier#Barrier(android.content.Context) parameter #0:
@@ -1267,6 +1263,8 @@
     Missing nullability on field `mReferenceTags` in class `class androidx.constraintlayout.widget.ConstraintHelper`
 MissingNullability: androidx.constraintlayout.widget.ConstraintHelper#myContext:
     Missing nullability on field `myContext` in class `class androidx.constraintlayout.widget.ConstraintHelper`
+MissingNullability: androidx.constraintlayout.widget.ConstraintHelper#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.widget.ConstraintHelper#removeView(android.view.View) parameter #0:
     Missing nullability on parameter `view` in method `removeView`
 MissingNullability: androidx.constraintlayout.widget.ConstraintHelper#resolveRtl(androidx.constraintlayout.core.widgets.ConstraintWidget, boolean) parameter #0:
@@ -1713,6 +1711,8 @@
     Missing nullability on parameter `context` in method `Guideline`
 MissingNullability: androidx.constraintlayout.widget.Guideline#Guideline(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
     Missing nullability on parameter `attrs` in method `Guideline`
+MissingNullability: androidx.constraintlayout.widget.Guideline#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.constraintlayout.widget.Placeholder#Placeholder(android.content.Context) parameter #0:
     Missing nullability on parameter `context` in method `Placeholder`
 MissingNullability: androidx.constraintlayout.widget.Placeholder#Placeholder(android.content.Context, android.util.AttributeSet) parameter #0:
@@ -1729,6 +1729,8 @@
     Missing nullability on parameter `attrs` in method `Placeholder`
 MissingNullability: androidx.constraintlayout.widget.Placeholder#getContent():
     Missing nullability on method `getContent` return
+MissingNullability: androidx.constraintlayout.widget.Placeholder#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.constraintlayout.widget.Placeholder#updatePostMeasure(androidx.constraintlayout.widget.ConstraintLayout) parameter #0:
     Missing nullability on parameter `container` in method `updatePostMeasure`
 MissingNullability: androidx.constraintlayout.widget.Placeholder#updatePreLayout(androidx.constraintlayout.widget.ConstraintLayout) parameter #0:
@@ -1747,6 +1749,8 @@
     Missing nullability on parameter `context` in method `ReactiveGuide`
 MissingNullability: androidx.constraintlayout.widget.ReactiveGuide#ReactiveGuide(android.content.Context, android.util.AttributeSet, int, int) parameter #1:
     Missing nullability on parameter `attrs` in method `ReactiveGuide`
+MissingNullability: androidx.constraintlayout.widget.ReactiveGuide#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.constraintlayout.widget.SharedValues#addListener(int, androidx.constraintlayout.widget.SharedValues.SharedValuesListener) parameter #1:
     Missing nullability on parameter `listener` in method `addListener`
 MissingNullability: androidx.constraintlayout.widget.SharedValues#removeListener(androidx.constraintlayout.widget.SharedValues.SharedValuesListener) parameter #0:
diff --git a/constraintlayout/constraintlayout/lint-baseline.xml b/constraintlayout/constraintlayout/lint-baseline.xml
index 6f8af38..a9b5204 100644
--- a/constraintlayout/constraintlayout/lint-baseline.xml
+++ b/constraintlayout/constraintlayout/lint-baseline.xml
@@ -5332,6 +5332,15 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/constraintlayout/widget/ConstraintLayout.java"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public void setOnConstraintsChanged(ConstraintsChangedListener constraintsChangedListener) {"
         errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
@@ -9247,6 +9256,15 @@
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected void dispatchDraw(Canvas canvas) {"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/constraintlayout/motion/widget/MotionLayout.java"/>
+    </issue>
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
         errorLine1="    public void setScene(MotionScene scene) {"
         errorLine2="                         ~~~~~~~~~~~">
         <location
diff --git a/coordinatorlayout/coordinatorlayout/api/api_lint.ignore b/coordinatorlayout/coordinatorlayout/api/api_lint.ignore
index f200680..06d3c6e 100644
--- a/coordinatorlayout/coordinatorlayout/api/api_lint.ignore
+++ b/coordinatorlayout/coordinatorlayout/api/api_lint.ignore
@@ -1,6 +1,4 @@
 // Baseline format: 1.0
-InvalidNullabilityOverride: androidx.coordinatorlayout.widget.CoordinatorLayout#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #0:
     Invalid nullability on parameter `target` in method `onNestedPreScroll`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedPreScroll(android.view.View, int, int, int[]) parameter #3:
@@ -35,6 +33,8 @@
     Missing nullability on method `generateLayoutParams` return
 MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
     Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
 MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
 MissingNullability: androidx.coordinatorlayout.widget.CoordinatorLayout#onNestedFling(android.view.View, float, float, boolean) parameter #0:
diff --git a/coordinatorlayout/coordinatorlayout/lint-baseline.xml b/coordinatorlayout/coordinatorlayout/lint-baseline.xml
index eb4748e..b3144af 100644
--- a/coordinatorlayout/coordinatorlayout/lint-baseline.xml
+++ b/coordinatorlayout/coordinatorlayout/lint-baseline.xml
@@ -1,5 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
+<issues format="6" by="lint 8.0.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-alpha07)" variant="all" version="8.0.0-alpha07">
+
+    <issue
+        id="UnknownNullness"
+        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
+        errorLine1="    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="src/main/java/androidx/coordinatorlayout/widget/CoordinatorLayout.java"/>
+    </issue>
 
     <issue
         id="UnknownNullness"
diff --git a/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java b/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
index 5da3a24..8a46af1 100644
--- a/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
+++ b/core/core-appdigest/src/androidTest/java/androidx/core/appdigest/ChecksumsTest.java
@@ -214,8 +214,8 @@
     }
 
     private static String executeShellCommand(String command) throws IOException {
-        if (Build.VERSION.SDK_INT >= 24) {
-            return InstallerApi24.executeShellCommand(command);
+        if (Build.VERSION.SDK_INT >= 29) {
+            return InstallerApi29.executeShellCommand(command);
         }
         return "";
     }
@@ -1022,8 +1022,8 @@
     }
 
     void installSplits(String[] names) throws Exception {
-        if (Build.VERSION.SDK_INT >= 24) {
-            new InstallerApi24(mContext).installSplits(names);
+        if (Build.VERSION.SDK_INT >= 29) {
+            new InstallerApi29(mContext).installSplits(names);
         }
     }
 
@@ -1035,17 +1035,17 @@
     }
 
     private boolean isAppInstalled(String packageName) throws IOException {
-        if (Build.VERSION.SDK_INT >= 24) {
-            return InstallerApi24.isAppInstalled(packageName);
+        if (Build.VERSION.SDK_INT >= 29) {
+            return InstallerApi29.isAppInstalled(packageName);
         }
         return false;
     }
 
-    @RequiresApi(24)
-    static class InstallerApi24 {
+    @RequiresApi(29)
+    static class InstallerApi29 {
         protected Context mContext;
 
-        InstallerApi24(Context context) {
+        InstallerApi29(Context context) {
             mContext = context;
         }
 
@@ -1120,9 +1120,10 @@
             final String action = "androidx.core.appdigest.COMMIT_COMPLETE." + resultId;
             IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(action);
-            mContext.registerReceiver(broadcastReceiver, intentFilter);
+            mContext.registerReceiver(broadcastReceiver, intentFilter, Context.RECEIVER_EXPORTED);
 
             Intent intent = new Intent(action);
+            intent.setPackage(mContext.getPackageName());
             PendingIntent sender = PendingIntent.getBroadcast(mContext, resultId, intent,
                     PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT
                             | PendingIntent.FLAG_MUTABLE);
@@ -1139,7 +1140,7 @@
     }
 
     @RequiresApi(31)
-    static class InstallerApi31 extends InstallerApi24 {
+    static class InstallerApi31 extends InstallerApi29 {
         InstallerApi31(Context context) {
             super(context);
         }
diff --git a/core/core-ktx/src/main/java/androidx/core/os/OutcomeReceiver.kt b/core/core-ktx/src/main/java/androidx/core/os/OutcomeReceiver.kt
index 74052a3..d6698aa 100644
--- a/core/core-ktx/src/main/java/androidx/core/os/OutcomeReceiver.kt
+++ b/core/core-ktx/src/main/java/androidx/core/os/OutcomeReceiver.kt
@@ -61,7 +61,7 @@
 private class ContinuationOutcomeReceiver<R, E : Throwable>(
     private val continuation: Continuation<R>
 ) : OutcomeReceiver<R, E>, AtomicBoolean(false) {
-    override fun onResult(result: R & Any) {
+    override fun onResult(result: R) {
         // Do not attempt to resume more than once, even if the caller of the returned
         // OutcomeReceiver is buggy and tries anyway.
         if (compareAndSet(false, true)) {
diff --git a/core/core-location-altitude-proto/OWNERS b/core/core-location-altitude-proto/OWNERS
new file mode 100644
index 0000000..b95c469
--- /dev/null
+++ b/core/core-location-altitude-proto/OWNERS
@@ -0,0 +1,2 @@
+bjj@google.com
+sooniln@google.com
diff --git a/core/core-location-altitude-proto/build.gradle b/core/core-location-altitude-proto/build.gradle
new file mode 100644
index 0000000..ee2c418
--- /dev/null
+++ b/core/core-location-altitude-proto/build.gradle
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("java-library")
+    id("com.google.protobuf")
+}
+
+dependencies {
+    implementation(libs.protobufLite)
+}
+
+protobuf {
+    protoc {
+        artifact = libs.protobufCompiler.get()
+    }
+    generateProtoTasks {
+        all().each { task ->
+            task.builtins {
+                java {
+                    option "lite"
+                }
+            }
+        }
+    }
+}
+
+afterEvaluate {
+    lint {
+        lintOptions {
+            // protobuf generates unannotated and synthetic accessor methods
+            disable("UnknownNullness", "SyntheticAccessor")
+        }
+    }
+}
+
+def preferencesProtoJarJarTask = tasks.register("exportJar", Jar) {
+    archiveBaseName.set("export")
+    from(sourceSets.main.output)
+    // The proto-lite dependency includes .proto files, which are not used by the altitude
+    // compatibility library. When apps depend on this library as well as proto-lite directly, these
+    // files conflict since jarjar only renames the java classes. Remove them here since they are
+    // unused.
+    exclude("**/*.proto")
+
+    from(zipTree(configurations.detachedConfiguration(
+            dependencies.create(libs.protobufLite.get())).getSingleFile()))
+}
+
+def jarjarConf = configurations.register("export")
+artifacts.add(jarjarConf.name, preferencesProtoJarJarTask.flatMap { it.archiveFile })
+
+androidx {
+    name = "Location Altitude Compatibility Library Protos"
+    publish = Publish.NONE
+    inceptionYear = "2022"
+    description = "Implementation protos for core-location-altitude artifact."
+}
diff --git a/core/core-location-altitude-proto/src/main/proto/map_params.proto b/core/core-location-altitude-proto/src/main/proto/map_params.proto
new file mode 100644
index 0000000..9082582
--- /dev/null
+++ b/core/core-location-altitude-proto/src/main/proto/map_params.proto
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package androidx.core.location.altitude.impl.proto;
+
+option java_package = "androidx.core.location.altitude.impl.proto";
+option java_multiple_files = true;
+
+// Defines parameters for a spherically projected geoid map and corresponding
+// tile management.
+message MapParamsProto {
+  // Defines the resolution of the map in terms of an S2 level.
+  optional int32 map_s2_level = 1;
+  // Defines the resolution of the tiles in cache in terms of an S2 level.
+  optional int32 cache_tile_s2_level = 2;
+  // Defines the resolution of the tiles on disk in terms of an S2 level.
+  optional int32 disk_tile_s2_level = 3;
+  // Defines the `a` coefficient in the expression `a * map_value + b` used to
+  // calculate a geoid height in meters.
+  optional double model_a_meters = 4;
+  // Defines the `b` coefficient in the expression `a * map_value + b` used to
+  // calculate a geoid height in meters.
+  optional double model_b_meters = 5;
+  // Defines the root mean square error in meters of the geoid height.
+  optional double model_rmse_meters = 6;
+}
diff --git a/core/core-location-altitude-proto/src/main/proto/s2_tile.proto b/core/core-location-altitude-proto/src/main/proto/s2_tile.proto
new file mode 100644
index 0000000..1b6ce41
--- /dev/null
+++ b/core/core-location-altitude-proto/src/main/proto/s2_tile.proto
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package androidx.core.location.altitude.impl.proto;
+
+option java_package = "androidx.core.location.altitude.impl.proto";
+option java_multiple_files = true;
+
+// A single tile associating values in the unit interval [0, 1] to map cells.
+message S2TileProto {
+  // The S2 token associated with the common parent of all map cells in this
+  // tile.
+  optional string tile_key = 1;
+
+  // Encoded data that merge into a value in the unit interval [0, 1] for each
+  // map cell in this tile.
+  optional bytes byte_buffer = 2;
+  optional bytes byte_jpeg = 3;
+  optional bytes byte_png = 4;
+}
\ No newline at end of file
diff --git a/core/core-location-altitude/api/current.txt b/core/core-location-altitude/api/current.txt
index e6f50d0..9263ab2 100644
--- a/core/core-location-altitude/api/current.txt
+++ b/core/core-location-altitude/api/current.txt
@@ -1 +1,9 @@
 // Signature format: 4.0
+package androidx.core.location.altitude {
+
+  public final class AltitudeConverterCompat {
+    method @WorkerThread public static void addMslAltitudeToLocation(android.content.Context, android.location.Location) throws java.io.IOException;
+  }
+
+}
+
diff --git a/core/core-location-altitude/api/restricted_current.txt b/core/core-location-altitude/api/restricted_current.txt
index e6f50d0..9263ab2 100644
--- a/core/core-location-altitude/api/restricted_current.txt
+++ b/core/core-location-altitude/api/restricted_current.txt
@@ -1 +1,9 @@
 // Signature format: 4.0
+package androidx.core.location.altitude {
+
+  public final class AltitudeConverterCompat {
+    method @WorkerThread public static void addMslAltitudeToLocation(android.content.Context, android.location.Location) throws java.io.IOException;
+  }
+
+}
+
diff --git a/core/core-location-altitude/build.gradle b/core/core-location-altitude/build.gradle
index ccee9b7..3ee3eef 100644
--- a/core/core-location-altitude/build.gradle
+++ b/core/core-location-altitude/build.gradle
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+import androidx.build.BundleInsideHelper
 import androidx.build.LibraryType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
     id("AndroidXPlugin")
@@ -24,18 +26,34 @@
 
 android {
     namespace "androidx.core.location.altitude"
+
+    buildTypes.all {
+        consumerProguardFiles "proguard-rules.pro"
+    }
 }
 
+BundleInsideHelper.forInsideAar(
+        project,
+        /* from = */ "com.google.protobuf",
+        /* to =   */ "androidx.core.location.altitude.impl.proto"
+)
+
 dependencies {
     api(libs.kotlinStdlib)
     api("androidx.annotation:annotation:1.5.0")
 
-    implementation("androidx.concurrent:concurrent-futures:1.1.0")
-    implementation("androidx.core:core:1.9.0")
+    bundleInside(project(path: ":core:core-location-altitude-proto", configuration: "export"))
+
+    implementation(libs.autoValueAnnotations)
+    implementation(project(":core:core"))
+    implementation("androidx.room:room-runtime:2.4.3")
+
+    annotationProcessor(libs.autoValue)
+    annotationProcessor("androidx.room:room-compiler:2.4.3")
 
     androidTestImplementation(libs.junit)
-    androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.truth)
 }
diff --git a/core/core-location-altitude/proguard-rules.pro b/core/core-location-altitude/proguard-rules.pro
new file mode 100644
index 0000000..dee5477
--- /dev/null
+++ b/core/core-location-altitude/proguard-rules.pro
@@ -0,0 +1,19 @@
+#  Copyright (C) 2022 The Android Open Source Project
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+# libproto uses reflection to deserialize a Proto, which Proguard can't accurately detect.
+# Keep all the class members of any generated messages to ensure we can deserialize properly inside
+# these classes.
+-if class * extends androidx.core.location.altitude.impl.proto.GeneratedMessageLite
+-keepclasseswithmembers
\ No newline at end of file
diff --git a/core/core-location-altitude/src/androidTest/java/androidx/core/location/altitude/AltitudeConverterCompatTest.java b/core/core-location-altitude/src/androidTest/java/androidx/core/location/altitude/AltitudeConverterCompatTest.java
index 3c61ed9..7b0787d 100644
--- a/core/core-location-altitude/src/androidTest/java/androidx/core/location/altitude/AltitudeConverterCompatTest.java
+++ b/core/core-location-altitude/src/androidTest/java/androidx/core/location/altitude/AltitudeConverterCompatTest.java
@@ -23,138 +23,143 @@
 import android.content.Context;
 import android.location.Location;
 
-import androidx.arch.core.util.Function;
 import androidx.core.location.LocationCompat;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
+import androidx.test.filters.MediumTest;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@SmallTest
+import java.io.IOException;
+
+@MediumTest
 @RunWith(AndroidJUnit4.class)
 public class AltitudeConverterCompatTest {
 
-    private Location mValidLocation;
     private Context mContext;
 
-    private static void assertEquals(Location actual, Location expected) {
-        assertThat(actual.getLatitude()).isEqualTo(expected.getLatitude());
-        assertThat(actual.getLongitude()).isEqualTo(expected.getLongitude());
-        assertEquals(actual, expected, Location::hasAltitude, Location::getAltitude);
-        assertEquals(
-                actual,
-                expected,
-                LocationCompat::hasVerticalAccuracy,
-                LocationCompat::getVerticalAccuracyMeters);
-        assertEquals(
-                actual, expected, LocationCompat::hasMslAltitude,
-                LocationCompat::getMslAltitudeMeters);
-        assertEquals(
-                actual,
-                expected,
-                LocationCompat::hasMslAltitudeAccuracy,
-                LocationCompat::getMslAltitudeAccuracyMeters);
-    }
-
-    private static <T> void assertEquals(
-            Location actual,
-            Location expected,
-            Function<Location, Boolean> has,
-            Function<Location, T> get) {
-        assertThat(has.apply(actual)).isEqualTo(has.apply(expected));
-        if (has.apply(expected)) {
-            assertThat(get.apply(actual)).isEqualTo(get.apply(expected));
-        }
-    }
-
     @Before
     public void setUp() {
-        mValidLocation = new Location("");
-        mValidLocation.setLatitude(-90);
-        mValidLocation.setLongitude(180);
-        mValidLocation.setAltitude(-1);
-        LocationCompat.setVerticalAccuracyMeters(mValidLocation, 1);
-
         mContext = ApplicationProvider.getApplicationContext();
     }
 
     @Test
-    public void testAddMslAltitude_validLocationThrows() {
-        assertThrows(
-                UnsupportedOperationException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(mValidLocation)));
+    public void testAddMslAltitudeToLocation_expectedBehavior() throws IOException {
+        // Interpolates in boundary region (bffffc).
+        Location location = new Location("");
+        location.setLatitude(-35.334815);
+        location.setLongitude(-45);
+        location.setAltitude(-1);
+        LocationCompat.setVerticalAccuracyMeters(location, 1);
+        // Loads data from raw assets.
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(5.0622);
+        assertThat(LocationCompat.getMslAltitudeAccuracyMeters(location)).isGreaterThan(1f);
+        assertThat(LocationCompat.getMslAltitudeAccuracyMeters(location)).isLessThan(1.1f);
+
+        // Again interpolates at same location to assert no loading from raw assets. Also checks
+        // behavior w.r.t. invalid vertical accuracy.
+        location = new Location("");
+        location.setLatitude(-35.334815);
+        location.setLongitude(-45);
+        location.setAltitude(-1);
+        LocationCompat.setVerticalAccuracyMeters(location, -1); // Invalid vertical accuracy
+        // Results in same outcome.
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(5.0622);
+        assertThat(LocationCompat.hasMslAltitudeAccuracy(location)).isFalse();
+
+        // Interpolates out of boundary region, e.g., Hawaii.
+        location = new Location("");
+        location.setLatitude(19.545519);
+        location.setLongitude(-155.998774);
+        location.setAltitude(-1);
+        LocationCompat.setVerticalAccuracyMeters(location, 1);
+        // Loads data from raw assets.
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(-19.2359);
+        assertThat(LocationCompat.getMslAltitudeAccuracyMeters(location)).isGreaterThan(1f);
+        assertThat(LocationCompat.getMslAltitudeAccuracyMeters(location)).isLessThan(1.1f);
+
+        // The following round out test coverage for boundary regions.
+
+        location = new Location("");
+        location.setLatitude(-35.229154);
+        location.setLongitude(44.925335);
+        location.setAltitude(-1);
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(-34.1913);
+
+        location = new Location("");
+        location.setLatitude(-35.334815);
+        location.setLongitude(45);
+        location.setAltitude(-1);
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(-34.2258);
+
+        location = new Location("");
+        location.setLatitude(35.229154);
+        location.setLongitude(-44.925335);
+        location.setAltitude(-1);
+        AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location);
+        assertThat(LocationCompat.getMslAltitudeMeters(location)).isWithin(2).of(-11.0691);
     }
 
     @Test
-    public void testAddMslAltitude_invalidLatitudeThrows() {
-        Location location = new Location(mValidLocation);
+    public void testAddMslAltitudeToLocation_invalidLatitudeThrows() {
+        Location location = new Location("");
+        location.setLongitude(-44.962683);
+        location.setAltitude(-1);
 
         location.setLatitude(Double.NaN);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setLatitude(91);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setLatitude(-91);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
     }
 
     @Test
-    public void testAddMslAltitude_invalidLongitudeThrows() {
-        Location location = new Location(mValidLocation);
+    public void testAddMslAltitudeToLocation_invalidLongitudeThrows() {
+        Location location = new Location("");
+        location.setLatitude(-35.246789);
+        location.setAltitude(-1);
 
         location.setLongitude(Double.NaN);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setLongitude(181);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setLongitude(-181);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
     }
 
     @Test
-    public void testAddMslAltitude_invalidAltitudeThrows() {
-        Location location = new Location(mValidLocation);
+    public void testAddMslAltitudeToLocation_invalidAltitudeThrows() {
+        Location location = new Location("");
+        location.setLatitude(-35.246789);
+        location.setLongitude(-44.962683);
 
-        location.removeAltitude();
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setAltitude(Double.NaN);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
 
         location.setAltitude(Double.POSITIVE_INFINITY);
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> AltitudeConverterCompat.addMslAltitudeAsync(mContext,
-                        new Location(location)));
+        assertThrows(IllegalArgumentException.class,
+                () -> AltitudeConverterCompat.addMslAltitudeToLocation(mContext, location));
     }
 }
diff --git a/core/core-location-altitude/src/main/assets/database/geoid-height-map-v0.db b/core/core-location-altitude/src/main/assets/database/geoid-height-map-v0.db
new file mode 100644
index 0000000..1037857
--- /dev/null
+++ b/core/core-location-altitude/src/main/assets/database/geoid-height-map-v0.db
Binary files differ
diff --git a/core/core-location-altitude/src/main/assets/database/geoids-v0.db b/core/core-location-altitude/src/main/assets/database/geoids-v0.db
deleted file mode 100644
index 1be3bd7..0000000
--- a/core/core-location-altitude/src/main/assets/database/geoids-v0.db
+++ /dev/null
Binary files differ
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/AltitudeConverterCompat.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/AltitudeConverterCompat.java
index f3cd443..555aaa0 100644
--- a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/AltitudeConverterCompat.java
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/AltitudeConverterCompat.java
@@ -18,74 +18,99 @@
 
 import android.content.Context;
 import android.location.Location;
+import android.os.Build;
 
+import androidx.annotation.DoNotInline;
+import androidx.annotation.GuardedBy;
 import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-import androidx.core.util.Preconditions;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.WorkerThread;
+import androidx.core.location.altitude.impl.AltitudeConverter;
 
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.util.Objects;
+import java.io.IOException;
 
 /**
  * Converts altitudes reported above the World Geodetic System 1984 (WGS84) reference ellipsoid
  * into ones above Mean Sea Level.
  *
+ * <p>Reference:
+ *
+ * <pre>
+ * Brian Julian and Michael Angermann.
+ * "Resource efficient and accurate altitude conversion to Mean Sea Level."
+ * 2023 IEEE/ION Position, Location and Navigation Symposium (PLANS).
+ * </pre>
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
 public final class AltitudeConverterCompat {
 
-    private static final double MAX_ABS_VALID_LATITUDE = 90;
-    private static final double MAX_ABS_VALID_LONGITUDE = 180;
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    @Nullable
+    private static AltitudeConverter sAltitudeConverter;
 
     /** Prevents instantiation. */
     private AltitudeConverterCompat() {
     }
 
     /**
-     * Returns a {@link ListenableFuture} that, upon success, adds a Mean Sea Level altitude to the
-     * {@code location} in {@link Location#getExtras()}. In addition, adds a Mean Sea Level altitude
-     * accuracy if the {@code location} has a valid vertical accuracy.
+     * Adds a Mean Sea Level altitude to the {@code location}. In addition, adds a Mean Sea Level
+     * altitude accuracy if the {@code location} has a finite and non-negative vertical accuracy;
+     * otherwise, does not add a corresponding accuracy.
      *
-     * <p>The {@link ListenableFuture} leaves the {@code location} unchanged if and only if any
-     * of the following are true:
+     * <p>Must be called off the main thread as data may be loaded from raw assets.
      *
-     * <ul>
-     *   <li>the {@code location} has an invalid latitude, longitude, or altitude above WGS84
-     *   <li>an I/O error occurs when loading data from raw assets via {@code context}.
-     * </ul>
-     *
-     * <p>NOTE: Currently throws {@link UnsupportedOperationException} for a valid {@code location}.
-     *
+     * @throws IOException              if an I/O error occurs when loading data from raw assets.
+     * @throws IllegalArgumentException if the {@code location} has an invalid latitude, longitude,
+     *                                  or altitude above WGS84. Specifically, the latitude must be
+     *                                  between -90 and 90 (both inclusive), the longitude must be
+     *                                  between -180 and 180 (both inclusive), and the altitude
+     *                                  above WGS84 must be finite.
      */
-    @NonNull
-    public static ListenableFuture<Location> addMslAltitudeAsync(
-            @NonNull Context context,
-            @NonNull Location location) {
-        Objects.requireNonNull(context);
-        Objects.requireNonNull(location);
-        validate(location);
-        throw new UnsupportedOperationException("addMslAltitude method not implemented.");
+    @WorkerThread
+    public static void addMslAltitudeToLocation(@NonNull Context context,
+            @NonNull Location location) throws IOException {
+        if (Build.VERSION.SDK_INT >= 34) {
+            Api34Impl.addMslAltitudeToLocation(context, location);
+            return;
+        }
+
+        AltitudeConverter altitudeConverter;
+        synchronized (sLock) {
+            if (sAltitudeConverter == null) {
+                sAltitudeConverter = new AltitudeConverter();
+            }
+            altitudeConverter = sAltitudeConverter;
+        }
+        altitudeConverter.addMslAltitudeToLocation(context, location);
     }
 
-    /**
-     * Throws an {@link IllegalArgumentException} if the {@code location} has an invalid latitude,
-     * longitude, or altitude above WGS84.
-     */
-    private static void validate(@NonNull Location location) {
-        Preconditions.checkArgument(isFiniteAndAtAbsMost(location.getLatitude(),
-                MAX_ABS_VALID_LATITUDE), "Location must contain a valid latitude.");
-        Preconditions.checkArgument(isFiniteAndAtAbsMost(location.getLongitude(),
-                MAX_ABS_VALID_LONGITUDE), "Location must contain a valid longitude.");
-        Preconditions.checkArgument(location.hasAltitude() && isFinite(location.getAltitude()),
-                "Location must contain a valid altitude above WGS84.");
-    }
+    @RequiresApi(34)
+    private static class Api34Impl {
 
-    private static boolean isFiniteAndAtAbsMost(double value, double rhs) {
-        return isFinite(value) && Math.abs(value) <= rhs;
-    }
+        private static final Object sLock = new Object();
 
-    private static boolean isFinite(double value) {
-        return !Double.isInfinite(value) && !Double.isNaN(value);
+        @GuardedBy("sLock")
+        @Nullable
+        private static Object sAltitudeConverter;
+
+        /** Prevents instantiation. */
+        private Api34Impl() {
+        }
+
+        @DoNotInline
+        static void addMslAltitudeToLocation(@NonNull Context context,
+                @NonNull Location location) throws IOException {
+            android.location.altitude.AltitudeConverter altitudeConverter;
+            synchronized (sLock) {
+                if (sAltitudeConverter == null) {
+                    sAltitudeConverter = new android.location.altitude.AltitudeConverter();
+                }
+                altitudeConverter =
+                        (android.location.altitude.AltitudeConverter) sAltitudeConverter;
+            }
+            altitudeConverter.addMslAltitudeToLocation(context, location);
+        }
     }
 }
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/AltitudeConverter.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/AltitudeConverter.java
new file mode 100644
index 0000000..3fd1272
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/AltitudeConverter.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl;
+
+import android.content.Context;
+import android.location.Location;
+
+import androidx.annotation.NonNull;
+import androidx.core.location.LocationCompat;
+import androidx.core.location.altitude.impl.proto.MapParamsProto;
+import androidx.core.util.Preconditions;
+
+import java.io.IOException;
+
+/** Implements {@link androidx.core.location.altitude.AltitudeConverterCompat}. */
+public final class AltitudeConverter {
+
+    private static final double MAX_ABS_VALID_LATITUDE = 90;
+    private static final double MAX_ABS_VALID_LONGITUDE = 180;
+
+    /** Manages a mapping of geoid heights associated with S2 cells. */
+    private final GeoidHeightMap mGeoidHeightMap = new GeoidHeightMap();
+
+    /**
+     * Creates an instance that manages an independent cache to optimized conversions of locations
+     * in proximity to one another.
+     */
+    public AltitudeConverter() {
+    }
+
+    /**
+     * Throws an {@link IllegalArgumentException} if the {@code location} has an invalid latitude,
+     * longitude, or altitude above WGS84.
+     */
+    private static void validate(@NonNull Location location) {
+        Preconditions.checkArgument(
+                isFiniteAndAtAbsMost(location.getLatitude(), MAX_ABS_VALID_LATITUDE),
+                "Invalid latitude: %f", location.getLatitude());
+        Preconditions.checkArgument(
+                isFiniteAndAtAbsMost(location.getLongitude(), MAX_ABS_VALID_LONGITUDE),
+                "Invalid longitude: %f", location.getLongitude());
+        Preconditions.checkArgument(location.hasAltitude(), "Missing altitude above WGS84");
+        Preconditions.checkArgument(Double.isFinite(location.getAltitude()),
+                "Invalid altitude above WGS84: %f", location.getAltitude());
+    }
+
+    private static boolean isFiniteAndAtAbsMost(double value, double rhs) {
+        return isFinite(value) && Math.abs(value) <= rhs;
+    }
+
+    private static boolean isFinite(double value) {
+        return !Double.isInfinite(value) && !Double.isNaN(value);
+    }
+
+    /**
+     * Returns the four S2 cell IDs for the map square associated with the {@code location}.
+     *
+     * <p>The first map cell, denoted z11 in the appendix of the referenced paper below, contains
+     * the location. The others are the map cells denoted z21, z12, and z22, in that order.
+     *
+     * <p>Reference:
+     *
+     * <pre>
+     * Brian Julian and Michael Angermann.
+     * "Resource efficient and accurate altitude conversion to Mean Sea Level."
+     * 2023 IEEE/ION Position, Location and Navigation Symposium (PLANS).
+     * </pre>
+     */
+    @NonNull
+    private static long[] findMapSquare(@NonNull MapParamsProto params,
+            @NonNull Location location) {
+        long s2CellId =
+                S2CellIdUtils.fromLatLngDegrees(location.getLatitude(), location.getLongitude());
+
+        // Cell-space properties and coordinates.
+        int sizeIj = 1 << (S2CellIdUtils.MAX_LEVEL - params.getMapS2Level());
+        int maxIj = 1 << S2CellIdUtils.MAX_LEVEL;
+        long z11 = S2CellIdUtils.getParent(s2CellId, params.getMapS2Level());
+        int f11 = S2CellIdUtils.getFace(s2CellId);
+        int i1 = S2CellIdUtils.getI(s2CellId);
+        int j1 = S2CellIdUtils.getJ(s2CellId);
+        int i2 = i1 + sizeIj;
+        int j2 = j1 + sizeIj;
+
+        // Non-boundary region calculation - simplest and most common case.
+        if (i2 < maxIj && j2 < maxIj) {
+            return new long[]{
+                    z11,
+                    S2CellIdUtils.getParent(S2CellIdUtils.fromFij(f11, i2, j1),
+                            params.getMapS2Level()),
+                    S2CellIdUtils.getParent(S2CellIdUtils.fromFij(f11, i1, j2),
+                            params.getMapS2Level()),
+                    S2CellIdUtils.getParent(S2CellIdUtils.fromFij(f11, i2, j2),
+                            params.getMapS2Level())
+            };
+        }
+
+        // Boundary region calculation
+        long[] edgeNeighbors = new long[4];
+        S2CellIdUtils.getEdgeNeighbors(z11, edgeNeighbors);
+        long z11W = edgeNeighbors[0];
+        long z11S = edgeNeighbors[1];
+        long z11E = edgeNeighbors[2];
+        long z11N = edgeNeighbors[3];
+
+        long[] otherEdgeNeighbors = new long[4];
+        S2CellIdUtils.getEdgeNeighbors(z11W, otherEdgeNeighbors);
+        S2CellIdUtils.getEdgeNeighbors(z11S, edgeNeighbors);
+        long z11SW = findCommonNeighbor(edgeNeighbors, otherEdgeNeighbors, z11);
+        S2CellIdUtils.getEdgeNeighbors(z11E, otherEdgeNeighbors);
+        long z11SE = findCommonNeighbor(edgeNeighbors, otherEdgeNeighbors, z11);
+        S2CellIdUtils.getEdgeNeighbors(z11N, edgeNeighbors);
+        long z11NE = findCommonNeighbor(edgeNeighbors, otherEdgeNeighbors, z11);
+
+        long z21 = (f11 % 2 == 1 && i2 >= maxIj) ? z11SW : z11S;
+        long z12 = (f11 % 2 == 0 && j2 >= maxIj) ? z11NE : z11E;
+        long z22 = (z21 == z11SW) ? z11S : (z12 == z11NE) ? z11E : z11SE;
+
+        // Reuse edge neighbors' array to avoid an extra allocation.
+        edgeNeighbors[0] = z11;
+        edgeNeighbors[1] = z21;
+        edgeNeighbors[2] = z12;
+        edgeNeighbors[3] = z22;
+        return edgeNeighbors;
+    }
+
+    /**
+     * Returns the first common non-z11 neighbor found between the two arrays of edge neighbors. If
+     * such a common neighbor does not exist, returns z11.
+     */
+    private static long findCommonNeighbor(
+            @NonNull long[] edgeNeighbors, @NonNull long[] otherEdgeNeighbors, long z11) {
+        for (long edgeNeighbor : edgeNeighbors) {
+            if (edgeNeighbor == z11) {
+                continue;
+            }
+            for (long otherEdgeNeighbor : otherEdgeNeighbors) {
+                if (edgeNeighbor == otherEdgeNeighbor) {
+                    return edgeNeighbor;
+                }
+            }
+        }
+        return z11;
+    }
+
+    /**
+     * Adds to {@code location} the bilinearly interpolated Mean Sea Level altitude. In addition, a
+     * Mean Sea Level altitude accuracy is added if the {@code location} has a valid vertical
+     * accuracy; otherwise, does not add a corresponding accuracy.
+     */
+    private static void addMslAltitude(@NonNull MapParamsProto params,
+            @NonNull double[] geoidHeightsMeters, @NonNull Location location) {
+        double h0 = geoidHeightsMeters[0];
+        double h1 = geoidHeightsMeters[1];
+        double h2 = geoidHeightsMeters[2];
+        double h3 = geoidHeightsMeters[3];
+
+        // Bilinear interpolation on an S2 square of size equal to that of a map cell. wi and wj
+        // are the normalized [0,1] weights in the i and j directions, respectively, allowing us to
+        // employ the simplified unit square formulation.
+        long s2CellId = S2CellIdUtils.fromLatLngDegrees(location.getLatitude(),
+                location.getLongitude());
+        double sizeIj = 1 << (S2CellIdUtils.MAX_LEVEL - params.getMapS2Level());
+        double wi = (S2CellIdUtils.getI(s2CellId) % sizeIj) / sizeIj;
+        double wj = (S2CellIdUtils.getJ(s2CellId) % sizeIj) / sizeIj;
+        double offsetMeters = h0 + (h1 - h0) * wi + (h2 - h0) * wj + (h3 - h1 - h2 + h0) * wi * wj;
+
+        LocationCompat.setMslAltitudeMeters(location, location.getAltitude() - offsetMeters);
+        if (LocationCompat.hasVerticalAccuracy(location)) {
+            double verticalAccuracyMeters = LocationCompat.getVerticalAccuracyMeters(location);
+            if (isFinite(verticalAccuracyMeters) && verticalAccuracyMeters >= 0) {
+                LocationCompat.setMslAltitudeAccuracyMeters(location,
+                        (float) Math.hypot(verticalAccuracyMeters, params.getModelRmseMeters()));
+            }
+        }
+    }
+
+    /**
+     * Implements
+     * {@link androidx.core.location.altitude.AltitudeConverterCompat#addMslAltitudeToLocation(Context, Location)}.
+     */
+    public void addMslAltitudeToLocation(@NonNull Context context, @NonNull Location location)
+            throws IOException {
+        validate(location);
+        MapParamsProto params = GeoidHeightMap.getParams(context);
+        long[] s2CellIds = findMapSquare(params, location);
+        double[] geoidHeightsMeters = mGeoidHeightMap.readGeoidHeights(params, context, s2CellIds);
+        addMslAltitude(params, geoidHeightsMeters, location);
+    }
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/GeoidHeightMap.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/GeoidHeightMap.java
new file mode 100644
index 0000000..811a19f
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/GeoidHeightMap.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.LruCache;
+
+import androidx.annotation.GuardedBy;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.location.altitude.impl.db.AltitudeConverterDatabase;
+import androidx.core.location.altitude.impl.db.MapParamsEntity;
+import androidx.core.location.altitude.impl.db.TilesEntity;
+import androidx.core.location.altitude.impl.proto.ByteString;
+import androidx.core.location.altitude.impl.proto.MapParamsProto;
+import androidx.core.location.altitude.impl.proto.S2TileProto;
+import androidx.core.util.Preconditions;
+import androidx.room.Room;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * Manages a mapping of geoid heights associated with S2 cells, referred to as MAP CELLS.
+ *
+ * <p>Tiles are used extensively to reduce the number of entries needed to be stored in memory and
+ * on disk. A tile associates geoid heights with all map cells of a common parent at a specified S2
+ * level.
+ *
+ * <p>Since bilinear interpolation considers at most four map cells at a time, at most four tiles
+ * are simultaneously stored in memory. These tiles, referred to as CACHE TILES, are each keyed by
+ * its common parent's S2 cell ID, referred to as a CACHE KEY.
+ *
+ * <p>Absent cache tiles needed for interpolation are constructed from larger tiles stored on disk.
+ * The latter tiles, referred to as DISK TILES, are each keyed by its common parent's S2 cell token,
+ * referred to as a DISK TOKEN.
+ */
+final class GeoidHeightMap {
+
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    @Nullable
+    private static MapParamsProto sParams;
+
+    /** Defines the resource database for {@link AltitudeConverter}. */
+    @GuardedBy("sLock")
+    @Nullable
+    private static AltitudeConverterDatabase sDatabase;
+
+
+    /** Defines a cache large enough to hold all cache tiles needed for interpolation. */
+    private final LruCache<Long, S2TileProto> mCacheTiles = new LruCache<>(4);
+
+    @NonNull
+    public static AltitudeConverterDatabase getDatabase(@NonNull Context context) {
+        synchronized (sLock) {
+            if (sDatabase == null) {
+                sDatabase = Room.databaseBuilder(context.getApplicationContext(),
+                        AltitudeConverterDatabase.class, "geoid-height-map.db").createFromAsset(
+                        "database/geoid-height-map-v0.db").build();
+            }
+            return sDatabase;
+        }
+    }
+
+    /**
+     * Returns the singleton parameter instance for a spherically projected geoid height map and its
+     * corresponding tile management.
+     */
+    @NonNull
+    public static MapParamsProto getParams(@NonNull Context context) throws IOException {
+        synchronized (sLock) {
+            if (sParams == null) {
+                MapParamsEntity current = getDatabase(context).mapParamsDao().getCurrent();
+                if (current == null) {
+                    throw new IOException("Unable to load map parameters from raw assets.");
+                }
+                sParams = current.value();
+            }
+            return sParams;
+        }
+    }
+
+    private static long getCacheKey(@NonNull MapParamsProto params, long s2CellId) {
+        return S2CellIdUtils.getParent(s2CellId, params.getCacheTileS2Level());
+    }
+
+    @NonNull
+    private static String getDiskToken(@NonNull MapParamsProto params, long s2CellId) {
+        return S2CellIdUtils.getToken(
+                S2CellIdUtils.getParent(s2CellId, params.getDiskTileS2Level()));
+    }
+
+    /**
+     * Adds to {@code values} values in the unit interval [0, 1] for the map cells identified by
+     * {@code s2CellIds}. Returns true if values are present for all IDs; otherwise, returns false
+     * and adds NaNs for absent values.
+     */
+    private static boolean getUnitIntervalValues(@NonNull MapParamsProto params,
+            @NonNull TileFunction tileFunction,
+            @NonNull long[] s2CellIds, @NonNull double[] values) throws IOException {
+        int len = s2CellIds.length;
+
+        S2TileProto[] tiles = new S2TileProto[len];
+        for (int i = 0; i < len; i++) {
+            long cacheKey = getCacheKey(params, s2CellIds[i]);
+            tiles[i] = tileFunction.getTile(cacheKey);
+            values[i] = Double.NaN;
+        }
+
+        for (int i = 0; i < len; i++) {
+            if (tiles[i] == null || !Double.isNaN(values[i])) {
+                continue;
+            }
+
+            mergeByteBufferValues(params, s2CellIds, tiles, i, values);
+            mergeByteJpegValues(params, s2CellIds, tiles, i, values);
+            mergeBytePngValues(params, s2CellIds, tiles, i, values);
+        }
+
+        boolean allFound = true;
+        for (int i = 0; i < len; i++) {
+            if (Double.isNaN(values[i])) {
+                allFound = false;
+            } else {
+                values[i] = (((int) values[i]) & 0xFF) / 255.0;
+            }
+        }
+        return allFound;
+    }
+
+    @SuppressWarnings("ReferenceEquality")
+    private static void mergeByteBufferValues(@NonNull MapParamsProto params,
+            @NonNull long[] s2CellIds,
+            @NonNull S2TileProto[] tiles,
+            int tileIndex, @NonNull double[] values) {
+        ByteString byteString = tiles[tileIndex].getByteBuffer();
+        if (byteString.isEmpty()) {
+            return;
+        }
+
+        ByteBuffer byteBuffer = byteString.asReadOnlyByteBuffer();
+        int tileS2Level =
+                params.getMapS2Level() - Integer.numberOfTrailingZeros(byteBuffer.limit()) / 2;
+        int numBitsLeftOfTile = 2 * tileS2Level + 3;
+
+        for (int i = tileIndex; i < tiles.length; i++) {
+            if (tiles[i] != tiles[tileIndex]) {
+                continue;
+            }
+
+            long maskedS2CellId = s2CellIds[i] & (-1L >>> numBitsLeftOfTile);
+            int numBitsRightOfMap = 2 * (S2CellIdUtils.MAX_LEVEL - params.getMapS2Level()) + 1;
+            int bufferIndex = (int) (maskedS2CellId >>> numBitsRightOfMap);
+            values[i] = Double.isNaN(values[i]) ? 0 : values[i];
+            values[i] += ((int) byteBuffer.get(bufferIndex)) & 0xFF;
+        }
+    }
+
+    private static void mergeByteJpegValues(@NonNull MapParamsProto params,
+            @NonNull long[] s2CellIds,
+            @NonNull S2TileProto[] tiles,
+            int tileIndex, @NonNull double[] values) throws IOException {
+        mergeByteImageValues(params, tiles[tileIndex].getByteJpeg(), s2CellIds, tiles, tileIndex,
+                values);
+    }
+
+    private static void mergeBytePngValues(@NonNull MapParamsProto params,
+            @NonNull long[] s2CellIds,
+            @NonNull S2TileProto[] tiles,
+            int tileIndex, @NonNull double[] values) throws IOException {
+        mergeByteImageValues(params, tiles[tileIndex].getBytePng(), s2CellIds, tiles, tileIndex,
+                values);
+    }
+
+    @SuppressWarnings("ReferenceEquality")
+    private static void mergeByteImageValues(@NonNull MapParamsProto params,
+            @NonNull ByteString byteString,
+            @NonNull long[] s2CellIds,
+            @NonNull S2TileProto[] tiles, int tileIndex, @NonNull double[] values)
+            throws IOException {
+        if (byteString.isEmpty()) {
+            return;
+        }
+        Bitmap bitmap;
+        try (InputStream inputStream = byteString.newInput()) {
+            bitmap = BitmapFactory.decodeStream(inputStream);
+        }
+        if (bitmap == null) {
+            return;
+        }
+
+        for (int i = tileIndex; i < tiles.length; i++) {
+            if (tiles[i] != tiles[tileIndex]) {
+                continue;
+            }
+
+            values[i] = Double.isNaN(values[i]) ? 0 : values[i];
+            values[i] += bitmap.getPixel(getIndexX(params, s2CellIds[i], bitmap.getWidth()),
+                    getIndexY(params, s2CellIds[i], bitmap.getHeight())) & 0xFF;
+        }
+    }
+
+    /** Returns the X index for an S2 cell within an S2 tile image of specified width. */
+    private static int getIndexX(@NonNull MapParamsProto params, long s2CellId, int width) {
+        return getIndexXOrY(params, S2CellIdUtils.getI(s2CellId), width);
+    }
+
+    /** Returns the Y index for an S2 cell within an S2 tile image of specified height. */
+    private static int getIndexY(@NonNull MapParamsProto params, long s2CellId, int height) {
+        return getIndexXOrY(params, S2CellIdUtils.getJ(s2CellId), height);
+    }
+
+    private static int getIndexXOrY(@NonNull MapParamsProto params, int iOrJ, int widthOrHeight) {
+        return (iOrJ >> (S2CellIdUtils.MAX_LEVEL - params.getMapS2Level())) % widthOrHeight;
+    }
+
+    /**
+     * Throws an {@link IllegalArgumentException} if the {@code s2CellIds} has an invalid length or
+     * ID.
+     */
+    private static void validate(@NonNull MapParamsProto params, @NonNull long[] s2CellIds) {
+        Preconditions.checkArgument(s2CellIds.length == 4);
+        for (long s2CellId : s2CellIds) {
+            Preconditions.checkArgument(S2CellIdUtils.getLevel(s2CellId) == params.getMapS2Level());
+        }
+    }
+
+    /**
+     * Returns the geoid heights in meters associated with the map cells identified by
+     * {@code s2CellIds}. Throws an {@link IOException} if a geoid height cannot be calculated for
+     * an ID.
+     */
+    @NonNull
+    public double[] readGeoidHeights(@NonNull MapParamsProto params, @NonNull Context context,
+            @NonNull long[] s2CellIds) throws IOException {
+        validate(params, s2CellIds);
+        double[] heightsMeters = new double[s2CellIds.length];
+        if (getGeoidHeights(params, mCacheTiles::get, s2CellIds, heightsMeters)) {
+            return heightsMeters;
+        }
+
+        TileFunction loadedTiles = loadFromCacheAndDisk(params, context, s2CellIds);
+        if (getGeoidHeights(params, loadedTiles, s2CellIds, heightsMeters)) {
+            return heightsMeters;
+        }
+        throw new IOException("Unable to calculate geoid heights from raw assets.");
+    }
+
+    /**
+     * Same as {@link #readGeoidHeights(MapParamsProto, Context, long[])} except that data will not
+     * be loaded from raw assets. Returns the heights if present for all IDs; otherwise, returns
+     * null.
+     */
+    @Nullable
+    public double[] readGeoidHeights(@NonNull MapParamsProto params, @NonNull long[] s2CellIds)
+            throws IOException {
+        validate(params, s2CellIds);
+        double[] heightsMeters = new double[s2CellIds.length];
+        if (getGeoidHeights(params, mCacheTiles::get, s2CellIds, heightsMeters)) {
+            return heightsMeters;
+        }
+        return null;
+    }
+
+    /**
+     * Adds to {@code heightsMeters} the geoid heights in meters associated with the map cells
+     * identified by {@code s2CellIds}. Returns true if heights are present for all IDs; otherwise,
+     * returns false and adds NaNs for absent heights.
+     */
+    private boolean getGeoidHeights(@NonNull MapParamsProto params,
+            @NonNull TileFunction tileFunction, @NonNull long[] s2CellIds,
+            @NonNull double[] heightsMeters) throws IOException {
+        boolean allFound = getUnitIntervalValues(params, tileFunction, s2CellIds, heightsMeters);
+        for (int i = 0; i < heightsMeters.length; i++) {
+            // NaNs are properly preserved.
+            heightsMeters[i] *= params.getModelAMeters();
+            heightsMeters[i] += params.getModelBMeters();
+        }
+        return allFound;
+    }
+
+    @NonNull
+    private TileFunction loadFromCacheAndDisk(@NonNull MapParamsProto params,
+            @NonNull Context context, @NonNull long[] s2CellIds) throws IOException {
+        int len = s2CellIds.length;
+
+        // Enable batch loading by finding all cache keys upfront.
+        long[] cacheKeys = new long[len];
+        for (int i = 0; i < len; i++) {
+            cacheKeys[i] = getCacheKey(params, s2CellIds[i]);
+        }
+
+        // Attempt to load tiles from cache.
+        S2TileProto[] loadedTiles = new S2TileProto[len];
+        String[] diskTokens = new String[len];
+        for (int i = 0; i < len; i++) {
+            if (diskTokens[i] != null) {
+                continue;
+            }
+            loadedTiles[i] = mCacheTiles.get(cacheKeys[i]);
+            diskTokens[i] = getDiskToken(params, cacheKeys[i]);
+
+            // Batch across common cache key.
+            for (int j = i + 1; j < len; j++) {
+                if (cacheKeys[j] == cacheKeys[i]) {
+                    loadedTiles[j] = loadedTiles[i];
+                    diskTokens[j] = diskTokens[i];
+                }
+            }
+        }
+
+        // Attempt to load tiles from disk.
+        for (int i = 0; i < len; i++) {
+            if (loadedTiles[i] != null) {
+                continue;
+            }
+
+            TilesEntity entity = getDatabase(context).tilesDao().get(diskTokens[i]);
+            if (entity == null) {
+                throw new IOException("Unable to read disk tile of disk token: " + diskTokens[i]);
+            }
+            mergeFromDiskTile(params, entity.tile(), cacheKeys, diskTokens, i, loadedTiles);
+        }
+
+        return cacheKey -> {
+            for (int i = 0; i < cacheKeys.length; i++) {
+                if (cacheKeys[i] == cacheKey) {
+                    return loadedTiles[i];
+                }
+            }
+            return null;
+        };
+    }
+
+    private void mergeFromDiskTile(@NonNull MapParamsProto params, @NonNull S2TileProto diskTile,
+            @NonNull long[] cacheKeys, @NonNull String[] diskTokens, int diskTokenIndex,
+            @NonNull S2TileProto[] loadedTiles) throws IOException {
+        int len = cacheKeys.length;
+        int numMapCellsPerCacheTile =
+                1 << (2 * (params.getMapS2Level() - params.getCacheTileS2Level()));
+
+        // Reusable arrays.
+        long[] s2CellIds = new long[numMapCellsPerCacheTile];
+        double[] values = new double[numMapCellsPerCacheTile];
+        byte[] bytes = new byte[numMapCellsPerCacheTile];
+
+        // Each cache key identifies a different sub-tile of the same disk tile.
+        TileFunction diskTileFunction = cacheKey -> diskTile;
+        for (int i = diskTokenIndex; i < len; i++) {
+            if (!Objects.equals(diskTokens[i], diskTokens[diskTokenIndex])
+                    || loadedTiles[i] != null) {
+                continue;
+            }
+
+            // Find all map cells within the current cache tile.
+            long s2CellId = S2CellIdUtils.getTraversalStart(cacheKeys[i], params.getMapS2Level());
+            for (int j = 0; j < numMapCellsPerCacheTile; j++) {
+                s2CellIds[j] = s2CellId;
+                s2CellId = S2CellIdUtils.getTraversalNext(s2CellId);
+            }
+
+            if (!getUnitIntervalValues(params, diskTileFunction, s2CellIds, values)) {
+                throw new IOException("Corrupted disk tile of disk token: " + diskTokens[i]);
+            }
+
+            for (int j = 0; j < numMapCellsPerCacheTile; j++) {
+                bytes[j] = (byte) Math.round(values[j] * 0xFF);
+            }
+            loadedTiles[i] =
+                    S2TileProto.newBuilder().setByteBuffer(ByteString.copyFrom(bytes)).build();
+
+            // Batch across common cache key.
+            for (int j = i + 1; j < len; j++) {
+                if (cacheKeys[j] == cacheKeys[i]) {
+                    loadedTiles[j] = loadedTiles[i];
+                }
+            }
+
+            // Side load into tile cache.
+            mCacheTiles.put(cacheKeys[i], loadedTiles[i]);
+        }
+    }
+
+    /** Defines a function-like object to retrieve tiles for cache keys. */
+    private interface TileFunction {
+
+        @Nullable
+        S2TileProto getTile(long cacheKey);
+    }
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/S2CellIdUtils.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/S2CellIdUtils.java
new file mode 100644
index 0000000..1c09c33
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/S2CellIdUtils.java
@@ -0,0 +1,662 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl;
+
+import androidx.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+/**
+ * Provides lightweight S2 cell ID utilities without traditional geometry dependencies.
+ *
+ * <p>See <a href="https://s2geometry.io/">the S2 Geometry Library website</a> for more details.
+ */
+final class S2CellIdUtils {
+
+    /** The level of all leaf S2 cells. */
+    static final int MAX_LEVEL = 30;
+
+    private static final int MAX_SIZE = 1 << MAX_LEVEL;
+    private static final double ONE_OVER_MAX_SIZE = 1.0 / MAX_SIZE;
+    private static final int NUM_FACES = 6;
+    private static final int POS_BITS = 2 * MAX_LEVEL + 1;
+    private static final int SWAP_MASK = 0x1;
+    private static final int LOOKUP_BITS = 4;
+    private static final int LOOKUP_MASK = (1 << LOOKUP_BITS) - 1;
+    private static final int INVERT_MASK = 0x2;
+    private static final int LEAF_MASK = 0x1;
+    private static final int[] LOOKUP_POS = new int[1 << (2 * LOOKUP_BITS + 2)];
+    private static final int[] LOOKUP_IJ = new int[1 << (2 * LOOKUP_BITS + 2)];
+    private static final int[] POS_TO_ORIENTATION = {SWAP_MASK, 0, 0, INVERT_MASK + SWAP_MASK};
+    private static final int[][] POS_TO_IJ =
+            {{0, 1, 3, 2}, {0, 2, 3, 1}, {3, 2, 0, 1}, {3, 1, 0, 2}};
+    private static final double UV_LIMIT = calculateUvLimit();
+    private static final UvTransform[] UV_TRANSFORMS = createUvTransforms();
+    private static final XyzTransform[] XYZ_TRANSFORMS = createXyzTransforms();
+
+    // Used to encode (i, j, o) coordinates into primitive longs.
+    private static final int I_SHIFT = 33;
+    private static final int J_SHIFT = 2;
+    private static final long J_MASK = (1L << 31) - 1;
+
+    static {
+        initLookupCells();
+    }
+
+    /** Prevents instantiation. */
+    private S2CellIdUtils() {
+    }
+
+    /**
+     * Returns the leaf S2 cell ID for the specified latitude and longitude, both measured in
+     * degrees.
+     */
+    static long fromLatLngDegrees(double latDegrees, double lngDegrees) {
+        return fromLatLngRadians(Math.toRadians(latDegrees), Math.toRadians(lngDegrees));
+    }
+
+    /** Returns the leaf S2 cell ID of the specified (face, i, j) coordinate. */
+    public static long fromFij(int face, int i, int j) {
+        int bits = (face & SWAP_MASK);
+        // Update most significant bits.
+        long msb = ((long) face) << (POS_BITS - 33);
+        for (int k = 7; k >= 4; --k) {
+            bits = lookupBits(i, j, k, bits);
+            msb = updateBits(msb, k, bits);
+            bits = maskBits(bits);
+        }
+        // Update least significant bits.
+        long lsb = 0;
+        for (int k = 3; k >= 0; --k) {
+            bits = lookupBits(i, j, k, bits);
+            lsb = updateBits(lsb, k, bits);
+            bits = maskBits(bits);
+        }
+        return (((msb << 32) + lsb) << 1) + 1;
+    }
+
+    /**
+     * Returns the face of the specified S2 cell. The returned face is in [0, 5] for valid S2 cell
+     * IDs. Behavior is undefined for invalid S2 cell IDs.
+     */
+    public static int getFace(long s2CellId) {
+        return (int) (s2CellId >>> POS_BITS);
+    }
+
+    /**
+     * Returns the ID of the parent of the specified S2 cell at the specified parent level.
+     * Behavior is undefined for invalid S2 cell IDs or parent levels not in
+     * [0, {#link #getLevel(s2CellId)}[.
+     */
+    static long getParent(long s2CellId, int level) {
+        long newLsb = getLowestOnBitForLevel(level);
+        return (s2CellId & -newLsb) | newLsb;
+    }
+
+    /**
+     * Inserts into {@code neighbors} the four S2 cell IDs corresponding to the neighboring
+     * cells adjacent across the specified cell's four edges. This array must be of minimum
+     * length four, and elements at the tail end of the array not corresponding to a neighbor
+     * are set to zero. A reference to this array is returned.
+     *
+     * <p>Inserts in the order of down, right, up, and left directions, in that order. All
+     * neighbors are guaranteed to be distinct.
+     */
+    static void getEdgeNeighbors(long s2CellId, @NonNull long[] neighbors) {
+        int level = getLevel(s2CellId);
+        int size = levelToSizeIj(level);
+        int face = getFace(s2CellId);
+        long ijo = toIjo(s2CellId);
+        int i = ijoToI(ijo);
+        int j = ijoToJ(ijo);
+
+        int iPlusSize = i + size;
+        int iMinusSize = i - size;
+        int jPlusSize = j + size;
+        int jMinusSize = j - size;
+        boolean iPlusSizeLtMax = iPlusSize < MAX_SIZE;
+        boolean iMinusSizeGteZero = iMinusSize >= 0;
+        boolean jPlusSizeLtMax = jPlusSize < MAX_SIZE;
+        boolean jMinusSizeGteZero = jMinusSize >= 0;
+
+        int index = 0;
+        // Down direction.
+        neighbors[index++] = getParent(fromFijSame(face, i, jMinusSize, jMinusSizeGteZero),
+                level);
+        // Right direction.
+        neighbors[index++] = getParent(fromFijSame(face, iPlusSize, j, iPlusSizeLtMax), level);
+        // Up direction.
+        neighbors[index++] = getParent(fromFijSame(face, i, jPlusSize, jPlusSizeLtMax), level);
+        // Left direction.
+        neighbors[index++] = getParent(fromFijSame(face, iMinusSize, j, iMinusSizeGteZero),
+                level);
+
+        // Pad end of neighbor array with zeros.
+        Arrays.fill(neighbors, index, neighbors.length, 0);
+    }
+
+    /** Returns the "i" coordinate for the specified S2 cell. */
+    static int getI(long s2CellId) {
+        return ijoToI(toIjo(s2CellId));
+    }
+
+    /** Returns the "j" coordinate for the specified S2 cell. */
+    static int getJ(long s2CellId) {
+        return ijoToJ(toIjo(s2CellId));
+    }
+
+    /**
+     * Returns the leaf S2 cell ID for the specified latitude and longitude, both measured in
+     * radians.
+     */
+    private static long fromLatLngRadians(double latRadians, double lngRadians) {
+        double cosLat = Math.cos(latRadians);
+        double x = Math.cos(lngRadians) * cosLat;
+        double y = Math.sin(lngRadians) * cosLat;
+        double z = Math.sin(latRadians);
+        return fromXyz(x, y, z);
+    }
+
+    /**
+     * Returns the level of the specified S2 cell. The returned level is in [0, 30] for valid
+     * S2 cell IDs. Behavior is undefined for invalid S2 cell IDs.
+     */
+    static int getLevel(long s2CellId) {
+        if (isLeaf(s2CellId)) {
+            return MAX_LEVEL;
+        }
+        return MAX_LEVEL - (Long.numberOfTrailingZeros(s2CellId) >> 1);
+    }
+
+    /** Returns the lowest-numbered bit that is on for the specified S2 cell. */
+    static long getLowestOnBit(long s2CellId) {
+        return s2CellId & -s2CellId;
+    }
+
+    /** Returns the lowest-numbered bit that is on for any S2 cell on the specified level. */
+    static long getLowestOnBitForLevel(int level) {
+        return 1L << (2 * (MAX_LEVEL - level));
+    }
+
+    /**
+     * Returns the ID of the first S2 cell in a traversal of children map S2 cells, in Hilbert curve
+     * order.
+     */
+    static long getTraversalStart(long s2CellId, int level) {
+        return s2CellId - getLowestOnBit(s2CellId) + getLowestOnBitForLevel(level);
+    }
+
+    /** Returns the ID of the next S2 cell at the same level along the Hilbert curve. */
+    static long getTraversalNext(long s2CellId) {
+        return s2CellId + (getLowestOnBit(s2CellId) << 1);
+    }
+
+    /**
+     * Encodes the S2 cell id to compact text strings suitable for display or indexing. Cells at
+     * lower levels (i.e., larger cells) are encoded into fewer characters.
+     */
+    @NonNull
+    static String getToken(long s2CellId) {
+        if (s2CellId == 0) {
+            return "X";
+        }
+
+        // Convert to a hex string with as many digits as necessary.
+        String hex = Long.toHexString(s2CellId).toLowerCase(Locale.US);
+        // Prefix 0s to get a length 16 string.
+        String padded = padStart(hex);
+        // Trim zeroes off the end.
+        return padded.replaceAll("0*$", "");
+    }
+
+    private static String padStart(String string) {
+        if (string.length() >= 16) {
+            return string;
+        }
+        StringBuilder sb = new StringBuilder(16);
+        for (int i = string.length(); i < 16; i++) {
+            sb.append('0');
+        }
+        sb.append(string);
+        return sb.toString();
+    }
+
+    /** Returns the leaf S2 cell ID of the specified (x, y, z) coordinate. */
+    private static long fromXyz(double x, double y, double z) {
+        int face = xyzToFace(x, y, z);
+        UvTransform uvTransform = UV_TRANSFORMS[face];
+        double u = uvTransform.xyzToU(x, y, z);
+        double v = uvTransform.xyzToV(x, y, z);
+        return fromFuv(face, u, v);
+    }
+
+    /** Returns the leaf S2 cell ID of the specified (face, u, v) coordinate. */
+    private static long fromFuv(int face, double u, double v) {
+        int i = uToI(u);
+        int j = vToJ(v);
+        return fromFij(face, i, j);
+    }
+
+    private static long fromFijWrap(int face, int i, int j) {
+        double u = iToU(i);
+        double v = jToV(j);
+
+        XyzTransform xyzTransform = XYZ_TRANSFORMS[face];
+        double x = xyzTransform.uvToX(u, v);
+        double y = xyzTransform.uvToY(u, v);
+        double z = xyzTransform.uvToZ(u, v);
+
+        int newFace = xyzToFace(x, y, z);
+        UvTransform uvTransform = UV_TRANSFORMS[newFace];
+        double newU = uvTransform.xyzToU(x, y, z);
+        double newV = uvTransform.xyzToV(x, y, z);
+
+        int newI = uShiftIntoI(newU);
+        int newJ = vShiftIntoJ(newV);
+        return fromFij(newFace, newI, newJ);
+    }
+
+    private static long fromFijSame(int face, int i, int j, boolean isSameFace) {
+        if (isSameFace) {
+            return fromFij(face, i, j);
+        }
+        return fromFijWrap(face, i, j);
+    }
+
+    /**
+     * Returns the face associated with the specified (x, y, z) coordinate. For a coordinate
+     * on a face boundary, the returned face is arbitrary but repeatable.
+     */
+    private static int xyzToFace(double x, double y, double z) {
+        double absX = Math.abs(x);
+        double absY = Math.abs(y);
+        double absZ = Math.abs(z);
+        if (absX > absY) {
+            if (absX > absZ) {
+                return (x < 0) ? 3 : 0;
+            }
+            return (z < 0) ? 5 : 2;
+        }
+        if (absY > absZ) {
+            return (y < 0) ? 4 : 1;
+        }
+        return (z < 0) ? 5 : 2;
+    }
+
+    private static int uToI(double u) {
+        double s;
+        if (u >= 0) {
+            s = 0.5 * Math.sqrt(1 + 3 * u);
+        } else {
+            s = 1 - 0.5 * Math.sqrt(1 - 3 * u);
+        }
+        return Math.max(0, Math.min(MAX_SIZE - 1, (int) Math.round(MAX_SIZE * s - 0.5)));
+    }
+
+    private static int vToJ(double v) {
+        // Same calculation as uToI.
+        return uToI(v);
+    }
+
+    private static int lookupBits(int i, int j, int k, int bits) {
+        bits += ((i >> (k * LOOKUP_BITS)) & LOOKUP_MASK) << (LOOKUP_BITS + 2);
+        bits += ((j >> (k * LOOKUP_BITS)) & LOOKUP_MASK) << 2;
+        return LOOKUP_POS[bits];
+    }
+
+    private static long updateBits(long sb, int k, int bits) {
+        return sb | ((((long) bits) >> 2) << ((k & 0x3) * 2 * LOOKUP_BITS));
+    }
+
+    private static int maskBits(int bits) {
+        return bits & (SWAP_MASK | INVERT_MASK);
+    }
+
+    private static boolean isLeaf(long s2CellId) {
+        return ((int) s2CellId & LEAF_MASK) != 0;
+    }
+
+    private static double iToU(int i) {
+        int satI = Math.max(-1, Math.min(MAX_SIZE, i));
+        return Math.max(
+                -UV_LIMIT,
+                Math.min(UV_LIMIT, ONE_OVER_MAX_SIZE * ((satI << 1) + 1 - MAX_SIZE)));
+    }
+
+    private static double jToV(int j) {
+        // Same calculation as iToU.
+        return iToU(j);
+    }
+
+    private static long toIjo(long s2CellId) {
+        int face = getFace(s2CellId);
+        int bits = face & SWAP_MASK;
+        int i = 0;
+        int j = 0;
+        for (int k = 7; k >= 0; --k) {
+            int nbits = (k == 7) ? (MAX_LEVEL - 7 * LOOKUP_BITS) : LOOKUP_BITS;
+            bits += ((int) (s2CellId >>> (k * 2 * LOOKUP_BITS + 1)) & ((1 << (2 * nbits))
+                    - 1)) << 2;
+            bits = LOOKUP_IJ[bits];
+            i += (bits >> (LOOKUP_BITS + 2)) << (k * LOOKUP_BITS);
+            j += ((bits >> 2) & ((1 << LOOKUP_BITS) - 1)) << (k * LOOKUP_BITS);
+            bits &= (SWAP_MASK | INVERT_MASK);
+        }
+        int orientation =
+                ((getLowestOnBit(s2CellId) & 0x1111111111111110L) != 0) ? (bits ^ SWAP_MASK)
+                        : bits;
+        return (((long) i) << I_SHIFT) | (((long) j) << J_SHIFT) | orientation;
+    }
+
+    private static int ijoToI(long ijo) {
+        return (int) (ijo >>> I_SHIFT);
+    }
+
+    private static int ijoToJ(long ijo) {
+        return (int) ((ijo >>> J_SHIFT) & J_MASK);
+    }
+
+    private static int uShiftIntoI(double u) {
+        double s = 0.5 * (u + 1);
+        return Math.max(0, Math.min(MAX_SIZE - 1, (int) Math.round(MAX_SIZE * s - 0.5)));
+    }
+
+    private static int vShiftIntoJ(double v) {
+        // Same calculation as uShiftIntoI.
+        return uShiftIntoI(v);
+    }
+
+    private static int levelToSizeIj(int level) {
+        return 1 << (MAX_LEVEL - level);
+    }
+
+    private static void initLookupCells() {
+        initLookupCell(0, 0, 0, 0, 0, 0);
+        initLookupCell(0, 0, 0, SWAP_MASK, 0, SWAP_MASK);
+        initLookupCell(0, 0, 0, INVERT_MASK, 0, INVERT_MASK);
+        initLookupCell(0, 0, 0, SWAP_MASK | INVERT_MASK, 0, SWAP_MASK | INVERT_MASK);
+    }
+
+    private static void initLookupCell(
+            int level, int i, int j, int origOrientation, int pos, int orientation) {
+        if (level == LOOKUP_BITS) {
+            int ij = (i << LOOKUP_BITS) + j;
+            LOOKUP_POS[(ij << 2) + origOrientation] = (pos << 2) + orientation;
+            LOOKUP_IJ[(pos << 2) + origOrientation] = (ij << 2) + orientation;
+        } else {
+            level++;
+            i <<= 1;
+            j <<= 1;
+            pos <<= 2;
+            for (int subPos = 0; subPos < 4; subPos++) {
+                int ij = POS_TO_IJ[orientation][subPos];
+                int orientationMask = POS_TO_ORIENTATION[subPos];
+                initLookupCell(
+                        level,
+                        i + (ij >>> 1),
+                        j + (ij & 0x1),
+                        origOrientation,
+                        pos + subPos,
+                        orientation ^ orientationMask);
+            }
+        }
+    }
+
+    private static double calculateUvLimit() {
+        double machEps = 1.0;
+        do {
+            machEps /= 2.0f;
+        } while ((1.0 + (machEps / 2.0)) != 1.0);
+        return 1.0 + machEps;
+    }
+
+    @NonNull
+    private static UvTransform[] createUvTransforms() {
+        UvTransform[] uvTransforms = new UvTransform[NUM_FACES];
+        uvTransforms[0] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return y / x;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return z / x;
+                    }
+                };
+        uvTransforms[1] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return -x / y;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return z / y;
+                    }
+                };
+        uvTransforms[2] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return -x / z;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return -y / z;
+                    }
+                };
+        uvTransforms[3] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return z / x;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return y / x;
+                    }
+                };
+        uvTransforms[4] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return z / y;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return -x / y;
+                    }
+                };
+        uvTransforms[5] =
+                new UvTransform() {
+
+                    @Override
+                    public double xyzToU(double x, double y, double z) {
+                        return -y / z;
+                    }
+
+                    @Override
+                    public double xyzToV(double x, double y, double z) {
+                        return -x / z;
+                    }
+                };
+        return uvTransforms;
+    }
+
+    @NonNull
+    private static XyzTransform[] createXyzTransforms() {
+        XyzTransform[] xyzTransforms = new XyzTransform[NUM_FACES];
+        xyzTransforms[0] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return 1;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return u;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return v;
+                    }
+                };
+        xyzTransforms[1] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return -u;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return 1;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return v;
+                    }
+                };
+        xyzTransforms[2] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return -u;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return -v;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return 1;
+                    }
+                };
+        xyzTransforms[3] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return -1;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return -v;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return -u;
+                    }
+                };
+        xyzTransforms[4] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return v;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return -1;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return -u;
+                    }
+                };
+        xyzTransforms[5] =
+                new XyzTransform() {
+
+                    @Override
+                    public double uvToX(double u, double v) {
+                        return v;
+                    }
+
+                    @Override
+                    public double uvToY(double u, double v) {
+                        return u;
+                    }
+
+                    @Override
+                    public double uvToZ(double u, double v) {
+                        return -1;
+                    }
+                };
+        return xyzTransforms;
+    }
+
+    /**
+     * Transform from (x, y, z) coordinates to (u, v) coordinates, indexed by face. For a
+     * (x, y, z) coordinate within a face, each element of the resulting (u, v) coordinate
+     * should lie in the inclusive range [-1, 1], with the face center having a (u, v)
+     * coordinate equal to (0, 0).
+     */
+    private interface UvTransform {
+
+        /**
+         * Returns for the specified (x, y, z) coordinate the corresponding u-coordinate
+         * (which may lie outside the range [-1, 1]).
+         */
+        double xyzToU(double x, double y, double z);
+
+        /**
+         * Returns for the specified (x, y, z) coordinate the corresponding v-coordinate
+         * (which may lie outside the range [-1, 1]).
+         */
+        double xyzToV(double x, double y, double z);
+    }
+
+    /**
+     * Transform from (u, v) coordinates to (x, y, z) coordinates, indexed by face. The
+     * resulting vectors are not necessarily of unit length.
+     */
+    private interface XyzTransform {
+
+        /** Returns for the specified (u, v) coordinate the corresponding x-coordinate. */
+        double uvToX(double u, double v);
+
+        /** Returns for the specified (u, v) coordinate the corresponding y-coordinate. */
+        double uvToY(double u, double v);
+
+        /** Returns for the specified (u, v) coordinate the corresponding z-coordinate. */
+        double uvToZ(double u, double v);
+    }
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/AltitudeConverterDatabase.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/AltitudeConverterDatabase.java
new file mode 100644
index 0000000..b84b467
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/AltitudeConverterDatabase.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl.db;
+
+import androidx.annotation.NonNull;
+import androidx.core.location.altitude.impl.AltitudeConverter;
+import androidx.room.Database;
+import androidx.room.RoomDatabase;
+import androidx.room.TypeConverters;
+
+/** Defines the resource database for {@link AltitudeConverter}. */
+@Database(entities = {MapParamsEntity.class, TilesEntity.class}, version = 1, exportSchema = false)
+@TypeConverters({MapParamsEntity.class, TilesEntity.class})
+public abstract class AltitudeConverterDatabase extends RoomDatabase {
+
+    /** Returns the data access object for the MapParams table. */
+    @NonNull
+    public abstract MapParamsDao mapParamsDao();
+
+    /** Returns the data access object for the Tiles table. */
+    @NonNull
+    public abstract TilesDao tilesDao();
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsDao.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsDao.java
new file mode 100644
index 0000000..c5e18b8
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsDao.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl.db;
+
+import androidx.annotation.Nullable;
+import androidx.room.Dao;
+import androidx.room.Query;
+
+/** Provides data access for entities within the MapParams table. */
+@Dao
+public interface MapParamsDao {
+
+    /** Returns the most current map parameters. */
+    @Nullable
+    @Query("SELECT * FROM MapParams ORDER BY id DESC LIMIT 1")
+    MapParamsEntity getCurrent();
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsEntity.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsEntity.java
new file mode 100644
index 0000000..7b27678
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/MapParamsEntity.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl.db;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.location.altitude.impl.proto.InvalidProtocolBufferException;
+import androidx.core.location.altitude.impl.proto.MapParamsProto;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+import androidx.room.TypeConverter;
+
+import com.google.auto.value.AutoValue;
+import com.google.auto.value.AutoValue.CopyAnnotations;
+
+import org.jetbrains.annotations.Contract;
+
+/** Defines the entity type and its converters within the MapParams table. */
+@AutoValue
+@Entity(tableName = "MapParams")
+public abstract class MapParamsEntity {
+
+    private static final String TAG = "MapParamsEntity";
+
+    @NonNull
+    @Contract("_, _ -> new")
+    static MapParamsEntity create(int id, MapParamsProto value) {
+        return new AutoValue_MapParamsEntity(id, value);
+    }
+
+    /** Encodes a {@link MapParamsProto} */
+    @NonNull
+    @TypeConverter
+    public static byte[] fromValue(@NonNull MapParamsProto value) {
+        return value.toByteArray();
+    }
+
+    /** Decodes a {@link MapParamsProto} */
+    @Nullable
+    @TypeConverter
+    public static MapParamsProto toValue(@NonNull byte[] byteArray) {
+        try {
+            return MapParamsProto.parseFrom(byteArray);
+        } catch (InvalidProtocolBufferException e) {
+            Log.e(TAG, "Unable to parse map params.");
+            return null;
+        }
+    }
+
+    @CopyAnnotations
+    @PrimaryKey
+    @ColumnInfo(name = "id")
+    abstract int id();
+
+    /**
+     * Returns parameters for a spherically projected geoid map and corresponding tile management.
+     */
+    @CopyAnnotations
+    @ColumnInfo(name = "value")
+    @NonNull
+    public abstract MapParamsProto value();
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesDao.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesDao.java
new file mode 100644
index 0000000..719d171
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesDao.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl.db;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.room.Dao;
+import androidx.room.Query;
+
+/** Provides data access for entities within the Tiles table. */
+@Dao
+public interface TilesDao {
+
+    /** Returns the tile associated with the provided token. */
+    @Nullable
+    @Query("SELECT * FROM Tiles WHERE token = :token LIMIT 1")
+    TilesEntity get(@NonNull String token);
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesEntity.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesEntity.java
new file mode 100644
index 0000000..6b3f29f
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/TilesEntity.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.location.altitude.impl.db;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.location.altitude.impl.proto.InvalidProtocolBufferException;
+import androidx.core.location.altitude.impl.proto.S2TileProto;
+import androidx.room.ColumnInfo;
+import androidx.room.Entity;
+import androidx.room.PrimaryKey;
+import androidx.room.TypeConverter;
+
+import com.google.auto.value.AutoValue;
+import com.google.auto.value.AutoValue.CopyAnnotations;
+
+/** Defines the entity type and its converters within the Tiles table. */
+@AutoValue
+@Entity(tableName = "Tiles")
+public abstract class TilesEntity {
+
+    private static final String TAG = "MapParamsEntity";
+
+    static TilesEntity create(String token, S2TileProto tile) {
+        return new AutoValue_TilesEntity(token, tile);
+    }
+
+    /** Encodes a {@link S2TileProto}. */
+    @NonNull
+    @TypeConverter
+    public static byte[] fromTile(@NonNull S2TileProto tile) {
+        return tile.toByteArray();
+    }
+
+    /** Decodes a {@link S2TileProto}. */
+    @Nullable
+    @TypeConverter
+    public static S2TileProto toTile(@NonNull byte[] byteArray) {
+        try {
+            return S2TileProto.parseFrom(byteArray);
+        } catch (InvalidProtocolBufferException e) {
+            Log.e(TAG, "Unable to parse tile.");
+            return null;
+        }
+    }
+
+    /** Returns an identifier for a tile within an S2 cell ID to unit interval map. */
+    @CopyAnnotations
+    @PrimaryKey
+    @ColumnInfo(name = "token")
+    @NonNull
+    public abstract String token();
+
+    /** Returns a tile within an S2 cell ID to unit interval map. */
+    @CopyAnnotations
+    @ColumnInfo(name = "tile")
+    @NonNull
+    public abstract S2TileProto tile();
+}
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/package-info.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/package-info.java
new file mode 100644
index 0000000..fa7d778
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/db/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @hide */
+@RestrictTo(LIBRARY)
+package androidx.core.location.altitude.impl.db;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import androidx.annotation.RestrictTo;
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/package-info.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/package-info.java
new file mode 100644
index 0000000..c61153e
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @hide */
+@RestrictTo(LIBRARY)
+package androidx.core.location.altitude.impl;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import androidx.annotation.RestrictTo;
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/proto/package-info.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/proto/package-info.java
new file mode 100644
index 0000000..81aad0e
--- /dev/null
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/impl/proto/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/** @hide */
+@RestrictTo(LIBRARY)
+package androidx.core.location.altitude.impl.proto;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import androidx.annotation.RestrictTo;
diff --git a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/package-info.java b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/package-info.java
index b9ddfaa..cf031ab 100644
--- a/core/core-location-altitude/src/main/java/androidx/core/location/altitude/package-info.java
+++ b/core/core-location-altitude/src/main/java/androidx/core/location/altitude/package-info.java
@@ -14,7 +14,5 @@
  * limitations under the License.
  */
 
-/**
- * Provides compatibility APIs concerning location altitudes.
- */
+/** Provides compatibility APIs concerning location altitudes. */
 package androidx.core.location.altitude;
diff --git a/core/core-performance-play-services/build.gradle b/core/core-performance-play-services/build.gradle
index 5ed74ea..f6643d6 100644
--- a/core/core-performance-play-services/build.gradle
+++ b/core/core-performance-play-services/build.gradle
@@ -26,7 +26,6 @@
     api(libs.kotlinStdlib)
 
     implementation(libs.kotlinCoroutinesCore)
-    implementation(libs.playServicesDevicePerformance)
     implementation(project(":core:core-performance"))
 
     testImplementation(libs.testCore)
diff --git a/core/core-performance/src/test/resources/robolectric.properties b/core/core-performance/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/core/core-performance/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/core/core-telecom/OWNERS b/core/core-telecom/OWNERS
new file mode 100644
index 0000000..7de7eb4
--- /dev/null
+++ b/core/core-telecom/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 151185
+breadley@google.com
+tgunn@google.com
+xiaotonj@google.com
+chinmayd@google.com
+tjstuart@google.com
+rgreenwalt@google.com
+pmadapurmath@google.com
+grantmenke@google.com
diff --git a/core/core-telecom/api/current.txt b/core/core-telecom/api/current.txt
new file mode 100644
index 0000000..aa73740
--- /dev/null
+++ b/core/core-telecom/api/current.txt
@@ -0,0 +1,98 @@
+// Signature format: 4.0
+package androidx.core.telecom {
+
+  public final class CallAttributesCompat {
+    ctor public CallAttributesCompat(CharSequence displayName, android.net.Uri address, int direction, optional int callType, optional int callCapabilities);
+    method public android.net.Uri getAddress();
+    method public int getCallCapabilities();
+    method public int getCallType();
+    method public int getDirection();
+    method public CharSequence getDisplayName();
+    property public final android.net.Uri address;
+    property public final int callCapabilities;
+    property public final int callType;
+    property public final int direction;
+    property public final CharSequence displayName;
+    field public static final int CALL_TYPE_AUDIO_CALL = 1; // 0x1
+    field public static final int CALL_TYPE_VIDEO_CALL = 2; // 0x2
+    field public static final androidx.core.telecom.CallAttributesCompat.Companion Companion;
+    field public static final int DIRECTION_INCOMING = 1; // 0x1
+    field public static final int DIRECTION_OUTGOING = 2; // 0x2
+    field public static final int SUPPORTS_SET_INACTIVE = 2; // 0x2
+    field public static final int SUPPORTS_STREAM = 4; // 0x4
+    field public static final int SUPPORTS_TRANSFER = 8; // 0x8
+  }
+
+  public static final class CallAttributesCompat.Companion {
+  }
+
+  public interface CallControlCallback {
+    method public suspend Object? onAnswer(int callType, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onDisconnect(android.telecom.DisconnectCause disconnectCause, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onSetActive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onSetInactive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public interface CallControlScope {
+    method public suspend Object? answer(int callType, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? disconnect(android.telecom.DisconnectCause disconnectCause, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> getAvailableEndpoints();
+    method public android.os.ParcelUuid getCallId();
+    method public kotlinx.coroutines.flow.Flow<androidx.core.telecom.CallEndpointCompat> getCurrentCallEndpoint();
+    method public kotlinx.coroutines.flow.Flow<java.lang.Boolean> isMuted();
+    method public suspend Object? requestEndpointChange(androidx.core.telecom.CallEndpointCompat endpoint, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? setActive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public void setCallback(androidx.core.telecom.CallControlCallback callControlCallback);
+    method public suspend Object? setInactive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    property public abstract kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> availableEndpoints;
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.core.telecom.CallEndpointCompat> currentCallEndpoint;
+    property public abstract kotlinx.coroutines.flow.Flow<java.lang.Boolean> isMuted;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class CallEndpointCompat {
+    ctor public CallEndpointCompat(CharSequence name, int type, android.os.ParcelUuid identifier);
+    method public android.os.ParcelUuid getIdentifier();
+    method public CharSequence getName();
+    method public int getType();
+    property public final android.os.ParcelUuid identifier;
+    property public final CharSequence name;
+    property public final int type;
+    field public static final androidx.core.telecom.CallEndpointCompat.Companion Companion;
+    field public static final int TYPE_BLUETOOTH = 2; // 0x2
+    field public static final int TYPE_EARPIECE = 1; // 0x1
+    field public static final int TYPE_SPEAKER = 4; // 0x4
+    field public static final int TYPE_STREAMING = 5; // 0x5
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
+  }
+
+  public static final class CallEndpointCompat.Companion {
+  }
+
+  public final class CallException extends java.lang.RuntimeException {
+    ctor public CallException(optional int code, optional String? message);
+    method public int getCode();
+    property public final int code;
+    field public static final androidx.core.telecom.CallException.Companion Companion;
+    field public static final int ERROR_CALLBACKS_CODE = 2; // 0x2
+    field public static final int ERROR_UNKNOWN_CODE = 1; // 0x1
+  }
+
+  public static final class CallException.Companion {
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class CallsManager {
+    ctor public CallsManager(android.content.Context context);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public suspend Object? addCall(androidx.core.telecom.CallAttributesCompat callAttributes, kotlin.jvm.functions.Function1<? super androidx.core.telecom.CallControlScope,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(int capabilities);
+    field public static final int CAPABILITY_BASELINE = 1; // 0x1
+    field public static final int CAPABILITY_SUPPORTS_CALL_STREAMING = 4; // 0x4
+    field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 2; // 0x2
+    field public static final androidx.core.telecom.CallsManager.Companion Companion;
+  }
+
+  public static final class CallsManager.Companion {
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/core/core-telecom/api/res-current.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to core/core-telecom/api/res-current.txt
diff --git a/core/core-telecom/api/restricted_current.txt b/core/core-telecom/api/restricted_current.txt
new file mode 100644
index 0000000..8c6ce9f
--- /dev/null
+++ b/core/core-telecom/api/restricted_current.txt
@@ -0,0 +1,116 @@
+// Signature format: 4.0
+package androidx.core.telecom {
+
+  public final class CallAttributesCompat {
+    ctor public CallAttributesCompat(CharSequence displayName, android.net.Uri address, @androidx.core.telecom.CallAttributesCompat.Companion.Direction int direction, optional @androidx.core.telecom.CallAttributesCompat.Companion.CallType int callType, optional @androidx.core.telecom.CallAttributesCompat.Companion.CallCapability int callCapabilities);
+    method public android.net.Uri getAddress();
+    method public int getCallCapabilities();
+    method public int getCallType();
+    method public int getDirection();
+    method public CharSequence getDisplayName();
+    property public final android.net.Uri address;
+    property public final int callCapabilities;
+    property public final int callType;
+    property public final int direction;
+    property public final CharSequence displayName;
+    field public static final int CALL_TYPE_AUDIO_CALL = 1; // 0x1
+    field public static final int CALL_TYPE_VIDEO_CALL = 2; // 0x2
+    field public static final androidx.core.telecom.CallAttributesCompat.Companion Companion;
+    field public static final int DIRECTION_INCOMING = 1; // 0x1
+    field public static final int DIRECTION_OUTGOING = 2; // 0x2
+    field public static final int SUPPORTS_SET_INACTIVE = 2; // 0x2
+    field public static final int SUPPORTS_STREAM = 4; // 0x4
+    field public static final int SUPPORTS_TRANSFER = 8; // 0x8
+  }
+
+  public static final class CallAttributesCompat.Companion {
+  }
+
+  @IntDef(value={androidx.core.telecom.CallAttributesCompat.SUPPORTS_SET_INACTIVE, androidx.core.telecom.CallAttributesCompat.SUPPORTS_STREAM, androidx.core.telecom.CallAttributesCompat.SUPPORTS_TRANSFER}, flag=true) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER}) public static @interface CallAttributesCompat.Companion.CallCapability {
+  }
+
+  @IntDef({androidx.core.telecom.CallAttributesCompat.CALL_TYPE_AUDIO_CALL, androidx.core.telecom.CallAttributesCompat.CALL_TYPE_VIDEO_CALL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.PROPERTY}) public static @interface CallAttributesCompat.Companion.CallType {
+  }
+
+  @IntDef({androidx.core.telecom.CallAttributesCompat.DIRECTION_INCOMING, androidx.core.telecom.CallAttributesCompat.DIRECTION_OUTGOING}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER}) public static @interface CallAttributesCompat.Companion.Direction {
+  }
+
+  public interface CallControlCallback {
+    method public suspend Object? onAnswer(@androidx.core.telecom.CallAttributesCompat.Companion.CallType int callType, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onDisconnect(android.telecom.DisconnectCause disconnectCause, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onSetActive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? onSetInactive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
+  public interface CallControlScope {
+    method public suspend Object? answer(@androidx.core.telecom.CallAttributesCompat.Companion.CallType int callType, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? disconnect(android.telecom.DisconnectCause disconnectCause, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> getAvailableEndpoints();
+    method public android.os.ParcelUuid getCallId();
+    method public kotlinx.coroutines.flow.Flow<androidx.core.telecom.CallEndpointCompat> getCurrentCallEndpoint();
+    method public kotlinx.coroutines.flow.Flow<java.lang.Boolean> isMuted();
+    method public suspend Object? requestEndpointChange(androidx.core.telecom.CallEndpointCompat endpoint, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public suspend Object? setActive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    method public void setCallback(androidx.core.telecom.CallControlCallback callControlCallback);
+    method public suspend Object? setInactive(kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+    property public abstract kotlinx.coroutines.flow.Flow<java.util.List<androidx.core.telecom.CallEndpointCompat>> availableEndpoints;
+    property public abstract kotlinx.coroutines.flow.Flow<androidx.core.telecom.CallEndpointCompat> currentCallEndpoint;
+    property public abstract kotlinx.coroutines.flow.Flow<java.lang.Boolean> isMuted;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class CallEndpointCompat {
+    ctor public CallEndpointCompat(CharSequence name, int type, android.os.ParcelUuid identifier);
+    method public android.os.ParcelUuid getIdentifier();
+    method public CharSequence getName();
+    method public int getType();
+    property public final android.os.ParcelUuid identifier;
+    property public final CharSequence name;
+    property public final int type;
+    field public static final androidx.core.telecom.CallEndpointCompat.Companion Companion;
+    field public static final int TYPE_BLUETOOTH = 2; // 0x2
+    field public static final int TYPE_EARPIECE = 1; // 0x1
+    field public static final int TYPE_SPEAKER = 4; // 0x4
+    field public static final int TYPE_STREAMING = 5; // 0x5
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
+  }
+
+  public static final class CallEndpointCompat.Companion {
+  }
+
+  @IntDef({androidx.core.telecom.CallEndpointCompat.TYPE_UNKNOWN, androidx.core.telecom.CallEndpointCompat.TYPE_EARPIECE, androidx.core.telecom.CallEndpointCompat.TYPE_BLUETOOTH, androidx.core.telecom.CallEndpointCompat.TYPE_WIRED_HEADSET, androidx.core.telecom.CallEndpointCompat.TYPE_SPEAKER, androidx.core.telecom.CallEndpointCompat.TYPE_STREAMING}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.TYPE, kotlin.annotation.AnnotationTarget.PROPERTY, kotlin.annotation.AnnotationTarget.VALUE_PARAMETER}) public static @interface CallEndpointCompat.Companion.EndpointType {
+  }
+
+  public final class CallException extends java.lang.RuntimeException {
+    ctor public CallException(optional @androidx.core.telecom.CallException.Companion.CallErrorCode int code, optional String? message);
+    method public int getCode();
+    property public final int code;
+    field public static final androidx.core.telecom.CallException.Companion Companion;
+    field public static final int ERROR_CALLBACKS_CODE = 2; // 0x2
+    field public static final int ERROR_UNKNOWN_CODE = 1; // 0x1
+  }
+
+  public static final class CallException.Companion {
+  }
+
+  @IntDef({androidx.core.telecom.CallException.ERROR_UNKNOWN_CODE, androidx.core.telecom.CallException.ERROR_CALLBACKS_CODE}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) public static @interface CallException.Companion.CallErrorCode {
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.O) public final class CallsManager {
+    ctor public CallsManager(android.content.Context context);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public suspend Object? addCall(androidx.core.telecom.CallAttributesCompat callAttributes, kotlin.jvm.functions.Function1<? super androidx.core.telecom.CallControlScope,kotlin.Unit> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission("android.permission.MANAGE_OWN_CALLS") public void registerAppWithTelecom(@androidx.core.telecom.CallsManager.Companion.Capability int capabilities);
+    field public static final int CAPABILITY_BASELINE = 1; // 0x1
+    field public static final int CAPABILITY_SUPPORTS_CALL_STREAMING = 4; // 0x4
+    field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 2; // 0x2
+    field public static final androidx.core.telecom.CallsManager.Companion Companion;
+  }
+
+  public static final class CallsManager.Companion {
+  }
+
+  @IntDef(value={androidx.core.telecom.CallsManager.CAPABILITY_BASELINE, androidx.core.telecom.CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING, androidx.core.telecom.CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING}, flag=true) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.VALUE_PARAMETER, kotlin.annotation.AnnotationTarget.TYPE}) public static @interface CallsManager.Companion.Capability {
+  }
+
+}
+
diff --git a/core/core-telecom/build.gradle b/core/core-telecom/build.gradle
new file mode 100644
index 0000000..4d1140f
--- /dev/null
+++ b/core/core-telecom/build.gradle
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    // core-telecom dependencies
+    api(libs.kotlinStdlib)
+    api(libs.guavaListenableFuture)
+    implementation("androidx.annotation:annotation:1.4.0")
+    implementation("androidx.core:core:1.9.0")
+    implementation(libs.kotlinCoroutinesCore)
+    implementation(libs.kotlinCoroutinesGuava)
+    // Test dependencies
+    androidTestImplementation(project(":internal-testutils-common"))
+    androidTestImplementation(libs.kotlinStdlib)
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.truth)
+    androidTestImplementation(libs.espressoCore)
+    androidTestImplementation(libs.multidex)
+    androidTestImplementation(libs.kotlinCoroutinesTest)
+}
+
+android {
+    namespace "androidx.core.telecom"
+}
+
+androidx {
+    name = "androidx.core:core-telecom"
+    type = LibraryType.PUBLISHED_LIBRARY
+    mavenVersion = LibraryVersions.CORE_TELECOM
+    inceptionYear = "2023"
+    description = "Integrate VoIP calls with the Telecom framework."
+}
diff --git a/core/core-telecom/integration-tests/testapp/build.gradle b/core/core-telecom/integration-tests/testapp/build.gradle
new file mode 100644
index 0000000..582f731
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/build.gradle
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.application")
+    id("kotlin-android")
+}
+
+android {
+    namespace 'androidx.core.telecom.test'
+
+    defaultConfig {
+        applicationId "androidx.core.telecom.test"
+        minSdk 21
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+    buildFeatures {
+        viewBinding true
+    }
+}
+
+dependencies {
+    implementation(libs.constraintLayout)
+    implementation("androidx.annotation:annotation:1.4.0")
+    implementation("androidx.core:core:1.9.0")
+    implementation(project(":core:core-telecom"))
+    implementation('androidx.appcompat:appcompat:1.6.1')
+    implementation('androidx.navigation:navigation-fragment-ktx:2.5.3')
+    implementation('androidx.navigation:navigation-ui-ktx:2.5.3')
+    implementation('androidx.recyclerview:recyclerview:1.2.1')
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testRunner)
+}
+
diff --git a/core/core-telecom/integration-tests/testapp/src/main/AndroidManifest.xml b/core/core-telecom/integration-tests/testapp/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..529aa31
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/Theme.AppCompat">
+        <activity
+            android:name=".CallingMainActivity"
+            android:exported="true"
+            android:label="@string/main_activity_name"
+            android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallListAdapter.kt b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallListAdapter.kt
new file mode 100644
index 0000000..7c33fc8
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallListAdapter.kt
@@ -0,0 +1,165 @@
+/*
+ * 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.core.telecom.test
+
+import android.telecom.CallEndpoint
+import android.telecom.DisconnectCause
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.TextView
+import androidx.annotation.RequiresApi
+import androidx.recyclerview.widget.RecyclerView
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+@RequiresApi(34)
+class CallListAdapter(private var mList: ArrayList<CallRow>?) :
+    RecyclerView.Adapter<CallListAdapter.ViewHolder>() {
+
+    var mCallIdToViewHolder: MutableMap<String, ViewHolder> = mutableMapOf()
+
+    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
+        // TextViews
+        val callCount: TextView = itemView.findViewById(R.id.callNumber)
+        val callIdTextView: TextView = itemView.findViewById(R.id.callIdTextView)
+        val currentState: TextView = itemView.findViewById(R.id.callStateTextView)
+        val currentEndpoint: TextView = itemView.findViewById(R.id.endpointStateTextView)
+
+        // Call State Buttons
+        val activeButton: Button = itemView.findViewById(R.id.activeButton)
+        val holdButton: Button = itemView.findViewById(R.id.holdButton)
+        val disconnectButton: Button = itemView.findViewById(R.id.disconnectButton)
+
+        // Call Audio Buttons
+        val earpieceButton: Button = itemView.findViewById(R.id.earpieceButton)
+        val speakerButton: Button = itemView.findViewById(R.id.speakerButton)
+        val bluetoothButton: Button = itemView.findViewById(R.id.bluetoothButton)
+    }
+
+    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+        // inflates the card_view_design view that is used to hold list item
+        val view = LayoutInflater.from(parent.context)
+            .inflate(R.layout.call_row, parent, false)
+
+        return ViewHolder(view)
+    }
+
+    override fun getItemCount(): Int {
+        return mList?.size ?: 0
+    }
+
+    // Set the data for the user
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        val ItemsViewModel = mList?.get(position)
+
+        // sets the text to the textview from our itemHolder class
+        if (ItemsViewModel != null) {
+            mCallIdToViewHolder[ItemsViewModel.callObject.mTelecomCallId] = holder
+
+            holder.callCount.text = "Call # " + ItemsViewModel.callNumber.toString() + "; "
+            holder.callIdTextView.text = "ID=[" + ItemsViewModel.callObject.mTelecomCallId + "]"
+
+            holder.activeButton.setOnClickListener {
+                CoroutineScope(Dispatchers.Main).launch {
+                    if (ItemsViewModel.callObject.mCallControl!!.setActive()) {
+                        holder.currentState.text = "CurrentState=[active]"
+                    }
+                }
+            }
+
+            holder.holdButton.setOnClickListener {
+                CoroutineScope(Dispatchers.Main).launch {
+                    if (ItemsViewModel.callObject.mCallControl!!.setInactive()) {
+                        holder.currentState.text = "CurrentState=[onHold]"
+                    }
+                }
+            }
+
+            holder.disconnectButton.setOnClickListener {
+                CoroutineScope(Dispatchers.IO).launch {
+                    ItemsViewModel.callObject.mCallControl?.disconnect(
+                        DisconnectCause(
+                            DisconnectCause.LOCAL
+                        )
+                    )
+                }
+                holder.currentState.text = "CurrentState=[null]"
+                mList?.remove(ItemsViewModel)
+                this.notifyDataSetChanged()
+            }
+
+            holder.earpieceButton.setOnClickListener {
+                CoroutineScope(Dispatchers.Main).launch {
+                    val earpieceEndpoint =
+                        ItemsViewModel.callObject.getEndpointType(CallEndpoint.TYPE_EARPIECE)
+                    if (earpieceEndpoint != null) {
+                        ItemsViewModel.callObject.mCallControl?.requestEndpointChange(
+                            earpieceEndpoint
+                        )
+                    }
+                }
+            }
+            holder.speakerButton.setOnClickListener {
+                CoroutineScope(Dispatchers.Main).launch {
+                    val speakerEndpoint = ItemsViewModel.callObject
+                        .getEndpointType(CallEndpoint.TYPE_SPEAKER)
+                    if (speakerEndpoint != null) {
+                        val success = ItemsViewModel.callObject.mCallControl?.requestEndpointChange(
+                            speakerEndpoint
+                        )
+                        if (success == true) {
+                            holder.currentEndpoint.text = "currentEndpoint=[speaker]"
+                        }
+                    }
+                }
+            }
+
+            holder.bluetoothButton.setOnClickListener {
+                CoroutineScope(Dispatchers.Main).launch {
+                    val bluetoothEndpoint = ItemsViewModel.callObject
+                        .getEndpointType(CallEndpoint.TYPE_BLUETOOTH)
+                    if (bluetoothEndpoint != null) {
+                        val success = ItemsViewModel.callObject.mCallControl?.requestEndpointChange(
+                            bluetoothEndpoint
+                        )
+                        if (success == true) {
+                            holder.currentEndpoint.text =
+                                "currentEndpoint=[BT:${bluetoothEndpoint.name}]"
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    fun updateCallState(callId: String, state: String) {
+        CoroutineScope(Dispatchers.Main).launch {
+            val holder = mCallIdToViewHolder[callId]
+            holder?.callIdTextView?.text = "currentState=[$state]"
+        }
+    }
+
+    fun updateEndpoint(callId: String, endpoint: String) {
+        CoroutineScope(Dispatchers.Main).launch {
+            val holder = mCallIdToViewHolder[callId]
+            holder?.currentEndpoint?.text = "currentEndpoint=[$endpoint]"
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallRow.kt b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallRow.kt
new file mode 100644
index 0000000..484a17e
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallRow.kt
@@ -0,0 +1,19 @@
+/*
+ * 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.core.telecom.test
+
+data class CallRow(val callNumber: Int, val callObject: VoipCall)
diff --git a/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallingMainActivity.kt b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallingMainActivity.kt
new file mode 100644
index 0000000..f1cebe4
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/CallingMainActivity.kt
@@ -0,0 +1,164 @@
+/*
+ * 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.core.telecom.test
+
+import android.annotation.SuppressLint
+import android.app.Activity
+import android.os.Bundle
+import android.telecom.DisconnectCause
+import android.util.Log
+import android.widget.Button
+import android.widget.CheckBox
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.CallsManager
+import androidx.core.view.WindowCompat
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+
+@RequiresApi(34)
+class CallingMainActivity : Activity() {
+    // Activity
+    private val TAG = CallingMainActivity::class.simpleName
+    private val mScope = CoroutineScope(Dispatchers.Default)
+    private var mCallCount: Int = 0
+
+    // Telecom
+    private var mCallsManager: CallsManager? = null
+
+    // Call Log objects
+    private var mRecyclerView: RecyclerView? = null
+    private var mCallObjects: ArrayList<CallRow> = ArrayList()
+    private var mAdapter: CallListAdapter? = CallListAdapter(mCallObjects)
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        WindowCompat.setDecorFitsSystemWindows(window, false)
+        super.onCreate(savedInstanceState)
+
+        setContentView(R.layout.activity_main)
+
+        mCallsManager = CallsManager(this)
+        mCallCount = 0
+
+        val registerPhoneAccountButton = findViewById<Button>(R.id.registerButton)
+        registerPhoneAccountButton.setOnClickListener {
+            mScope.launch {
+                registerPhoneAccount()
+            }
+        }
+
+        val addOutgoingCallButton = findViewById<Button>(R.id.addOutgoingCall)
+        addOutgoingCallButton.setOnClickListener {
+            mScope.launch {
+                addCallWithAttributes(Utilities.OUTGOING_CALL_ATTRIBUTES)
+            }
+        }
+
+        val addIncomingCallButton = findViewById<Button>(R.id.addIncomingCall)
+        addIncomingCallButton.setOnClickListener {
+            mScope.launch {
+                addCallWithAttributes(Utilities.INCOMING_CALL_ATTRIBUTES)
+            }
+        }
+
+        // set up the call list view holder
+        mRecyclerView = findViewById(R.id.callListRecyclerView)
+        mRecyclerView?.layoutManager = LinearLayoutManager(this)
+        mRecyclerView?.adapter = mAdapter
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        for (call in mCallObjects) {
+            CoroutineScope(Dispatchers.IO).launch {
+                try {
+                    call.callObject.mCallControl?.disconnect(DisconnectCause(DisconnectCause.LOCAL))
+                } catch (e: Exception) {
+                    Log.i(TAG, "onDestroy: exception hit trying to destroy")
+                }
+            }
+        }
+    }
+
+    @SuppressLint("WrongConstant")
+    private fun registerPhoneAccount() {
+        var capabilities: @CallsManager.Companion.Capability Int = CallsManager.CAPABILITY_BASELINE
+
+        val videoCallingCheckBox = findViewById<CheckBox>(R.id.VideoCallingCheckBox)
+        if (videoCallingCheckBox.isChecked) {
+            capabilities = capabilities or CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING
+        }
+        val streamingCheckBox = findViewById<CheckBox>(R.id.streamingCheckBox)
+        if (streamingCheckBox.isChecked) {
+            capabilities = capabilities or CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING
+        }
+        mCallsManager?.registerAppWithTelecom(capabilities)
+    }
+
+    private suspend fun addCallWithAttributes(attributes: CallAttributesCompat) {
+        Log.i(TAG, "addCallWithAttributes: attributes=$attributes")
+        val callObject = VoipCall()
+
+        CoroutineScope(Dispatchers.IO).launch {
+            val coroutineScope = this
+            try {
+                mCallsManager!!.addCall(attributes) {
+                    // set the client callback implementation
+                    setCallback(callObject.mCallControlCallbackImpl)
+
+                    // inject client control interface into the VoIP call object
+                    callObject.setCallId(getCallId().toString())
+                    callObject.setCallControl(this)
+
+                    // Collect updates
+                    currentCallEndpoint
+                        .onEach { callObject.onCallEndpointChanged(it) }
+                        .launchIn(coroutineScope)
+
+                    availableEndpoints
+                        .onEach { callObject.onAvailableCallEndpointsChanged(it) }
+                        .launchIn(coroutineScope)
+
+                    isMuted
+                        .onEach { callObject.onMuteStateChanged(it) }
+                        .launchIn(coroutineScope)
+                }
+                addCallRow(callObject)
+            } catch (e: CancellationException) {
+                Log.i(TAG, "addCallWithAttributes: cancellationException:$e")
+            }
+        }
+    }
+
+    private fun addCallRow(callObject: VoipCall) {
+        mCallObjects.add(CallRow(++mCallCount, callObject))
+        callObject.setCallAdapter(mAdapter)
+        updateCallList()
+    }
+
+    private fun updateCallList() {
+        runOnUiThread {
+            mAdapter?.notifyDataSetChanged()
+        }
+    }
+}
diff --git a/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/Utilities.kt b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/Utilities.kt
new file mode 100644
index 0000000..13c0b67
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/Utilities.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.core.telecom.test
+
+import android.net.Uri
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.CallAttributesCompat.Companion.CALL_TYPE_VIDEO_CALL
+import androidx.core.telecom.CallAttributesCompat.Companion.DIRECTION_INCOMING
+import androidx.core.telecom.CallAttributesCompat.Companion.DIRECTION_OUTGOING
+
+@RequiresApi(34)
+class Utilities {
+    companion object {
+        const val APP_SCHEME = "MyCustomScheme"
+        const val ALL_CALL_CAPABILITIES = (CallAttributesCompat.SUPPORTS_SET_INACTIVE
+        or CallAttributesCompat.SUPPORTS_STREAM or CallAttributesCompat.SUPPORTS_TRANSFER)
+
+        // outgoing attributes constants
+        const val OUTGOING_NAME = "Darth Maul"
+        val OUTGOING_URI: Uri = Uri.parse("tel:6506958985")
+        // Define the minimal set of properties to start an outgoing call
+        var OUTGOING_CALL_ATTRIBUTES = CallAttributesCompat(
+            OUTGOING_NAME,
+            OUTGOING_URI,
+            DIRECTION_OUTGOING)
+
+        // incoming attributes constants
+        const val INCOMING_NAME = "Sundar Pichai"
+        val INCOMING_URI: Uri = Uri.parse("tel:6506958985")
+        // Define all possible properties for CallAttributes
+        val INCOMING_CALL_ATTRIBUTES =
+            CallAttributesCompat(
+                INCOMING_NAME,
+                INCOMING_URI,
+                DIRECTION_INCOMING,
+                CALL_TYPE_VIDEO_CALL,
+                ALL_CALL_CAPABILITIES)
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/VoipCall.kt b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/VoipCall.kt
new file mode 100644
index 0000000..d2decbb
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/java/androidx/core/telecom/test/VoipCall.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.core.telecom.test
+
+import android.telecom.DisconnectCause
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallControlCallback
+import androidx.core.telecom.CallControlScope
+import androidx.core.telecom.CallEndpointCompat
+
+@RequiresApi(34)
+class VoipCall {
+    private val TAG = VoipCall::class.simpleName
+
+    var mAdapter: CallListAdapter? = null
+    var mCallControl: CallControlScope? = null
+    var mCurrentEndpoint: CallEndpointCompat? = null
+    var mAvailableEndpoints: List<CallEndpointCompat>? = ArrayList()
+    var mIsMuted = false
+    var mTelecomCallId: String = ""
+
+    val mCallControlCallbackImpl = object : CallControlCallback {
+        override suspend fun onSetActive(): Boolean {
+            mAdapter?.updateCallState(mTelecomCallId, "Active")
+            return true
+        }
+        override suspend fun onSetInactive(): Boolean {
+            mAdapter?.updateCallState(mTelecomCallId, "Inactive")
+            return true
+        }
+        override suspend fun onAnswer(callType: Int): Boolean {
+            mAdapter?.updateCallState(mTelecomCallId, "Answered")
+            return true
+        }
+        override suspend fun onDisconnect(disconnectCause: DisconnectCause): Boolean {
+            mAdapter?.updateCallState(mTelecomCallId, "Disconnected")
+            return true
+        }
+    }
+
+    fun setCallControl(callControl: CallControlScope) {
+        mCallControl = callControl
+    }
+
+    fun setCallAdapter(adapter: CallListAdapter?) {
+        mAdapter = adapter
+    }
+
+    fun setCallId(callId: String) {
+        mTelecomCallId = callId
+    }
+
+    fun onCallEndpointChanged(endpoint: CallEndpointCompat) {
+        Log.i(TAG, "onCallEndpointChanged: endpoint=$endpoint")
+        mCurrentEndpoint = endpoint
+        mAdapter?.updateEndpoint(mTelecomCallId, endpoint.name.toString())
+    }
+
+    fun onAvailableCallEndpointsChanged(endpoints: List<CallEndpointCompat>) {
+        Log.i(TAG, "onAvailableCallEndpointsChanged:")
+        for (endpoint in endpoints) {
+            Log.i(TAG, "onAvailableCallEndpointsChanged: --> endpoint=$endpoint")
+        }
+        mAvailableEndpoints = endpoints
+    }
+
+    fun onMuteStateChanged(isMuted: Boolean) {
+        Log.i(TAG, "onMuteStateChanged: isMuted=$isMuted")
+        mIsMuted = isMuted
+    }
+
+    fun getEndpointType(type: Int): CallEndpointCompat? {
+        for (endpoint in mAvailableEndpoints!!) {
+            if (endpoint.type == type) {
+                return endpoint
+            }
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/drawable/android.xml b/core/core-telecom/integration-tests/testapp/src/main/res/drawable/android.xml
new file mode 100644
index 0000000..dfa932e
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/drawable/android.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="160dp"
+    android:height="160dp"
+    android:viewportHeight="432"
+    android:viewportWidth="432">
+
+    <!-- Safe zone = 66dp => 432 * (66 / 108) = 432 * 0.61 -->
+    <group
+        android:translateX="84"
+        android:translateY="84"
+        android:scaleX="0.61"
+        android:scaleY="0.61">
+
+        <path
+            android:fillColor="#3ddc84"
+            android:pathData="m322.02,167.89c12.141,-21.437 25.117,-42.497 36.765,-64.158 2.2993,-7.7566 -9.5332,-12.802 -13.555,-5.7796 -12.206,21.045 -24.375,42.112 -36.567,63.166 -57.901,-26.337 -127.00,-26.337 -184.90,0.0 -12.685,-21.446 -24.606,-43.441 -37.743,-64.562 -5.6074,-5.8390 -15.861,1.9202 -11.747,8.8889 12.030,20.823 24.092,41.629 36.134,62.446C47.866,200.90 5.0987,267.15 0.0,337.5c144.00,0.0 288.00,0.0 432.0,0.0C426.74,267.06 384.46,201.32 322.02,167.89ZM116.66,276.03c-13.076,0.58968 -22.531,-15.277 -15.773,-26.469 5.7191,-11.755 24.196,-12.482 30.824,-1.2128 7.8705,11.451 -1.1102,28.027 -15.051,27.682zM315.55,276.03c-13.076,0.58968 -22.531,-15.277 -15.773,-26.469 5.7191,-11.755 24.196,-12.482 30.824,-1.2128 7.8705,11.451 -1.1097,28.027 -15.051,27.682z"
+            android:strokeWidth="2" />
+    </group>
+</vector>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/drawable/ic_launcher.xml b/core/core-telecom/integration-tests/testapp/src/main/res/drawable/ic_launcher.xml
new file mode 100644
index 0000000..481bbd7
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/drawable/ic_launcher.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/android" />
+</layer-list>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/layout/activity_main.xml b/core/core-telecom/integration-tests/testapp/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..ae035a5
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/layout/activity_main.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true"
+    tools:context=".CallingMainActivity">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/app_name"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+
+        <CheckBox
+            android:id="@+id/VideoCallingCheckBox"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CAPABILITY_SUPPORTS_VIDEO_CALLING" />
+
+        <CheckBox
+            android:id="@+id/streamingCheckBox"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="CAPABILITY_SUPPORTS_CALL_STREAMING" />
+
+        <Button
+            android:id="@+id/registerButton"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/register_button_text"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/add_out_call_button_text"
+            android:id="@+id/addOutgoingCall"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/add_in_call_button_text"
+            android:id="@+id/addIncomingCall"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+        </LinearLayout>
+
+    </LinearLayout>
+
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/callListRecyclerView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            tools:itemCount="3" />
+
+    </LinearLayout>
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/layout/call_row.xml b/core/core-telecom/integration-tests/testapp/src/main/res/layout/call_row.xml
new file mode 100644
index 0000000..9001096
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/layout/call_row.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/callNumber"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="call # -" />
+
+        <TextView
+            android:id="@+id/callIdTextView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="callId" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+        <TextView
+            android:id="@+id/callStateTextView"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="currentCallState=[null]; " />
+
+            <TextView
+                android:id="@+id/endpointStateTextView"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="currentEndpoint=[null]" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/activeButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="Active" />
+
+            <Button
+                android:id="@+id/holdButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="Hold" />
+
+            <Button
+                android:id="@+id/disconnectButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="Disc." />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/earpieceButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="earpiece" />
+
+            <Button
+                android:id="@+id/speakerButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="speaker" />
+
+            <Button
+                android:id="@+id/bluetoothButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="bluetooth" />
+        </LinearLayout>
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values-land/dimens.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values-land/dimens.xml
new file mode 100644
index 0000000..6a160a9
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values-land/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+
+<resources>
+    <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values-w1240dp/dimens.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 0000000..ba6cad4
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+
+<resources>
+    <dimen name="fab_margin">200dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values-w600dp/dimens.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 0000000..6a160a9
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+
+<resources>
+    <dimen name="fab_margin">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values/colors.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values/colors.xml
new file mode 100644
index 0000000..d70ea01
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<resources>
+    <color name="black">#FF000000</color>
+    <color name="white">#FFFFFFFF</color>
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values/dimens.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..fc04383
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values/dimens.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+
+<resources>
+    <dimen name="fab_margin">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values/strings.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8d10c8c
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values/strings.xml
@@ -0,0 +1,31 @@
+<!--
+  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.
+  -->
+
+<resources>
+    <string name="app_name">Telecom Jetpack Test App</string>
+    <string name="main_activity_name">Tel-Jetpack Activity</string>
+    <string name="register_button_text">Register App Phone Account</string>
+    <string name="add_out_call_button_text">+ Outgoing Call </string>
+    <string name="add_in_call_button_text">+ Incoming Call </string>
+
+    <string name="action_settings">Settings</string>
+    <!-- Strings used for fragments for navigation -->
+    <string name="first_fragment_label">First Fragment</string>
+    <string name="second_fragment_label">Second Fragment</string>
+    <string name="next">Next</string>
+    <string name="previous">Previous</string>
+
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/integration-tests/testapp/src/main/res/values/themes.xml b/core/core-telecom/integration-tests/testapp/src/main/res/values/themes.xml
new file mode 100644
index 0000000..14dbff3
--- /dev/null
+++ b/core/core-telecom/integration-tests/testapp/src/main/res/values/themes.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+    <style name="Theme.Androidx.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
+    <style name="Theme.Androidx.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
+    <style name="AppTheme" parent="ThemeOverlay.AppCompat.Light" />
+</resources>
\ No newline at end of file
diff --git a/core/core-telecom/lint-baseline.xml b/core/core-telecom/lint-baseline.xml
new file mode 100644
index 0000000..0df9fc9
--- /dev/null
+++ b/core/core-telecom/lint-baseline.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+    <issue
+        id="ImplicitCastClassVerificationFailure"
+        message="This expression has type android.telecom.CallException (introduced in API level 34) but it used as type java.lang.Throwable (introduced in API level 1). Run-time class verification will not be able to validate this implicit cast on devices between these API levels."
+        errorLine1="                        openResult.completeExceptionally(reason)"
+        errorLine2="                                                         ~~~~~~">
+        <location
+            file="src/main/java/androidx/core/telecom/CallsManager.kt"/>
+    </issue>
+</issues>
diff --git a/core/core-telecom/src/androidTest/AndroidManifest.xml b/core/core-telecom/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..ec9a3d9
--- /dev/null
+++ b/core/core-telecom/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
+
+    <application>
+        <service
+            android:name="androidx.core.telecom.internal.JetpackConnectionService"
+            android:exported="true"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService"/>
+            </intent-filter>
+        </service>
+
+        <service android:name="androidx.core.telecom.utils.MockInCallService"
+            android:permission="android.permission.BIND_INCALL_SERVICE"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.telecom.InCallService"/>
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
+            <meta-data android:name="android.telecom.INCLUDE_EXTERNAL_CALLS" android:value="true" />
+            <meta-data android:name="android.telecom.INCLUDE_SELF_MANAGED_CALLS"
+                android:value="true" />
+        </service>
+
+        <activity android:name="androidx.core.telecom.utils.MockDialerActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:mimeType="vnd.android.cursor.item/phone" />
+                <data android:mimeType="vnd.android.cursor.item/person" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="voicemail" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlCallbacksTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlCallbacksTest.kt
new file mode 100644
index 0000000..1aaf4db
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlCallbacksTest.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.telecom.Call
+import android.telecom.DisconnectCause
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.internal.utils.Utils
+import androidx.core.telecom.utils.BaseTelecomTest
+import androidx.core.telecom.utils.TestUtils
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * This test class verifies the [CallControlCallback] functionality is working as intended when
+ * adding a VoIP call.  Each test should add a call via [CallsManager.addCall] but should be
+ * manipulated via the [androidx.core.telecom.utils.MockInCallService].  The MockInCallService will
+ * create a [CallControlCallback] request before changing the call state.
+ */
+@RunWith(AndroidJUnit4::class)
+@RequiresApi(VERSION_CODES.O)
+class BasicCallControlCallbacksTest : BaseTelecomTest() {
+
+    @Before
+    fun setUp() {
+        Utils.resetUtils()
+    }
+
+    @After
+    fun onDestroy() {
+        Utils.resetUtils()
+    }
+
+    /***********************************************************************************************
+     *                           V2 APIs (Android U and above) tests
+     *********************************************************************************************/
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *INCOMING* call and answer it via
+     * an InCallService that requires the [CallControlCallback.onAnswer] to accept the request. The
+     * call should use the *V2 platform APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @LargeTest
+    @Test
+    fun testBasicCallControlCallbackOperations() {
+        setUpV2Test()
+        verifyAnswerCall()
+    }
+
+    /***********************************************************************************************
+     *                           Backwards Compatibility Layer tests
+     *********************************************************************************************/
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *INCOMING* call and answer it via
+     * an InCallService that requires the [CallControlCallback.onAnswer] to accept the request.
+     * The call should use the *[android.telecom.ConnectionService] and [android.telecom.Connection]
+     * APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @LargeTest
+    @Test
+    fun testBasicCallControlCallbackOperations_BackwardsCompat() {
+        setUpBackwardsCompatTest()
+        verifyAnswerCall()
+    }
+
+    /***********************************************************************************************
+     *                           Helpers
+     *********************************************************************************************/
+
+    @Suppress("deprecation")
+    private fun verifyAnswerCall() {
+        runBlocking {
+            mCallsManager.addCall(TestUtils.INCOMING_CALL_ATTRIBUTES) {
+                setCallback(TestUtils.mCompleteAllCallControlCallbacksImpl)
+                launch {
+                    val call = TestUtils.waitOnInCallServiceToReachXCalls(1)
+                    assertNotNull("The returned Call object is <NULL>", call)
+                    assertFalse(TestUtils.mOnAnswerCallbackCalled)
+                    call!!.answer(0) // API under test
+                    TestUtils.waitOnCallState(call, Call.STATE_ACTIVE)
+                    // Assert that the callback was invoked
+                    assertTrue(TestUtils.mOnAnswerCallbackCalled)
+                    // always send the disconnect signal if possible
+                    assertTrue(disconnect(DisconnectCause(DisconnectCause.LOCAL)))
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlsTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlsTest.kt
new file mode 100644
index 0000000..94b9287
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/BasicCallControlsTest.kt
@@ -0,0 +1,268 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.telecom.DisconnectCause
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.internal.utils.Utils
+import androidx.core.telecom.utils.BaseTelecomTest
+import androidx.core.telecom.utils.TestUtils
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * This test class verifies the [CallControlScope] functionality is working as intended when adding
+ * a VoIP call.  Each test should add a call via [CallsManager.addCall] and changes the call state
+ * via the [CallControlScope].
+ *
+ * Note: Be careful with using a delay in a runBlocking scope to avoid missing flows. ex:
+ * runBlocking {
+ *      addCall(...){
+ *          delay(x time) // The flow will be emitted here and missed
+ *          currentCallEndpoint.counter.getFirst() // The flow may never be collected
+ *      }
+ * }
+ */
+@RunWith(AndroidJUnit4::class)
+@RequiresApi(VERSION_CODES.O)
+class BasicCallControlsTest : BaseTelecomTest() {
+    private val NUM_OF_TIMES_TO_TOGGLE = 3
+
+    @Before
+    fun setUp() {
+        Utils.resetUtils()
+    }
+
+    @After
+    fun onDestroy() {
+        Utils.resetUtils()
+    }
+
+    /***********************************************************************************************
+     *                           V2 APIs (Android U and above) tests
+     *********************************************************************************************/
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *OUTGOING* call and set it active. The
+     * call should use the *V2 platform APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @LargeTest
+    @Test
+    fun testBasicOutgoingCall() {
+        setUpV2Test()
+        runBlocking_addCallAndSetActive(TestUtils.OUTGOING_CALL_ATTRIBUTES)
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *INCOMING* call and answer it. The
+     * call should use the *V2 platform APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @LargeTest
+    @Test
+    fun testBasicIncomingCall() {
+        setUpV2Test()
+        runBlocking_addCallAndSetActive(TestUtils.INCOMING_CALL_ATTRIBUTES)
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add a call and **TOGGLE** active and inactive.
+     * The call should use the *V2 platform APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @LargeTest
+    @Test
+    fun testTogglingHoldOnActiveCall() {
+        setUpV2Test()
+        runBlocking_ToggleCallAsserts()
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add a call and request a new
+     * [CallEndpointCompat] via [CallControlScope.requestEndpointChange].
+     * The call should use the *V2 platform APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @LargeTest
+    @Test
+    fun testRequestEndpointChange() {
+        setUpV2Test()
+        runBlocking_RequestEndpointChangeAsserts()
+    }
+
+    /***********************************************************************************************
+     *                           Backwards Compatibility Layer tests
+     *********************************************************************************************/
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *OUTGOING* call and set it active. The
+     * call should use the *[android.telecom.ConnectionService] and [android.telecom.Connection]
+     * APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @LargeTest
+    @Test
+    fun testBasicOutgoingCall_BackwardsCompat() {
+        setUpBackwardsCompatTest()
+        runBlocking_addCallAndSetActive(TestUtils.OUTGOING_CALL_ATTRIBUTES)
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add an *INCOMING* call and answer it.
+     * The call should use the *[android.telecom.ConnectionService] and [android.telecom.Connection]
+     * APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @LargeTest
+    @Test
+    fun testBasicIncomingCall_BackwardsCompat() {
+        setUpBackwardsCompatTest()
+        runBlocking_addCallAndSetActive(TestUtils.INCOMING_CALL_ATTRIBUTES)
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add a call and **TOGGLE** active and inactive.
+     * The call should use the *[android.telecom.ConnectionService] and [android.telecom.Connection]
+     * APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @LargeTest
+    @Test
+    fun testTogglingHoldOnActiveCall_BackwardsCompat() {
+        setUpBackwardsCompatTest()
+        runBlocking_ToggleCallAsserts()
+    }
+
+    /**
+     * assert [CallsManager.addCall] can successfully add a call and request a new
+     * [CallEndpointCompat] via [CallControlScope.requestEndpointChange].
+     * The call should use the *[android.telecom.ConnectionService] and [android.telecom.Connection]
+     * APIs* under the hood.
+     */
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @LargeTest
+    @Test
+    fun testRequestEndpointChange_BackwardsCompat() {
+        setUpBackwardsCompatTest()
+        runBlocking_RequestEndpointChangeAsserts()
+        // TODO:: tracking bug: b/283324578. This test passes when the request is sent off and does
+        // not actually verify the request was successful. Need to change the impl. details.
+    }
+
+    /***********************************************************************************************
+     *                           Helpers
+     *********************************************************************************************/
+
+    /**
+     * This helper facilitates adding a call, setting it active or answered, and disconnecting.
+     *
+     * Note: delays are inserted to simulate more natural calling. Otherwise the call dumpsys
+     * does not reflect realistic transitions.
+     *
+     * Note: This helper blocks the TestRunner from finishing until all asserts and async functions
+     * have finished or the timeout has been reached.
+     */
+    private fun runBlocking_addCallAndSetActive(callAttributesCompat: CallAttributesCompat) {
+        runBlocking {
+            val deferred = CompletableDeferred<Unit>()
+            assertWithinTimeout_addCall(deferred, callAttributesCompat) {
+                launch {
+                    if (callAttributesCompat.isOutgoingCall()) {
+                        assertTrue(setActive())
+                    } else {
+                        assertTrue(answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL))
+                    }
+                    assertTrue(disconnect(DisconnectCause(DisconnectCause.LOCAL)))
+                    deferred.complete(Unit) // completed all asserts. cancel timeout!
+                }
+            }
+        }
+    }
+
+    // similar to runBlocking_addCallAndSetActive except for toggling
+    private fun runBlocking_ToggleCallAsserts() {
+        runBlocking {
+            val deferred = CompletableDeferred<Unit>()
+            assertWithinTimeout_addCall(deferred, TestUtils.OUTGOING_CALL_ATTRIBUTES) {
+                launch {
+                    repeat(NUM_OF_TIMES_TO_TOGGLE) {
+                        assertTrue(setActive())
+                        assertTrue(setInactive())
+                    }
+                    assertTrue(disconnect(DisconnectCause(DisconnectCause.LOCAL)))
+                    deferred.complete(Unit) // completed all asserts. cancel timeout!
+                }
+            }
+        }
+    }
+
+    // similar to runBlocking_addCallAndSetActive except for requesting a new call endpoint
+    private fun runBlocking_RequestEndpointChangeAsserts() {
+        runBlocking {
+            val deferred = CompletableDeferred<Unit>()
+            assertWithinTimeout_addCall(deferred, TestUtils.OUTGOING_CALL_ATTRIBUTES) {
+                launch {
+                    // ============================================================================
+                    //   NOTE:: DO NOT DELAY BEFORE COLLECTING FLOWS OR THEY COULD BE MISSED!!
+                    // ============================================================================
+                    val currentEndpoint = currentCallEndpoint.first()
+                    assertNotNull("currentEndpoint is null", currentEndpoint)
+                    val availableEndpointsList = availableEndpoints.first()
+                    // only run the following asserts if theres another endpoint available
+                    // (This will most likely the speaker endpoint)
+                    if (availableEndpointsList.size > 1) {
+                        // grab another endpoint
+                        val anotherEndpoint =
+                            getAnotherEndpoint(currentEndpoint, availableEndpointsList)
+                        assertNotNull(anotherEndpoint)
+                        // set the call active
+                        assertTrue(setActive())
+                        // request an endpoint switch
+                        assertTrue(requestEndpointChange(anotherEndpoint!!))
+                    }
+                    assertTrue(disconnect(DisconnectCause(DisconnectCause.LOCAL)))
+                    deferred.complete(Unit) // completed all asserts. cancel timeout!
+                }
+            }
+        }
+    }
+
+    private fun getAnotherEndpoint(
+        currentEndpoint: CallEndpointCompat,
+        availableEndpoints: List<CallEndpointCompat>
+    ): CallEndpointCompat? {
+        for (endpoint in availableEndpoints) {
+            if (endpoint.type != currentEndpoint.type) {
+                return endpoint
+            }
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallEndpointCompatTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallEndpointCompatTest.kt
new file mode 100644
index 0000000..1711968
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallEndpointCompatTest.kt
@@ -0,0 +1,116 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.os.ParcelUuid
+import android.telecom.CallAudioState
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.internal.utils.EndpointUtils
+import androidx.test.filters.SdkSuppress
+import java.util.UUID
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+@RequiresApi(VERSION_CODES.O)
+class CallEndpointCompatTest {
+
+    @Test
+    fun testCallEndpointConstructor() {
+        val name = "Endpoint"
+        val type = CallEndpointCompat.TYPE_EARPIECE
+        val identifier = ParcelUuid.fromString(UUID.randomUUID().toString())
+        val endpoint = CallEndpointCompat(name, type, identifier)
+        assertEquals(name, endpoint.name)
+        assertEquals(type, endpoint.type)
+        assertEquals(identifier, endpoint.identifier)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @Test
+    fun testWrappingAudioStateIntoAEndpoint() {
+        val state = CallAudioState(false, CallAudioState.ROUTE_EARPIECE, 0)
+        val endpoint = EndpointUtils.toCallEndpointCompat(state)
+        assertEquals("EARPIECE", endpoint.name)
+        assertEquals(CallEndpointCompat.TYPE_EARPIECE, endpoint.type)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @Test
+    fun testSupportedMask() {
+        val supportedRouteMask = CallAudioState.ROUTE_EARPIECE or
+            CallAudioState.ROUTE_SPEAKER or CallAudioState.ROUTE_WIRED_HEADSET
+        val state = CallAudioState(false, CallAudioState.ROUTE_EARPIECE, supportedRouteMask)
+        val endpoints = EndpointUtils.toCallEndpointsCompat(state)
+        assertEquals(3, endpoints.size)
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @Test
+    fun testCallAudioRouteToEndpointTypeMapping() {
+        assertEquals(
+            CallEndpointCompat.TYPE_EARPIECE,
+            EndpointUtils.mapRouteToType(CallAudioState.ROUTE_EARPIECE)
+        )
+        assertEquals(
+            CallEndpointCompat.TYPE_SPEAKER,
+            EndpointUtils.mapRouteToType(CallAudioState.ROUTE_SPEAKER)
+        )
+        assertEquals(
+            CallEndpointCompat.TYPE_WIRED_HEADSET,
+            EndpointUtils.mapRouteToType(CallAudioState.ROUTE_WIRED_HEADSET)
+        )
+        assertEquals(
+            CallEndpointCompat.TYPE_BLUETOOTH,
+            EndpointUtils.mapRouteToType(CallAudioState.ROUTE_BLUETOOTH)
+        )
+        assertEquals(
+            CallEndpointCompat.TYPE_STREAMING,
+            EndpointUtils.mapRouteToType(CallAudioState.ROUTE_STREAMING)
+        )
+        assertEquals(CallEndpointCompat.TYPE_UNKNOWN, EndpointUtils.mapRouteToType(-1))
+    }
+
+    @SdkSuppress(minSdkVersion = VERSION_CODES.O)
+    @Test
+    fun testTypeToRouteMapping() {
+        assertEquals(
+            CallAudioState.ROUTE_EARPIECE,
+            EndpointUtils.mapTypeToRoute(CallEndpointCompat.TYPE_EARPIECE)
+        )
+        assertEquals(
+            CallAudioState.ROUTE_SPEAKER,
+            EndpointUtils.mapTypeToRoute(CallEndpointCompat.TYPE_SPEAKER)
+        )
+        assertEquals(
+            CallAudioState.ROUTE_BLUETOOTH,
+            EndpointUtils.mapTypeToRoute(CallEndpointCompat.TYPE_BLUETOOTH)
+        )
+        assertEquals(
+            CallAudioState.ROUTE_WIRED_HEADSET,
+            EndpointUtils.mapTypeToRoute(CallEndpointCompat.TYPE_WIRED_HEADSET)
+        )
+        assertEquals(
+            CallAudioState.ROUTE_STREAMING,
+            EndpointUtils.mapTypeToRoute(CallEndpointCompat.TYPE_STREAMING)
+        )
+        assertEquals(
+            CallAudioState.ROUTE_EARPIECE,
+            EndpointUtils.mapTypeToRoute(-1)
+        )
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallsManagerTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallsManagerTest.kt
new file mode 100644
index 0000000..5c2fa7d
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/CallsManagerTest.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.telecom.PhoneAccount.CAPABILITY_SELF_MANAGED
+import android.telecom.PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.internal.utils.Utils
+import androidx.core.telecom.utils.BaseTelecomTest
+import androidx.core.telecom.utils.TestUtils
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertThrows
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@RequiresApi(VERSION_CODES.O)
+@SdkSuppress(minSdkVersion = VERSION_CODES.O /* api=26 */)
+class CallsManagerTest : BaseTelecomTest() {
+    private val mTestClassName = "androidx.core.telecom.test"
+
+    @SmallTest
+    @Test
+    fun testGetPhoneAccountWithUBuild() {
+        try {
+            Utils.setUtils(TestUtils.mV2Build)
+            val account = mCallsManager.getPhoneAccountHandleForPackage()
+            assertEquals(mTestClassName, account.componentName.className)
+        } finally {
+            Utils.resetUtils()
+        }
+    }
+
+    @SmallTest
+    @Test
+    fun testGetPhoneAccountWithUBuildWithTminusBuild() {
+        try {
+            Utils.setUtils(TestUtils.mBackwardsCompatBuild)
+            val account = mCallsManager.getPhoneAccountHandleForPackage()
+            assertEquals(CallsManager.CONNECTION_SERVICE_CLASS, account.componentName.className)
+        } finally {
+            Utils.resetUtils()
+        }
+    }
+
+    @SmallTest
+    @Test
+    fun testGetPhoneAccountWithInvalidBuild() {
+        try {
+            Utils.setUtils(TestUtils.mInvalidBuild)
+            assertThrows(UnsupportedOperationException::class.java) {
+                mCallsManager.getPhoneAccountHandleForPackage()
+            }
+        } finally {
+            Utils.resetUtils()
+        }
+    }
+
+    @SmallTest
+    @Test
+    fun testRegisterPhoneAccount() {
+        Utils.resetUtils()
+
+        if (Utils.hasInvalidBuildVersion()) {
+            assertThrows(UnsupportedOperationException::class.java) {
+                mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+            }
+        } else {
+
+            mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+            val account = mCallsManager.getBuiltPhoneAccount()!!
+
+            if (Utils.hasPlatformV2Apis()) {
+                assertTrue(
+                    Utils.hasCapability(
+                        CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS,
+                        account.capabilities
+                    )
+                )
+            } else {
+                assertTrue(
+                    account.capabilities and CAPABILITY_SELF_MANAGED ==
+                        CAPABILITY_SELF_MANAGED
+                )
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/JetpackConnectionServiceTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/JetpackConnectionServiceTest.kt
new file mode 100644
index 0000000..5da05c7
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/JetpackConnectionServiceTest.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.telecom.Connection
+import android.telecom.ConnectionRequest
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.internal.CallChannels
+import androidx.core.telecom.internal.JetpackConnectionService
+import androidx.core.telecom.internal.utils.Utils
+import androidx.core.telecom.utils.BaseTelecomTest
+import androidx.core.telecom.utils.TestUtils
+import androidx.core.telecom.utils.TestUtils.TEST_CALL_ATTRIB_NAME
+import androidx.core.telecom.utils.TestUtils.TEST_PHONE_NUMBER_9001
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@RequiresApi(VERSION_CODES.O)
+@SdkSuppress(minSdkVersion = VERSION_CODES.O /* api=26 */)
+class JetpackConnectionServiceTest : BaseTelecomTest() {
+    private val callChannels = CallChannels()
+
+    @Before
+    fun setUp() {
+        Utils.resetUtils()
+    }
+
+    @After
+    fun onDestroy() {
+        callChannels.closeAllChannels()
+    }
+
+    /**
+     * Ensure an outgoing Connection object has its properties set before sending it off to the
+     * platform.  The properties should reflect everything that is set in CallAttributes.
+     */
+    @SmallTest
+    @Test
+    fun testConnectionServicePropertiesAreSet_outgoingCall() {
+        // create the CallAttributes
+        val attributes = TestUtils.createCallAttributes(
+            CallAttributesCompat.DIRECTION_OUTGOING,
+            mPackagePhoneAccountHandle
+        )
+        // simulate the connection being created
+        val connection = mConnectionService.createSelfManagedConnection(
+            createConnectionRequest(attributes),
+            CallAttributesCompat.DIRECTION_OUTGOING
+        )
+        // verify / assert connection properties
+        verifyConnectionPropertiesBasics(connection)
+        assertEquals(Connection.STATE_DIALING, connection!!.state)
+    }
+
+    /**
+     * Ensure an incoming Connection object has its properties set before sending it off to the
+     * platform.  The properties should reflect everything that is set in CallAttributes.
+     */
+    @SmallTest
+    @Test
+    fun testConnectionServicePropertiesAreSet_incomingCall() {
+        // create the CallAttributes
+        val attributes = TestUtils.createCallAttributes(
+            CallAttributesCompat.DIRECTION_INCOMING,
+            mPackagePhoneAccountHandle
+        )
+        // simulate the connection being created
+        val connection = mConnectionService.createSelfManagedConnection(
+            createConnectionRequest(attributes),
+            CallAttributesCompat.DIRECTION_INCOMING
+        )
+        // verify / assert connection properties
+        verifyConnectionPropertiesBasics(connection)
+        assertEquals(Connection.STATE_RINGING, connection!!.state)
+    }
+
+    private fun verifyConnectionPropertiesBasics(connection: Connection?) {
+        // assert it's not null
+        assertNotNull(connection)
+        // unwrap for testing
+        val unwrappedConnection = connection!!
+        // assert all the properties are the same
+        assertEquals(TEST_CALL_ATTRIB_NAME, unwrappedConnection.callerDisplayName)
+        assertEquals(TEST_PHONE_NUMBER_9001, unwrappedConnection.address)
+        assertEquals(
+            Connection.CAPABILITY_HOLD,
+            unwrappedConnection.connectionCapabilities
+                and Connection.CAPABILITY_HOLD
+        )
+        assertEquals(
+            Connection.CAPABILITY_SUPPORT_HOLD,
+            unwrappedConnection.connectionCapabilities
+                and Connection.CAPABILITY_SUPPORT_HOLD
+        )
+        assertEquals(0, JetpackConnectionService.mPendingConnectionRequests.size)
+    }
+
+    private fun createConnectionRequest(callAttributesCompat: CallAttributesCompat):
+        ConnectionRequest {
+        // wrap in PendingRequest
+        val pr = JetpackConnectionService.PendingConnectionRequest(
+            callAttributesCompat, callChannels, mWorkerContext, null
+        )
+        // add to the list of pendingRequests
+        JetpackConnectionService.mPendingConnectionRequests.add(pr)
+        // create a ConnectionRequest
+        return ConnectionRequest(mPackagePhoneAccountHandle, TEST_PHONE_NUMBER_9001, null)
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/BaseTelecomTest.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/BaseTelecomTest.kt
new file mode 100644
index 0000000..89fbcea
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/BaseTelecomTest.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.core.telecom.utils
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import android.telecom.PhoneAccountHandle
+import android.telecom.TelecomManager
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.CallControlScope
+import androidx.core.telecom.CallsManager
+import androidx.core.telecom.internal.JetpackConnectionService
+import androidx.core.telecom.internal.utils.Utils
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SdkSuppress
+import androidx.testutils.TestExecutor
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.asCoroutineDispatcher
+import kotlinx.coroutines.withTimeout
+import org.junit.After
+import org.junit.Assert
+import org.junit.Before
+
+@RequiresApi(Build.VERSION_CODES.O)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O /* api=26 */)
+abstract class BaseTelecomTest {
+    val L_TAG = "BaseTelecomTest"
+    val mContext: Context = ApplicationProvider.getApplicationContext()
+    val mWorkerExecutor = TestExecutor()
+    val mWorkerContext: CoroutineContext = mWorkerExecutor.asCoroutineDispatcher()
+
+    lateinit var mPreviousDefaultDialer: String
+    lateinit var mTelecomManager: TelecomManager
+    lateinit var mCallsManager: CallsManager
+    lateinit var mPackagePhoneAccountHandle: PhoneAccountHandle
+    internal lateinit var mConnectionService: JetpackConnectionService
+
+    @Before
+    fun setUpBase() {
+        Log.i(L_TAG, "setUpBase: in function")
+        mTelecomManager = mContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
+        mCallsManager = CallsManager(mContext)
+        mConnectionService = mCallsManager.mConnectionService
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+        mPackagePhoneAccountHandle = mCallsManager.getPhoneAccountHandleForPackage()
+        mPreviousDefaultDialer = TestUtils.getDefaultDialer()
+        TestUtils.setDefaultDialer(TestUtils.TEST_PACKAGE)
+        maybeCleanupStuckCalls()
+        Utils.resetUtils()
+        TestUtils.resetCallbackConfigs()
+    }
+
+    @After
+    fun onDestroyBase() {
+        Log.i(L_TAG, "onDestroyBase: in function")
+        Utils.resetUtils()
+        TestUtils.resetCallbackConfigs()
+        TestUtils.setDefaultDialer(mPreviousDefaultDialer)
+        maybeCleanupStuckCalls()
+    }
+
+    fun setUpV2Test() {
+        Log.i(L_TAG, "setUpV2Test: core-telecom w/ [V2] APIs")
+        Utils.setUtils(TestUtils.mV2Build)
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+        logTelecomState()
+    }
+
+    fun setUpBackwardsCompatTest() {
+        Log.i(L_TAG, "setUpBackwardsCompatTest: core-telecom w/ [ConnectionService] APIs")
+        Utils.setUtils(TestUtils.mBackwardsCompatBuild)
+        mCallsManager.registerAppWithTelecom(CallsManager.CAPABILITY_BASELINE)
+        logTelecomState()
+    }
+
+    private fun logTelecomState() {
+        val telecomDumpsysString = TestUtils.runShellCommand(TestUtils.COMMAND_DUMP_TELECOM)
+        val isInCallXmCallsDump = isInCallFromTelDumpsys(telecomDumpsysString)
+
+        Log.i(L_TAG, "logTelecomState: " +
+            "hasTelecomFeature=[${hasTelecomFeature()}]," +
+            "isInCall=[${isInCallXmCallsDump.first}], " +
+            "mCalls={${isInCallXmCallsDump.second}}, " +
+            "sdkInt=[${Build.VERSION.SDK_INT}], " +
+            "phoneAccounts=[${getPhoneAccountsFromTelDumpsys(telecomDumpsysString)}]")
+    }
+
+    private fun hasTelecomFeature(): Boolean {
+        return mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_TELECOM)
+    }
+
+    private fun maybeCleanupStuckCalls() {
+        JetpackConnectionService.mPendingConnectionRequests.clear()
+        MockInCallService.destroyAllCalls()
+    }
+
+    private fun isInCallFromTelDumpsys(telecomDumpsysString: String): Pair<Boolean, String> {
+        val allCallsText = telecomDumpsysString
+            .substringBefore("mCallAudioManager")
+            .substringAfter("mCalls:")
+        if (allCallsText.contains("Call")) {
+            return Pair(true, allCallsText)
+        }
+        return Pair(false, "")
+    }
+
+    private fun getPhoneAccountsFromTelDumpsys(telecomDumpsysString: String): String {
+        return telecomDumpsysString
+            .substringBefore("Analytics")
+            .substringAfter("phoneAccounts:")
+    }
+
+    /**
+     * This helper requires an asserBlock (a set of assert statements), creates a timer, and
+     * either halts execution until all the asserts are completed or times out if the asserts
+     * are not completed in time. It's important to do this
+     */
+    suspend fun assertWithinTimeout_addCall(
+        deferred: CompletableDeferred<Unit>,
+        attributes: CallAttributesCompat,
+        assertBlock: CallControlScope.() -> (Unit)
+    ) {
+        try {
+            withTimeout(TestUtils.WAIT_ON_ASSERTS_TO_FINISH_TIMEOUT) {
+                mCallsManager.addCall(attributes) {
+                    setCallback(TestUtils.mCompleteAllCallControlCallbacksImpl)
+                    assertBlock()
+                }
+                Log.i(TestUtils.LOG_TAG, "assertWithinTimeout: execution <PAUSED>")
+                deferred.await()
+                Log.i(TestUtils.LOG_TAG, "assertWithinTimeout: execution <UN-PAUSED>")
+            }
+        } catch (timeout: TimeoutCancellationException) {
+            Log.i(TestUtils.LOG_TAG, "assertWithinTimeout: reached timeout; dumping telecom")
+            TestUtils.dumpTelecom()
+            Assert.fail(TestUtils.VERIFICATION_TIMEOUT_MSG)
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockDialerActivity.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockDialerActivity.kt
new file mode 100644
index 0000000..93fb341
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockDialerActivity.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.core.telecom.utils
+
+import android.app.Activity
+import android.os.Bundle
+import androidx.core.view.WindowCompat
+
+/**
+ * API 26 - 28 require an Activity that filters the DIAL intent in order to bind to an InCallService
+ */
+class MockDialerActivity : Activity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        WindowCompat.setDecorFitsSystemWindows(window, false)
+        super.onCreate(savedInstanceState)
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockInCallService.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockInCallService.kt
new file mode 100644
index 0000000..3efd8c0
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/MockInCallService.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.core.telecom.utils
+
+import android.content.Intent
+import android.os.Build
+import android.os.IBinder
+import android.telecom.Call
+import android.telecom.InCallService
+import android.util.Log
+import androidx.annotation.RequiresApi
+import java.util.Collections
+
+@RequiresApi(Build.VERSION_CODES.M)
+class MockInCallService : InCallService() {
+    companion object {
+        val LOG_TAG = "MockInCallService"
+        val mCalls = Collections.synchronizedList(ArrayList<Call>())
+        var mIsServiceBound = false
+
+        @Suppress("deprecation")
+        fun destroyAllCalls() {
+            Log.i(LOG_TAG, "destroyAllCalls: Calls.size=[${mCalls.size}]")
+            mIsServiceBound = false
+            for (call in mCalls) {
+                if (call.state != Call.STATE_DISCONNECTED ||
+                    call.state != Call.STATE_DISCONNECTING
+                ) {
+                    Log.i(LOG_TAG, "destroyAllCalls: disconnecting call=[$call]")
+                    call.disconnect()
+                }
+            }
+            mCalls.clear()
+        }
+
+        fun getLastCall(): Call? {
+            return if (mCalls.size == 0) {
+                null
+            } else {
+                mCalls[mCalls.size - 1]
+            }
+        }
+
+        fun getCallCount(): Int {
+            return mCalls.size
+        }
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        Log.i(LOG_TAG, "Service bounded")
+        mIsServiceBound = true
+        return super.onBind(intent)
+    }
+
+    override fun onUnbind(intent: Intent?): Boolean {
+        Log.i(LOG_TAG, "Service has been unbound")
+        mIsServiceBound = false
+        return super.onUnbind(intent)
+    }
+
+    override fun onCallAdded(call: Call) {
+        Log.i(LOG_TAG, String.format("onCallAdded: call=[%s]", call))
+        super.onCallAdded(call)
+
+        if (!mCalls.contains(call)) {
+            Log.i(LOG_TAG, "onCallAdded: added the new call to static call list")
+            mCalls.add(call)
+        }
+    }
+
+    override fun onCallRemoved(call: Call) {
+        Log.i(LOG_TAG, String.format("onCallRemoved: call=[%s]", call))
+        super.onCallRemoved(call)
+        mCalls.remove(call)
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/TestUtils.kt b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/TestUtils.kt
new file mode 100644
index 0000000..9231f7bf
--- /dev/null
+++ b/core/core-telecom/src/androidTest/java/androidx/core/telecom/utils/TestUtils.kt
@@ -0,0 +1,265 @@
+/*
+ * 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.core.telecom.utils
+
+import android.net.Uri
+import android.os.Build.VERSION_CODES
+import android.telecom.Call
+import android.telecom.DisconnectCause
+import android.telecom.PhoneAccountHandle
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.CallControlCallback
+import androidx.core.telecom.internal.utils.BuildVersionAdapter
+import androidx.test.platform.app.InstrumentationRegistry
+import java.io.FileInputStream
+import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.withTimeout
+import kotlinx.coroutines.yield
+
+/**
+ * Singleton class.
+ */
+@RequiresApi(VERSION_CODES.O)
+object TestUtils {
+    const val LOG_TAG = "TelecomTestUtils"
+    const val TEST_PACKAGE = "androidx.core.telecom.test"
+    const val COMMAND_SET_DEFAULT_DIALER = "telecom set-default-dialer " // DO NOT REMOVE SPACE
+    const val COMMAND_GET_DEFAULT_DIALER = "telecom get-default-dialer"
+    const val COMMAND_CLEANUP_STUCK_CALLS = "cleanup-stuck-calls"
+    const val COMMAND_DUMP_TELECOM = "dumpsys telecom"
+    const val TEST_CALL_ATTRIB_NAME = "Elon Musk"
+    const val OUTGOING_NAME = "Larry Page"
+    const val INCOMING_NAME = "Sundar Pichai"
+    const val WAIT_ON_ASSERTS_TO_FINISH_TIMEOUT = 5000L
+    const val WAIT_ON_CALL_STATE_TIMEOUT = 5000L
+    const val WAIT_ON_IN_CALL_SERVICE_CALL_COUNT_TIMEOUT = 5000L
+    const val ALL_CALL_CAPABILITIES = (CallAttributesCompat.SUPPORTS_SET_INACTIVE
+        or CallAttributesCompat.SUPPORTS_STREAM or CallAttributesCompat.SUPPORTS_TRANSFER)
+    val VERIFICATION_TIMEOUT_MSG =
+        "Timed out before asserting all values. This most likely means the platform failed to" +
+            " add the call or hung on a CallControl operation."
+
+    // non-primitive constants
+    val TEST_PHONE_NUMBER_9001 = Uri.parse("tel:6506959001")
+    val TEST_PHONE_NUMBER_8985 = Uri.parse("tel:6506958985")
+
+    // Define the minimal set of properties to start an outgoing call
+    val OUTGOING_CALL_ATTRIBUTES = CallAttributesCompat(
+        OUTGOING_NAME,
+        TEST_PHONE_NUMBER_8985,
+        CallAttributesCompat.DIRECTION_OUTGOING
+    )
+
+    // Define all possible properties for CallAttributes
+    val INCOMING_CALL_ATTRIBUTES =
+        CallAttributesCompat(
+            INCOMING_NAME,
+            TEST_PHONE_NUMBER_8985,
+            CallAttributesCompat.DIRECTION_INCOMING,
+            ALL_CALL_CAPABILITIES
+        )
+
+    /**
+     * This build version should be set when the **V2 transactional APIs** are desired as
+     * the underlying call management.
+     */
+    internal val mV2Build = object : BuildVersionAdapter {
+        override fun hasPlatformV2Apis(): Boolean {
+            return true
+        }
+
+        override fun hasInvalidBuildVersion(): Boolean {
+            return false
+        }
+    }
+
+    /**
+     * This build version should be set when the **ConnectionService and Connection APIs** are
+     * desired as the underlying call management.
+     */
+    internal val mBackwardsCompatBuild = object : BuildVersionAdapter {
+        override fun hasPlatformV2Apis(): Boolean {
+            return false
+        }
+
+        override fun hasInvalidBuildVersion(): Boolean {
+            return false
+        }
+    }
+
+    /**
+     * This build version should be set when edge case testing on invalid builds
+     */
+    internal val mInvalidBuild = object : BuildVersionAdapter {
+        override fun hasPlatformV2Apis(): Boolean {
+            return false
+        }
+
+        override fun hasInvalidBuildVersion(): Boolean {
+            return true
+        }
+    }
+
+    /**
+     * This [CallControlCallback] implementation will be called by the platform whenever an
+     * InCallService wants to [answer, setActive, setInactive, or disconnect] a particular call
+     * and will immediately complete the transaction.
+     */
+    val mCompleteAllCallControlCallbacksImpl = object : CallControlCallback {
+        override suspend fun onSetActive(): Boolean {
+            Log.i(LOG_TAG, "mCACCCI: onSetActive: completing")
+            mOnSetActiveCallbackCalled = true
+            return true
+        }
+
+        override suspend fun onSetInactive(): Boolean {
+            Log.i(LOG_TAG, "mCACCCI: onSetInactive: completing")
+            mOnSetInactiveCallbackCalled = true
+            return true
+        }
+
+        override suspend fun onAnswer(callType: Int): Boolean {
+            Log.i(LOG_TAG, "mCACCCI: onAnswer: callType=[$callType]")
+            mOnAnswerCallbackCalled = true
+            return true
+        }
+
+        override suspend fun onDisconnect(disconnectCause: DisconnectCause): Boolean {
+            Log.i(LOG_TAG, "mCACCCI: onDisconnect: disconnectCause=[$disconnectCause]")
+            mOnDisconnectCallbackCalled = true
+            return true
+        }
+    }
+
+    var mOnSetActiveCallbackCalled = false
+    var mOnSetInactiveCallbackCalled = false
+    var mOnAnswerCallbackCalled = false
+    var mOnDisconnectCallbackCalled = false
+
+    fun resetCallbackConfigs() {
+        mOnSetActiveCallbackCalled = false
+        mOnSetInactiveCallbackCalled = false
+        mOnAnswerCallbackCalled = false
+        mOnDisconnectCallbackCalled = false
+    }
+
+    fun createCallAttributes(
+        callDirection: Int,
+        phoneAccountHandle: PhoneAccountHandle,
+        callType: Int? = CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
+    ): CallAttributesCompat {
+
+        val attributes: CallAttributesCompat = if (callType != null) {
+            CallAttributesCompat(
+                TEST_CALL_ATTRIB_NAME,
+                TEST_PHONE_NUMBER_9001,
+                callDirection, callType
+            )
+        } else {
+            CallAttributesCompat(
+                TEST_CALL_ATTRIB_NAME,
+                TEST_PHONE_NUMBER_9001,
+                callDirection
+            )
+        }
+
+        attributes.mHandle = phoneAccountHandle
+
+        return attributes
+    }
+
+    /** Run a command and retrieve the output as a string. */
+    fun runShellCommand(command: String): String {
+        return InstrumentationRegistry.getInstrumentation()
+            .uiAutomation
+            .executeShellCommand(command)
+            .use { FileInputStream(it.fileDescriptor).reader().readText() }
+    }
+
+    fun setDefaultDialer(packageName: String) {
+        Log.i(
+            LOG_TAG,
+            "setDefaultDialer=[${runShellCommand((COMMAND_SET_DEFAULT_DIALER + packageName))}]"
+        )
+    }
+
+    fun getDefaultDialer(): String {
+        val s = runShellCommand(COMMAND_GET_DEFAULT_DIALER)
+        return s.replace("\n", "")
+    }
+
+    fun dumpTelecom() {
+        Log.i(LOG_TAG, "telecom dumpsys=[${runShellCommand(COMMAND_DUMP_TELECOM)}]")
+        Log.i(LOG_TAG, "defaultDialer=[${getDefaultDialer()}]")
+    }
+
+    @Suppress("deprecation")
+    suspend fun waitOnInCallServiceToReachXCalls(targetCallCount: Int): Call? {
+        var targetCall: Call?
+        try {
+            withTimeout(WAIT_ON_IN_CALL_SERVICE_CALL_COUNT_TIMEOUT) {
+                Log.i(LOG_TAG, "waitOnInCallServiceToReachXCalls: starting call check")
+                while (isActive &&
+                    (MockInCallService.getCallCount() < targetCallCount)
+                ) {
+                    yield() // ensure the coroutine is not canceled
+                    delay(1) // sleep x millisecond(s) instead of spamming check
+                }
+                targetCall = MockInCallService.getLastCall()
+                Log.i(
+                    LOG_TAG, "waitOnInCallServiceToReachXCalls: " +
+                        "found targetCall=[$targetCall]"
+                )
+            }
+        } catch (e: TimeoutCancellationException) {
+            Log.i(LOG_TAG, "waitOnInCallServiceToReachXCalls: timeout reached")
+            dumpTelecom()
+            MockInCallService.destroyAllCalls()
+            throw AssertionError(
+                "Expected call count to be <$targetCallCount>" +
+                    " but the Actual call count was <${MockInCallService.getCallCount()}>"
+            )
+        }
+        return targetCall
+    }
+
+    @Suppress("deprecation")
+    suspend fun waitOnCallState(call: Call, targetState: Int) {
+        try {
+            withTimeout(WAIT_ON_CALL_STATE_TIMEOUT) {
+                while (isActive /* aka  within timeout window */ &&
+                    (call.state != targetState)
+                ) {
+                    yield() // another mechanism to stop the while loop if the coroutine is dead
+                    delay(1) // sleep x millisecond(s) instead of spamming check
+                }
+            }
+        } catch (e: TimeoutCancellationException) {
+            Log.i(LOG_TAG, "waitOnCallState: timeout reached")
+            dumpTelecom()
+            MockInCallService.destroyAllCalls()
+            throw AssertionError(
+                "Expected call state to be <$targetState>" +
+                    " but the Actual call state was <${call.state}>"
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/AndroidManifest.xml b/core/core-telecom/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8ea6753
--- /dev/null
+++ b/core/core-telecom/src/main/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
+    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
+
+    <application>
+        <service
+            android:name="androidx.core.telecom.internal.JetpackConnectionService"
+            android:exported="true"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService"/>
+            </intent-filter>
+        </service>
+
+    </application>
+
+</manifest>
diff --git a/core/core-telecom/src/main/java/androidx/core/androidx-core-core-telecom-documentation.md b/core/core-telecom/src/main/java/androidx/core/androidx-core-core-telecom-documentation.md
new file mode 100644
index 0000000..bfb5ecc
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/androidx-core-core-telecom-documentation.md
@@ -0,0 +1,7 @@
+# Module root
+
+<GROUPID> <ARTIFACTID>
+
+# Package androidx.core.telecom
+
+TODO: Document
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallAttributesCompat.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallAttributesCompat.kt
new file mode 100644
index 0000000..e3d3610
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallAttributesCompat.kt
@@ -0,0 +1,192 @@
+/*
+ * 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.core.telecom
+
+import android.net.Uri
+import android.telecom.PhoneAccountHandle
+import androidx.annotation.IntDef
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.core.telecom.internal.utils.CallAttributesUtils
+import androidx.core.telecom.internal.utils.Utils
+import java.util.Objects
+
+/**
+ * CallAttributes represents a set of properties that define a new Call.  Applications should build
+ * an instance of this class and use [CallsManager.addCall] to start a new call with Telecom.
+ *
+ * @param displayName  Display name of the person on the other end of the call
+ * @param address Address of the call. Note, this can be extended to a meeting link
+ * @param direction The direction (Outgoing/Incoming) of the new Call
+ * @param callType Information related to data being transmitted (voice, video, etc. )
+ * @param callCapabilities Allows a package to opt into capabilities on the telecom side,
+ *                         on a per-call basis
+ */
+class CallAttributesCompat constructor(
+    val displayName: CharSequence,
+    val address: Uri,
+    @Direction val direction: Int,
+    @CallType val callType: Int = CALL_TYPE_AUDIO_CALL,
+    @CallCapability val callCapabilities: Int = SUPPORTS_SET_INACTIVE
+) {
+    internal var mHandle: PhoneAccountHandle? = null
+
+    override fun toString(): String {
+        return "CallAttributes(" +
+            "displayName=[$displayName], " +
+            "address=[$address], " +
+            "direction=[${directionToString()}], " +
+            "callType=[${callTypeToString()}], " +
+            "capabilities=[${capabilitiesToString()}])"
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return other is CallAttributesCompat &&
+            displayName == other.displayName &&
+            address == other.address &&
+            direction == other.direction &&
+            callType == other.callType &&
+            callCapabilities == other.callCapabilities
+    }
+
+    override fun hashCode(): Int {
+        return Objects.hash(displayName, address, direction, callType, callCapabilities)
+    }
+
+    companion object {
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(DIRECTION_INCOMING, DIRECTION_OUTGOING)
+        @Target(AnnotationTarget.TYPE, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
+        annotation class Direction
+
+        /**
+         * Indicates that the call is an incoming call.
+         */
+        const val DIRECTION_INCOMING = 1
+
+        /**
+         * Indicates that the call is an outgoing call.
+         */
+        const val DIRECTION_OUTGOING = 2
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(CALL_TYPE_AUDIO_CALL, CALL_TYPE_VIDEO_CALL)
+        @Target(AnnotationTarget.TYPE, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.PROPERTY)
+        annotation class CallType
+
+        /**
+         * Used when answering or dialing a call to indicate that the call does not have a video
+         * component
+         */
+        const val CALL_TYPE_AUDIO_CALL = 1
+
+        /**
+         * Indicates video transmission is supported
+         */
+        const val CALL_TYPE_VIDEO_CALL = 2
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(SUPPORTS_SET_INACTIVE, SUPPORTS_STREAM, SUPPORTS_TRANSFER, flag = true)
+        @Target(AnnotationTarget.TYPE, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
+        annotation class CallCapability
+
+        /**
+         * This call being created can be set to inactive (traditionally referred to as hold).  This
+         * means that once a new call goes active, if the active call needs to be held in order to
+         * place or receive an incoming call, the active call will be placed on hold.  otherwise,
+         * the active call may be disconnected.
+         */
+        const val SUPPORTS_SET_INACTIVE = 1 shl 1
+
+        /**
+         * This call can be streamed from a root device to another device to continue the call
+         * without completely transferring it. The call continues to take place on the source
+         * device, however media and control are streamed to another device.
+         */
+        const val SUPPORTS_STREAM = 1 shl 2
+
+        /**
+         * This call can be completely transferred from one endpoint to another.
+         */
+        const val SUPPORTS_TRANSFER = 1 shl 3
+    }
+
+    @RequiresApi(34)
+    internal fun toCallAttributes(
+        phoneAccountHandle: PhoneAccountHandle
+    ): android.telecom.CallAttributes {
+        return CallAttributesUtils.Api34PlusImpl.toTelecomCallAttributes(
+            phoneAccountHandle,
+            direction,
+            displayName,
+            address,
+            callType,
+            callCapabilities
+        )
+    }
+
+    private fun directionToString(): String {
+        return if (direction == DIRECTION_OUTGOING) {
+            "Outgoing"
+        } else {
+            "Incoming"
+        }
+    }
+
+    private fun callTypeToString(): String {
+        return if (callType == CALL_TYPE_AUDIO_CALL) {
+            "Audio"
+        } else {
+            "Video"
+        }
+    }
+
+    internal fun hasSupportsSetInactiveCapability(): Boolean {
+        return Utils.hasCapability(SUPPORTS_SET_INACTIVE, callCapabilities)
+    }
+
+    private fun hasStreamCapability(): Boolean {
+        return Utils.hasCapability(SUPPORTS_STREAM, callCapabilities)
+    }
+
+    private fun hasTransferCapability(): Boolean {
+        return Utils.hasCapability(SUPPORTS_TRANSFER, callCapabilities)
+    }
+
+    private fun capabilitiesToString(): String {
+        val sb = StringBuilder()
+        sb.append("[")
+        if (hasSupportsSetInactiveCapability()) {
+            sb.append("SetInactive")
+        }
+        if (hasStreamCapability()) {
+            sb.append(", Stream")
+        }
+        if (hasTransferCapability()) {
+            sb.append(", Transfer")
+        }
+        sb.append("])")
+        return sb.toString()
+    }
+
+    internal fun isOutgoingCall(): Boolean {
+        return direction == DIRECTION_OUTGOING
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallControlCallback.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallControlCallback.kt
new file mode 100644
index 0000000..8651577
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallControlCallback.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.core.telecom
+
+/**
+ * CallControlCallback relays call updates (that require a response) from the Telecom framework out
+ * to the application. This can include operations which the app must implement on a Call due to the
+ * presence of other calls on the device, requests relayed from a Bluetooth device, or from another
+ * calling surface.
+ *
+ *
+ * All CallControlCallbacks are transactional, meaning that a client must
+ * complete the suspend fun with a [Boolean] response in order to complete the
+ * CallControlCallback. If the operation has been completed, the [suspend fun] should return
+ * true. Otherwise, the suspend fun should be returned with a false to represent the
+ * CallControlCallback cannot be completed on the client side.
+ *
+ *
+ * Note: Each CallEventCallback has a timeout of 5000 milliseconds. Failing to complete the
+ * suspend fun before the timeout will result in a failed transaction.
+ */
+interface CallControlCallback {
+    /**
+     * Telecom is informing your VoIP application to set the call active.  Telecom is requesting
+     * this on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).
+     *
+     * @return true to indicate your VoIP application can set the call (that corresponds to this
+     * CallControlCallback) to active. Otherwise, return false to indicate your application is
+     * unable to process the request and telecom will cancel the external request.
+     */
+    suspend fun onSetActive(): Boolean
+
+    /**
+     * Telecom is informing your VoIP application to set the call inactive. This is the same as
+     * holding a call for two endpoints but can be extended to setting a meeting inactive. Telecom
+     * is requesting this on behalf of an system service (e.g. Automotive service) or a device (e.g.
+     * Wearable).
+     *
+     * Note: Your app must stop using the microphone and playing incoming media when returning.
+     *
+     * @return true to indicate your VoIP application can transition the call state to inactive.
+     * Otherwise, return false to indicate your application is  unable to process the request and
+     * telecom will cancel the external request.
+     */
+    suspend fun onSetInactive(): Boolean
+
+    /**
+     * Telecom is informing your VoIP application to answer an incoming call and set it to active.
+     * Telecom is requesting this on behalf of an system service (e.g. Automotive service) or a
+     * device (e.g. Wearable).
+     *
+     * @param callType that call is requesting to be answered as.
+     *
+     * @return true to indicate your VoIP application can answer the call with the given
+     * [CallAttributesCompat.Companion.CallType]. Otherwise, return false to indicate your application is
+     * unable to process the request and telecom will cancel the external request.
+     */
+    suspend fun onAnswer(@CallAttributesCompat.Companion.CallType callType: Int): Boolean
+
+    /**
+     * Telecom is informing your VoIP application to disconnect the call. Telecom is requesting this
+     * on behalf of an system service (e.g. Automotive service) or a device (e.g. Wearable).
+     *
+     * @param disconnectCause represents the cause for disconnecting the call.
+     *
+     * @return true when your VoIP application has disconnected the call. Otherwise, return false to
+     * indicate your application is unable to process the request. However, telecom will still
+     * disconnect and untrack the call.
+     */
+    suspend fun onDisconnect(disconnectCause: android.telecom.DisconnectCause): Boolean
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallControlScope.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallControlScope.kt
new file mode 100644
index 0000000..5977ca0
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallControlScope.kt
@@ -0,0 +1,142 @@
+/*
+ * 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.core.telecom
+
+import android.os.ParcelUuid
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * DSL interface to provide and receive updates about a single call session. The scope should be
+ * used to provide updates to the call state and receive updates about a call state.  Example usage:
+ *
+ *    // initiate a call and control via the CallControlScope
+ *    mCallsManager.addCall(callAttributes) { // This block represents the CallControlScope
+ *
+ *          // set your implementation of [CallControlCallback]
+ *         setCallback(myCallControlCallbackImplementation)
+ *
+ *         // UI flow sends an update to a call state, relay the update to Telecom
+ *         disconnectCallButton.setOnClickListener {
+ *             val wasSuccessful = disconnect(reason) // waits for telecom async. response
+ *             // update UI
+ *         }
+ *
+ *         // Collect updates
+ *         currentCallEndpoint
+ *           .onEach { // access the new [CallEndpoint] here }
+ *           .launchIn(coroutineScope)
+ *     }
+ *
+ */
+interface CallControlScope {
+    /**
+     * This method should be the first method called within the [CallControlScope] and your VoIP
+     * application should pass in a valid implementation of [CallControlCallback].  Failing to call
+     * this method first will result in a [CallException] to be thrown.
+     */
+    @Suppress("ExecutorRegistration")
+    fun setCallback(callControlCallback: CallControlCallback)
+
+    /**
+     * @return the 128-bit universally unique identifier Telecom assigned to this CallControlScope.
+     * This id can be helpful for debugging when dumping the telecom system.
+     */
+    fun getCallId(): ParcelUuid
+
+    /**
+     * Inform Telecom that your app wants to make this call active. This method should be called
+     * when either an outgoing call is ready to go active or a held call is ready to go active
+     * again. For incoming calls that are ready to be answered, use [answer].
+     *
+     * Telecom will return true if your app is able to set the call active.  Otherwise false will
+     * be returned (ex. another call is active and telecom cannot set this call active until the
+     * other call is held or disconnected)
+     */
+    suspend fun setActive(): Boolean
+
+    /**
+     * Inform Telecom that your app wants to make this call inactive. This the same as hold for two
+     * call endpoints but can be extended to setting a meeting to inactive.
+     *
+     * Telecom will return true if your app is able to set the call inactive. Otherwise, false will
+     * be returned.
+     */
+    suspend fun setInactive(): Boolean
+
+    /**
+     * Inform Telecom that your app wants to make this incoming call active.  For outgoing calls
+     * and calls that have been placed on hold, use [setActive].
+     *
+     * @param [callType] that call is to be answered as.
+     *
+     * Telecom will return true if your app is able to answer the call.  Otherwise false will
+     * be returned (ex. another call is active and telecom cannot set this call active until the
+     * other call is held or disconnected) which means that your app cannot answer this call at
+     * this time.
+     */
+    suspend fun answer(@CallAttributesCompat.Companion.CallType callType: Int): Boolean
+
+    /**
+     * Inform Telecom that your app wishes to disconnect the call and remove the call from telecom
+     * tracking.
+     *
+     * @param disconnectCause represents the cause for disconnecting the call.  The only valid
+     *                        codes for the [android.telecom.DisconnectCause] passed in are:
+     *                        <ul>
+     *                        <li>[DisconnectCause#LOCAL]</li>
+     *                        <li>[DisconnectCause#REMOTE]</li>
+     *                        <li>[DisconnectCause#REJECTED]</li>
+     *                        <li>[DisconnectCause#MISSED]</li>
+     *                        </ul>
+     *
+     * Telecom will always return true unless the call has already been disconnected.
+     *
+     * <p>
+     * Note: After the call has been successfully disconnected, calling any [CallControlScope] will
+     * result in a false to be returned.
+     */
+    suspend fun disconnect(disconnectCause: android.telecom.DisconnectCause): Boolean
+
+    /**
+     * Request a [CallEndpointCompat] change. Clients should not define their own [CallEndpointCompat] when
+     * requesting a change. Instead, the new [endpoint] should be one of the valid [CallEndpointCompat]s
+     * provided by [availableEndpoints].
+     *
+     * @param endpoint The [CallEndpointCompat] to change to.
+     *
+     * @return true if Telecom is able to switch to the requested endpoint successfully.  Otherwise,
+     * false will be returned to represent a failure.
+     */
+    suspend fun requestEndpointChange(endpoint: CallEndpointCompat): Boolean
+
+    /**
+     * Collect the new [CallEndpointCompat] through which call media flows (i.e. speaker,
+     * bluetooth, etc.).
+     */
+    val currentCallEndpoint: Flow<CallEndpointCompat>
+
+    /**
+     * Collect the set of available [CallEndpointCompat]s reported by Telecom.
+     */
+    val availableEndpoints: Flow<List<CallEndpointCompat>>
+
+    /**
+     * Collect the current mute state of the call. This Flow is updated every time the mute state
+     * changes.
+     */
+    val isMuted: Flow<Boolean>
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallEndpointCompat.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallEndpointCompat.kt
new file mode 100644
index 0000000..13ee6cd
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallEndpointCompat.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.core.telecom
+
+import android.os.Build.VERSION_CODES
+import android.os.ParcelUuid
+import androidx.annotation.IntDef
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.core.telecom.internal.utils.EndpointUtils
+import java.util.Objects
+import java.util.UUID
+
+/**
+ * Constructor for a [CallEndpointCompat] object.
+ *
+ * @param name Human-readable name associated with the endpoint
+ * @param type The type of endpoint through which call media being routed
+ *   Allowed values: [TYPE_EARPIECE] , [TYPE_BLUETOOTH] , [TYPE_WIRED_HEADSET] , [TYPE_SPEAKER]
+ *      , [TYPE_STREAMING] , [TYPE_UNKNOWN]
+ * @param identifier A unique identifier for this endpoint on the device
+ */
+@RequiresApi(VERSION_CODES.O)
+class CallEndpointCompat(val name: CharSequence, val type: Int, val identifier: ParcelUuid) {
+    internal var mMackAddress: String = "-1"
+
+    override fun toString(): String {
+        return "CallEndpoint(" +
+            "name=[$name]," +
+            "type=[${EndpointUtils.endpointTypeToString(type)}]," +
+            "identifier=[$identifier])"
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return other is CallEndpointCompat &&
+            name == other.name &&
+            type == other.type &&
+            identifier == other.identifier
+    }
+
+    override fun hashCode(): Int {
+        return Objects.hash(name, type, identifier)
+    }
+
+    companion object {
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(
+            TYPE_UNKNOWN,
+            TYPE_EARPIECE,
+            TYPE_BLUETOOTH,
+            TYPE_WIRED_HEADSET,
+            TYPE_SPEAKER,
+            TYPE_STREAMING
+        )
+        @Target(AnnotationTarget.TYPE, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
+        annotation class EndpointType
+
+        /** Indicates that the type of endpoint through which call media flows is unknown type.  */
+        const val TYPE_UNKNOWN = -1
+
+        /** Indicates that the type of endpoint through which call media flows is an earpiece.  */
+        const val TYPE_EARPIECE = 1
+
+        /** Indicates that the type of endpoint through which call media flows is a Bluetooth.  */
+        const val TYPE_BLUETOOTH = 2
+
+        /** Indicates that the type of endpoint through which call media flows is a wired headset. */
+        const val TYPE_WIRED_HEADSET = 3
+
+        /** Indicates that the type of endpoint through which call media flows is a speakerphone. */
+        const val TYPE_SPEAKER = 4
+
+        /** Indicates that the type of endpoint through which call media flows is an external.  */
+        const val TYPE_STREAMING = 5
+    }
+
+    internal constructor(name: String, @EndpointType type: Int) :
+        this(name, type, ParcelUuid(UUID.randomUUID())) {
+    }
+
+    internal constructor(name: String, @EndpointType type: Int, address: String) : this(
+        name,
+        type
+    ) {
+        mMackAddress = address
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallException.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallException.kt
new file mode 100644
index 0000000..8677df2
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallException.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.core.telecom
+
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+
+/**
+ * This class defines exceptions that can be thrown when using [androidx.core.telecom] APIs.
+ */
+class CallException(
+    @CallErrorCode val code: Int = ERROR_UNKNOWN_CODE,
+    message: String? = codeToMessage(code)
+) : RuntimeException(message) {
+
+    override fun toString(): String {
+        return "CallException( code=[$code], message=[$message])"
+    }
+
+    companion object {
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Retention(AnnotationRetention.SOURCE)
+        @IntDef(ERROR_UNKNOWN_CODE, ERROR_CALLBACKS_CODE)
+        annotation class CallErrorCode
+
+        /**
+         * The operation has failed due to an unknown or unspecified error.
+         */
+        const val ERROR_UNKNOWN_CODE = 1
+
+        /**
+         * This error code is thrown whenever a call is added via [CallsManager.addCall] and the
+         * [CallControlScope.setCallback]s is not the first API called in the session block or at
+         * all. In order to avoid this exception, ensure your [CallControlScope] is calling
+         * [CallControlScope.setCallback]s.
+         */
+        const val ERROR_CALLBACKS_CODE = 2
+
+        internal const val ERROR_CALLBACKS_MSG: String = "Error, when using the " +
+            "[CallControlScope], you must first set the " +
+            "[androidx.core.telecom.CallControlCallback]s via [CallControlScope]#[setCallback]"
+
+        internal const val ERROR_BUILD_VERSION: String = "Core-Telecom only supports builds from" +
+            " Oreo (Android 8) and above.  In order to utilize Core-Telecom, your device must" +
+            " be updated."
+
+        internal fun codeToMessage(@CallErrorCode code: Int): String {
+            when (code) {
+                ERROR_CALLBACKS_CODE -> return ERROR_CALLBACKS_MSG
+            }
+            return "An Unknown Error has occurred while using the Core-Telecom APIs"
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt b/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt
new file mode 100644
index 0000000..32e5e2d
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/CallsManager.kt
@@ -0,0 +1,304 @@
+/*
+ * 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.core.telecom
+
+import android.content.ComponentName
+import android.content.Context
+import android.os.Build.VERSION_CODES
+import android.os.OutcomeReceiver
+import android.os.Process
+import android.telecom.CallControl
+import android.telecom.CallException
+import android.telecom.PhoneAccount
+import android.telecom.PhoneAccountHandle
+import android.telecom.TelecomManager
+import android.util.Log
+import androidx.annotation.IntDef
+import androidx.annotation.RequiresApi
+import androidx.annotation.RequiresPermission
+import androidx.annotation.RestrictTo
+import androidx.core.telecom.CallAttributesCompat.Companion.CALL_TYPE_VIDEO_CALL
+import androidx.core.telecom.internal.CallChannels
+import androidx.core.telecom.internal.CallSession
+import androidx.core.telecom.internal.CallSessionLegacy
+import androidx.core.telecom.internal.JetpackConnectionService
+import androidx.core.telecom.internal.utils.Utils
+import java.util.concurrent.CancellationException
+import java.util.concurrent.Executor
+import kotlin.coroutines.coroutineContext
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.job
+import kotlinx.coroutines.withTimeout
+
+/**
+ * CallsManager allows VoIP applications to add their calls to the Android system service Telecom.
+ * By doing this, other services are aware of your VoIP application calls which leads to a more
+ * stable environment. For example, a wearable may be able to answer an incoming call from your
+ * application if the call is added to the Telecom system.  VoIP applications that manage calls and
+ * do not inform the Telecom system may experience issues with resources (ex. microphone access).
+ *
+ * Note that access to some telecom information is permission-protected. Your app cannot access the
+ * protected information or gain access to protected functionality unless it has the appropriate
+ * permissions declared in its manifest file. Where permissions apply, they are noted in the method
+ * descriptions.
+ */
+@RequiresApi(VERSION_CODES.O)
+class CallsManager constructor(context: Context) {
+    private val mContext: Context = context
+    private var mPhoneAccount: PhoneAccount? = null
+    private val mTelecomManager: TelecomManager =
+        mContext.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
+    internal val mConnectionService: JetpackConnectionService = JetpackConnectionService()
+
+    // A single declared constant for a direct [Executor], since the coroutines primitives we invoke
+    // from the associated callbacks will perform their own dispatch as needed.
+    private val mDirectExecutor = Executor { it.run() }
+
+    companion object {
+        @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        @Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.TYPE)
+        @IntDef(
+            CAPABILITY_BASELINE,
+            CAPABILITY_SUPPORTS_VIDEO_CALLING,
+            CAPABILITY_SUPPORTS_CALL_STREAMING,
+            flag = true
+        )
+        @Retention(AnnotationRetention.SOURCE)
+        annotation class Capability
+
+        /**
+         * If your VoIP application does not want support any of the capabilities below, then your
+         * application can register with [CAPABILITY_BASELINE].
+         *
+         * Note: Calls can still be added and to the Telecom system but if other services request to
+         * perform a capability that is not supported by your application, Telecom will notify the
+         * service of the inability to perform the action instead of hitting an error.
+         */
+        const val CAPABILITY_BASELINE = 1 shl 0
+
+        /**
+         * Flag indicating that your VoIP application supports video calling.
+         * This is not an indication that your application is currently able to make a video
+         * call, but rather that it has the ability to make video calls (but not necessarily at this
+         * time).
+         *
+         * Whether a call can make a video call is ultimately controlled by
+         * [androidx.core.telecom.CallAttributesCompat]s capability
+         * [androidx.core.telecom.CallAttributesCompat.CallType]#[CALL_TYPE_VIDEO_CALL],
+         * which indicates that particular call is currently capable of making a video call.
+         */
+        const val CAPABILITY_SUPPORTS_VIDEO_CALLING = 1 shl 1
+
+        /**
+         * Flag indicating that this VoIP application supports call streaming. Call streaming means
+         * a call can be streamed from a root device to another device to continue the call
+         * without completely transferring it. The call continues to take place on the source
+         * device, however media and control are streamed to another device.
+         * [androidx.core.telecom.CallAttributesCompat.CallType]#[CAPABILITY_SUPPORTS_CALL_STREAMING]
+         * must also be set on per call basis in the event an application wants to gate this
+         * capability on a stricter basis.
+         */
+        const val CAPABILITY_SUPPORTS_CALL_STREAMING = 1 shl 2
+
+        // identifiers that indicate the call was established with core-telecom
+        internal const val PACKAGE_HANDLE_ID: String = "Jetpack"
+        internal const val PACKAGE_LABEL: String = "Telecom-Jetpack"
+        internal const val CONNECTION_SERVICE_CLASS =
+            "androidx.core.telecom.internal.JetpackConnectionService"
+
+        // fail messages specific to addCall
+        internal const val CALL_CREATION_FAILURE_MSG =
+            "The call failed to be added."
+        internal const val ADD_CALL_TIMEOUT = 5000L
+        private val TAG: String = CallsManager::class.java.simpleName.toString()
+    }
+
+    /**
+     * VoIP applications should look at each [Capability] annotated above and call this API in
+     * order to start adding calls via [addCall].
+     *
+     * Note: Registering capabilities must be done before calling [addCall] or an exception will
+     * be thrown by [addCall].
+     *
+     * @throws UnsupportedOperationException if the device is on an invalid build
+     */
+    @RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
+    fun registerAppWithTelecom(@Capability capabilities: Int) {
+        // verify the build version supports this API and throw an exception if not
+        Utils.verifyBuildVersion()
+        // start to build the PhoneAccount that will be registered via the platform API
+        var platformCapabilities: Int = PhoneAccount.CAPABILITY_SELF_MANAGED
+        val phoneAccountBuilder = PhoneAccount.builder(
+            getPhoneAccountHandleForPackage(),
+            PACKAGE_LABEL
+        )
+        // append additional capabilities if the device is on a U build or above
+        if (Utils.hasPlatformV2Apis()) {
+            platformCapabilities = PhoneAccount.CAPABILITY_SUPPORTS_TRANSACTIONAL_OPERATIONS or
+                Utils.remapJetpackCapabilitiesToPlatformCapabilities(capabilities)
+        }
+        // remap and set capabilities
+        phoneAccountBuilder.setCapabilities(platformCapabilities)
+        // build and register the PhoneAccount via the Platform API
+        mPhoneAccount = phoneAccountBuilder.build()
+        mTelecomManager.registerPhoneAccount(mPhoneAccount)
+    }
+
+    /**
+     * Adds a new call with the specified [CallAttributesCompat] to the telecom service. This method
+     * can be used to add both incoming and outgoing calls. Once the call is ready to be
+     * disconnected, use the [CallControlScope.disconnect].
+     *
+     * <b>Call Lifecycle</b>: Your app is given foreground execution priority as long as you have an
+     * ongoing call and are posting a [android.app.Notification.CallStyle] notification.
+     * When your application is given foreground execution priority, your app is treated as a
+     * foreground service. Foreground execution priority will prevent the
+     * [android.app.ActivityManager] from killing your application when it is placed the
+     * background. Foreground execution priority is removed from your app when all of your app's
+     * calls terminate or your app no longer posts a valid notification.
+     *
+     * @param callAttributes     attributes of the new call (incoming or outgoing, address, etc. )
+     * @param block              DSL interface block that will run when the call is ready
+     *
+     * @Throws UnsupportedOperationException if the device is on an invalid build
+     * @Throws CancellationException if the call failed to be added within 5000 milliseconds
+     * @Throws CallException if [CallControlScope.setCallback] is not called first within the block
+     */
+    @RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
+    @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+    @Suppress("ClassVerificationFailure")
+    suspend fun addCall(
+        callAttributes: CallAttributesCompat,
+        block: CallControlScope.() -> Unit
+    ) {
+        // This API is not supported for device running anything below Android O (26)
+        Utils.verifyBuildVersion()
+        // Setup channels for the CallEventCallbacks that only provide info updates
+        val callChannels = CallChannels()
+        callAttributes.mHandle = getPhoneAccountHandleForPackage()
+
+        // create a call session based off the build version
+        @RequiresApi(34)
+        if (Utils.hasPlatformV2Apis()) {
+            // CompletableDeferred pauses the execution of this method until the CallControl is
+            // returned by the Platform.
+            val openResult = CompletableDeferred<CallSession>(parent = coroutineContext.job)
+            // CallSession is responsible for handling both CallControl responses from the Platform
+            // and propagates CallControlCallbacks that originate in the Platform out to the client.
+            val callSession = CallSession(coroutineContext)
+
+            /**
+             * The Platform [android.telecom.TelecomManager.addCall] requires a
+             * [OutcomeReceiver]#<[CallControl], [CallException]> that will receive the async
+             * response of whether the call can be added.
+             */
+            val callControlOutcomeReceiver =
+                object : OutcomeReceiver<CallControl, CallException> {
+                    override fun onResult(control: CallControl) {
+                        callSession.setCallControl(control)
+                        openResult.complete(callSession)
+                    }
+
+                    override fun onError(reason: CallException) {
+                        // close all channels
+                        callChannels.closeAllChannels()
+                        // fail if we were still waiting for a CallControl
+                        openResult.cancel(CancellationException(CALL_CREATION_FAILURE_MSG))
+                    }
+                }
+            // leverage the platform API
+            mTelecomManager.addCall(
+                callAttributes.toCallAttributes(getPhoneAccountHandleForPackage()),
+                mDirectExecutor,
+                callControlOutcomeReceiver,
+                CallSession.CallControlCallbackImpl(callSession),
+                CallSession.CallEventCallbackImpl(callChannels)
+            )
+
+            pauseExecutionUntilCallIsReady_orTimeout(openResult)
+
+            /* at this point in time we have CallControl object */
+            val scope =
+                CallSession.CallControlScopeImpl(openResult.getCompleted(), callChannels)
+
+            // Run the clients code with the session active and exposed via the CallControlScope
+            // interface implementation declared above.
+            scope.block()
+        } else {
+            // CompletableDeferred pauses the execution of this method until the Connection
+            // is created in JetpackConnectionService
+            val openResult =
+                CompletableDeferred<CallSessionLegacy>(parent = coroutineContext.job)
+
+            val request = JetpackConnectionService.PendingConnectionRequest(
+                callAttributes, callChannels, coroutineContext, openResult
+            )
+
+            mConnectionService.createConnectionRequest(mTelecomManager, request)
+
+            pauseExecutionUntilCallIsReady_orTimeout(openResult, request)
+
+            val scope =
+                CallSessionLegacy.CallControlScopeImpl(openResult.getCompleted(), callChannels)
+
+            // Run the clients code with the session active and exposed via the
+            // CallControlScope interface implementation declared above.
+            scope.block()
+        }
+    }
+
+    private suspend fun pauseExecutionUntilCallIsReady_orTimeout(
+        openResult: CompletableDeferred<*>,
+        request: JetpackConnectionService.PendingConnectionRequest? = null
+    ) {
+        try {
+            withTimeout(ADD_CALL_TIMEOUT) {
+                Log.i(TAG, "addCall: pausing [$coroutineContext] execution" +
+                    " until the CallControl or Connection is ready")
+                openResult.await()
+            }
+        } catch (timeout: TimeoutCancellationException) {
+            Log.i(TAG, "addCall: timeout hit; canceling call in context=[$coroutineContext]")
+            if (request != null) {
+                JetpackConnectionService.mPendingConnectionRequests.remove(request)
+            }
+            openResult.cancel(CancellationException(CALL_CREATION_FAILURE_MSG))
+        }
+        Log.i(TAG, "addCall: creating call session and running the clients scope")
+    }
+
+    internal fun getPhoneAccountHandleForPackage(): PhoneAccountHandle {
+        // This API is not supported for device running anything below Android O (26)
+        Utils.verifyBuildVersion()
+
+        val className = if (Utils.hasPlatformV2Apis()) {
+            mContext.packageName
+        } else {
+            CONNECTION_SERVICE_CLASS
+        }
+        return PhoneAccountHandle(
+            ComponentName(mContext.packageName, className),
+            PACKAGE_HANDLE_ID,
+            Process.myUserHandle()
+        )
+    }
+
+    internal fun getBuiltPhoneAccount(): PhoneAccount? {
+        return mPhoneAccount
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallChannels.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallChannels.kt
new file mode 100644
index 0000000..8989ca4
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallChannels.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.core.telecom.internal
+
+import androidx.core.telecom.CallEndpointCompat
+import kotlinx.coroutines.channels.Channel
+
+internal class CallChannels(
+    val currentEndpointChannel: Channel<CallEndpointCompat> = Channel(Channel.UNLIMITED),
+    val availableEndpointChannel: Channel<List<CallEndpointCompat>> = Channel(Channel.UNLIMITED),
+    val isMutedChannel: Channel<Boolean> = Channel(Channel.UNLIMITED)
+) {
+    fun closeAllChannels() {
+        currentEndpointChannel.close()
+        availableEndpointChannel.close()
+        isMutedChannel.close()
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSession.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSession.kt
new file mode 100644
index 0000000..a0e2cae
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSession.kt
@@ -0,0 +1,282 @@
+/*
+ * 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.core.telecom.internal
+
+import android.os.Bundle
+import android.os.OutcomeReceiver
+import android.os.ParcelUuid
+import android.telecom.CallException
+import android.telecom.DisconnectCause
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallControlCallback
+import androidx.core.telecom.CallControlScope
+import androidx.core.telecom.CallEndpointCompat
+import androidx.core.telecom.internal.utils.EndpointUtils
+import java.util.function.Consumer
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+
+@RequiresApi(34)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@Suppress("ClassVerificationFailure")
+internal class CallSession(coroutineContext: CoroutineContext) {
+    private val mCoroutineContext = coroutineContext
+    private var mPlatformInterface: android.telecom.CallControl? = null
+    private var mClientInterface: CallControlCallback? = null
+
+    class CallControlCallbackImpl(private val callSession: CallSession) :
+        android.telecom.CallControlCallback {
+        override fun onSetActive(wasCompleted: Consumer<Boolean>) {
+            callSession.onSetActive(wasCompleted)
+        }
+
+        override fun onSetInactive(wasCompleted: Consumer<Boolean>) {
+            callSession.onSetInactive(wasCompleted)
+        }
+
+        override fun onAnswer(videoState: Int, wasCompleted: Consumer<Boolean>) {
+            callSession.onAnswer(videoState, wasCompleted)
+        }
+
+        override fun onDisconnect(
+            disconnectCause: DisconnectCause,
+            wasCompleted: Consumer<Boolean>
+        ) {
+            callSession.onDisconnect(disconnectCause, wasCompleted)
+        }
+
+        override fun onCallStreamingStarted(wasCompleted: Consumer<Boolean>) {
+            TODO("Implement with the CallStreaming code")
+        }
+    }
+
+    class CallEventCallbackImpl(private val callChannels: CallChannels) :
+        android.telecom.CallEventCallback {
+        override fun onCallEndpointChanged(
+            endpoint: android.telecom.CallEndpoint
+        ) {
+            callChannels.currentEndpointChannel.trySend(
+                EndpointUtils.Api34PlusImpl.toCallEndpointCompat(endpoint)
+            ).getOrThrow()
+        }
+
+        override fun onAvailableCallEndpointsChanged(
+            endpoints: List<android.telecom.CallEndpoint>
+        ) {
+            callChannels.availableEndpointChannel.trySend(
+                EndpointUtils.Api34PlusImpl.toCallEndpointsCompat(endpoints)
+            ).getOrThrow()
+        }
+
+        override fun onMuteStateChanged(isMuted: Boolean) {
+            callChannels.isMutedChannel.trySend(isMuted).getOrThrow()
+        }
+
+        override fun onCallStreamingFailed(reason: Int) {
+            TODO("Implement with the CallStreaming code")
+        }
+
+        override fun onEvent(event: String, extras: Bundle) {
+            TODO("Implement when events are agreed upon by ICS and package")
+        }
+    }
+
+    /**
+     * CallControl is set by CallsManager#addCall when the CallControl object is returned by the
+     * platform
+     */
+    fun setCallControl(control: android.telecom.CallControl) {
+        mPlatformInterface = control
+    }
+
+    /**
+     * pass in the clients callback implementation for CallControlCallback that is set in the
+     * CallsManager#addCall scope.
+     */
+    fun setCallControlCallback(clientCallbackImpl: CallControlCallback) {
+        mClientInterface = clientCallbackImpl
+    }
+
+    fun hasClientSetCallbacks(): Boolean {
+        return mClientInterface != null
+    }
+
+    /**
+     * Custom OutcomeReceiver that handles the Platform responses to a CallControl API call
+     */
+    inner class CallControlReceiver(deferred: CompletableDeferred<Boolean>) :
+        OutcomeReceiver<Void, CallException> {
+        private val mResultDeferred: CompletableDeferred<Boolean> = deferred
+
+        override fun onResult(r: Void?) {
+            mResultDeferred.complete(true)
+        }
+
+        override fun onError(error: CallException) {
+            mResultDeferred.complete(false)
+        }
+    }
+
+    fun getCallId(): ParcelUuid {
+        return mPlatformInterface!!.callId
+    }
+
+    suspend fun setActive(): Boolean {
+        val result: CompletableDeferred<Boolean> = CompletableDeferred()
+        mPlatformInterface?.setActive(Runnable::run, CallControlReceiver(result))
+        result.await()
+        return result.getCompleted()
+    }
+
+    suspend fun setInactive(): Boolean {
+        val result: CompletableDeferred<Boolean> = CompletableDeferred()
+        mPlatformInterface?.setInactive(Runnable::run, CallControlReceiver(result))
+        result.await()
+        return result.getCompleted()
+    }
+
+    suspend fun answer(videoState: Int): Boolean {
+        val result: CompletableDeferred<Boolean> = CompletableDeferred()
+        mPlatformInterface?.answer(videoState, Runnable::run, CallControlReceiver(result))
+        result.await()
+        return result.getCompleted()
+    }
+
+    suspend fun requestEndpointChange(endpoint: android.telecom.CallEndpoint): Boolean {
+        val result: CompletableDeferred<Boolean> = CompletableDeferred()
+        mPlatformInterface?.requestCallEndpointChange(
+            endpoint,
+            Runnable::run, CallControlReceiver(result)
+        )
+        result.await()
+        return result.getCompleted()
+    }
+
+    suspend fun disconnect(disconnectCause: DisconnectCause): Boolean {
+        val result: CompletableDeferred<Boolean> = CompletableDeferred()
+        mPlatformInterface?.disconnect(
+            disconnectCause,
+            Runnable::run,
+            CallControlReceiver(result)
+        )
+        result.await()
+        return result.getCompleted()
+    }
+
+    /**
+     * CallControlCallback
+     */
+    fun onSetActive(wasCompleted: Consumer<Boolean>) {
+        CoroutineScope(mCoroutineContext).launch {
+            val clientResponse: Boolean = mClientInterface!!.onSetActive()
+            wasCompleted.accept(clientResponse)
+        }
+    }
+
+    fun onSetInactive(wasCompleted: Consumer<Boolean>) {
+        CoroutineScope(mCoroutineContext).launch {
+            val clientResponse: Boolean = mClientInterface!!.onSetInactive()
+            wasCompleted.accept(clientResponse)
+        }
+    }
+
+    fun onAnswer(videoState: Int, wasCompleted: Consumer<Boolean>) {
+        CoroutineScope(mCoroutineContext).launch {
+            val clientResponse: Boolean = mClientInterface!!.onAnswer(videoState)
+            wasCompleted.accept(clientResponse)
+        }
+    }
+
+    fun onDisconnect(cause: DisconnectCause, wasCompleted: Consumer<Boolean>) {
+        CoroutineScope(mCoroutineContext).launch {
+            val clientResponse: Boolean = mClientInterface!!.onDisconnect(cause)
+            wasCompleted.accept(clientResponse)
+        }
+    }
+
+    /**
+     * =========================================================================================
+     *  Simple implementation of [CallControlScope] with a [CallSession] as the session.
+     * =========================================================================================
+     */
+    class CallControlScopeImpl(
+        private val session: CallSession,
+        callChannels: CallChannels
+    ) : CallControlScope {
+        //  handle actionable/handshake events that originate in the platform
+        //  and require a response from the client
+        override fun setCallback(callControlCallback: CallControlCallback) {
+            session.setCallControlCallback(callControlCallback)
+        }
+
+        // handle requests that originate from the client and propagate into platform
+        //  return the platforms response which indicates success of the request.
+        override fun getCallId(): ParcelUuid {
+            verifySessionCallbacks()
+            return session.getCallId()
+        }
+
+        override suspend fun setActive(): Boolean {
+            verifySessionCallbacks()
+            return session.setActive()
+        }
+
+        override suspend fun setInactive(): Boolean {
+            verifySessionCallbacks()
+            return session.setInactive()
+        }
+
+        override suspend fun answer(callType: Int): Boolean {
+            verifySessionCallbacks()
+            return session.answer(callType)
+        }
+
+        override suspend fun disconnect(disconnectCause: DisconnectCause): Boolean {
+            verifySessionCallbacks()
+            return session.disconnect(disconnectCause)
+        }
+
+        override suspend fun requestEndpointChange(endpoint: CallEndpointCompat):
+            Boolean {
+            verifySessionCallbacks()
+            return session.requestEndpointChange(
+                EndpointUtils.Api34PlusImpl.toCallEndpoint(endpoint)
+            )
+        }
+
+        // Send these events out to the client to collect
+        override val currentCallEndpoint: Flow<CallEndpointCompat> =
+            callChannels.currentEndpointChannel.receiveAsFlow()
+
+        override val availableEndpoints: Flow<List<CallEndpointCompat>> =
+            callChannels.availableEndpointChannel.receiveAsFlow()
+
+        override val isMuted: Flow<Boolean> =
+            callChannels.isMutedChannel.receiveAsFlow()
+
+        private fun verifySessionCallbacks() {
+            if (!session.hasClientSetCallbacks()) {
+                throw androidx.core.telecom.CallException(
+                    androidx.core.telecom.CallException.ERROR_CALLBACKS_CODE)
+            }
+        }
+    }
+}
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSessionLegacy.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSessionLegacy.kt
new file mode 100644
index 0000000..f0a632c
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/CallSessionLegacy.kt
@@ -0,0 +1,322 @@
+/*
+ * 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.core.telecom.internal
+
+import android.bluetooth.BluetoothDevice
+import android.os.Build
+import android.os.Build.VERSION_CODES
+import android.os.ParcelUuid
+import android.telecom.CallAudioState
+import android.telecom.DisconnectCause
+import android.util.Log
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallControlCallback
+import androidx.core.telecom.CallControlScope
+import androidx.core.telecom.CallEndpointCompat
+import androidx.core.telecom.CallException
+import androidx.core.telecom.internal.utils.EndpointUtils
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.receiveAsFlow
+import kotlinx.coroutines.launch
+
+@RequiresApi(VERSION_CODES.O)
+internal class CallSessionLegacy(
+    private val id: ParcelUuid,
+    private val callChannels: CallChannels,
+    private val coroutineContext: CoroutineContext
+) : android.telecom.Connection() {
+    // instance vars
+    private val TAG: String = CallSessionLegacy::class.java.simpleName
+    private var mClientInterface: CallControlCallback? = null
+    private var mCachedBluetoothDevices: ArrayList<BluetoothDevice> = ArrayList()
+
+    companion object {
+        // CallStates. All these states mirror the values in the platform.
+        const val STATE_INITIALIZING = 0
+        const val STATE_NEW = 1
+        const val STATE_RINGING = 2
+        const val STATE_DIALING = 3
+        const val STATE_ACTIVE = 4
+        const val STATE_HOLDING = 5
+        const val STATE_DISCONNECTED = 6
+    }
+
+    fun setCallControlCallback(callControlCallback: CallControlCallback) {
+        mClientInterface = callControlCallback
+    }
+
+    fun hasClientSetCallbacks(): Boolean {
+        return mClientInterface != null
+    }
+
+    /**
+     * =========================================================================================
+     *                Call State Updates
+     * =========================================================================================
+     */
+    override fun onStateChanged(state: Int) {
+        Log.v(TAG, "onStateChanged: state=${platformCallStateToString(state)}")
+    }
+
+    private fun platformCallStateToString(state: Int): String {
+        return when (state) {
+            STATE_INITIALIZING -> "INITIALIZING"
+            STATE_NEW -> "NEW"
+            STATE_DIALING -> "DIALING"
+            STATE_RINGING -> "RINGING"
+            STATE_ACTIVE -> "ACTIVE"
+            STATE_HOLDING -> "HOLDING"
+            STATE_DISCONNECTED -> "DISCONNECTED"
+            else -> "UNKNOWN"
+        }
+    }
+
+    /**
+     * =========================================================================================
+     *                Audio Updates
+     * =========================================================================================
+     */
+    override fun onCallAudioStateChanged(state: CallAudioState) {
+        if (Build.VERSION.SDK_INT >= VERSION_CODES.P) {
+            Api28PlusImpl.refreshBluetoothDeviceCache(mCachedBluetoothDevices, state)
+        }
+        callChannels.currentEndpointChannel.trySend(
+            EndpointUtils.toCallEndpointCompat(state)
+        ).getOrThrow()
+
+        callChannels.availableEndpointChannel.trySend(
+            EndpointUtils.toCallEndpointsCompat(state)
+        ).getOrThrow()
+
+        callChannels.isMutedChannel.trySend(state.isMuted).getOrThrow()
+    }
+
+    /**
+     * =========================================================================================
+     *                CallControl
+     * =========================================================================================
+     */
+
+    fun getCallId(): ParcelUuid {
+        return id
+    }
+
+    fun answer(videoState: Int): Boolean {
+        setVideoState(videoState)
+        setActive()
+        return true
+    }
+
+    fun setConnectionActive(): Boolean {
+        setActive()
+        return true
+    }
+
+    fun setConnectionInactive(): Boolean {
+        setOnHold()
+        return true
+    }
+
+    fun setConnectionDisconnect(cause: DisconnectCause): Boolean {
+        setDisconnected(cause)
+        destroy()
+        return true
+    }
+
+    // TODO:: verify the CallEndpoint change was successful. tracking bug: b/283324578
+    @Suppress("deprecation")
+    fun requestEndpointChange(callEndpoint: CallEndpointCompat): Boolean {
+        return if (Build.VERSION.SDK_INT < VERSION_CODES.P) {
+            Api26PlusImpl.setAudio(callEndpoint, this)
+            true
+        } else {
+            Api28PlusImpl.setAudio(callEndpoint, this, mCachedBluetoothDevices)
+        }
+    }
+
+    @Suppress("deprecation")
+    @RequiresApi(VERSION_CODES.O)
+    private object Api26PlusImpl {
+        @JvmStatic
+        @DoNotInline
+        fun setAudio(callEndpoint: CallEndpointCompat, connection: CallSessionLegacy) {
+            connection.setAudioRoute(EndpointUtils.mapTypeToRoute(callEndpoint.type))
+        }
+    }
+
+    @Suppress("deprecation")
+    @RequiresApi(VERSION_CODES.P)
+    private object Api28PlusImpl {
+        @JvmStatic
+        @DoNotInline
+        fun setAudio(
+            callEndpoint: CallEndpointCompat,
+            connection: CallSessionLegacy,
+            btCache: ArrayList<BluetoothDevice>
+        ): Boolean {
+            if (callEndpoint.type == CallEndpointCompat.TYPE_BLUETOOTH) {
+                val btDevice = getBluetoothDeviceFromEndpoint(btCache, callEndpoint)
+                if (btDevice != null) {
+                    connection.requestBluetoothAudio(btDevice)
+                    return true
+                }
+                return false
+            } else {
+                connection.setAudioRoute(EndpointUtils.mapTypeToRoute(callEndpoint.type))
+                return true
+            }
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun refreshBluetoothDeviceCache(
+            btCacheList: ArrayList<BluetoothDevice>,
+            state: CallAudioState
+        ) {
+            btCacheList.clear()
+            btCacheList.addAll(state.supportedBluetoothDevices)
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun getBluetoothDeviceFromEndpoint(
+            btCacheList: ArrayList<BluetoothDevice>,
+            endpoint: CallEndpointCompat
+        ): BluetoothDevice? {
+            for (btDevice in btCacheList) {
+                if (bluetoothDeviceMatchesEndpoint(btDevice, endpoint)) {
+                    return btDevice
+                }
+            }
+            return null
+        }
+
+        fun bluetoothDeviceMatchesEndpoint(btDevice: BluetoothDevice, endpoint: CallEndpointCompat):
+            Boolean {
+            return (btDevice.address?.equals(endpoint.mMackAddress) ?: false)
+        }
+    }
+
+    /**
+     * =========================================================================================
+     *                           CallControlCallbacks
+     * =========================================================================================
+     */
+    override fun onAnswer(videoState: Int) {
+        CoroutineScope(coroutineContext).launch {
+            val clientCanAnswer = mClientInterface!!.onAnswer(videoState)
+            if (clientCanAnswer) {
+                setActive()
+                setVideoState(videoState)
+            }
+        }
+    }
+
+    override fun onUnhold() {
+        CoroutineScope(coroutineContext).launch {
+            val clientCanUnhold = mClientInterface!!.onSetActive()
+            if (clientCanUnhold) {
+                setActive()
+            }
+        }
+    }
+
+    override fun onHold() {
+        CoroutineScope(coroutineContext).launch {
+            val clientCanHold = mClientInterface!!.onSetInactive()
+            if (clientCanHold) {
+                setOnHold()
+            }
+        }
+    }
+
+    override fun onDisconnect() {
+        CoroutineScope(coroutineContext).launch {
+            mClientInterface!!.onDisconnect(
+                DisconnectCause(DisconnectCause.LOCAL)
+            )
+            setDisconnected(DisconnectCause(DisconnectCause.LOCAL))
+        }
+    }
+
+    /**
+     * =========================================================================================
+     *  Simple implementation of [CallControlScope] with a [CallSessionLegacy] as the session.
+     * =========================================================================================
+     */
+    class CallControlScopeImpl(
+        private val session: CallSessionLegacy,
+        callChannels: CallChannels
+    ) : CallControlScope {
+        //  handle actionable/handshake events that originate in the platform
+        //  and require a response from the client
+        override fun setCallback(callControlCallback: CallControlCallback) {
+            session.setCallControlCallback(callControlCallback)
+        }
+
+        // handle requests that originate from the client and propagate into platform
+        //  return the platforms response which indicates success of the request.
+        override fun getCallId(): ParcelUuid {
+            verifySessionCallbacks()
+            return session.getCallId()
+        }
+
+        override suspend fun setActive(): Boolean {
+            verifySessionCallbacks()
+            return session.setConnectionActive()
+        }
+
+        override suspend fun setInactive(): Boolean {
+            verifySessionCallbacks()
+            return session.setConnectionInactive()
+        }
+
+        override suspend fun answer(callType: Int): Boolean {
+            verifySessionCallbacks()
+            return session.answer(callType)
+        }
+
+        override suspend fun disconnect(disconnectCause: DisconnectCause): Boolean {
+            verifySessionCallbacks()
+            return session.setConnectionDisconnect(disconnectCause)
+        }
+
+        override suspend fun requestEndpointChange(endpoint: CallEndpointCompat): Boolean {
+            verifySessionCallbacks()
+            return session.requestEndpointChange(endpoint)
+        }
+
+        // Send these events out to the client to collect
+        override val currentCallEndpoint: Flow<CallEndpointCompat> =
+            callChannels.currentEndpointChannel.receiveAsFlow()
+
+        override val availableEndpoints: Flow<List<CallEndpointCompat>> =
+            callChannels.availableEndpointChannel.receiveAsFlow()
+
+        override val isMuted: Flow<Boolean> =
+            callChannels.isMutedChannel.receiveAsFlow()
+
+        private fun verifySessionCallbacks() {
+            if (!session.hasClientSetCallbacks()) {
+                throw CallException(CallException.ERROR_CALLBACKS_CODE)
+            }
+        }
+    }
+}
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/JetpackConnectionService.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/JetpackConnectionService.kt
new file mode 100644
index 0000000..5e9aa66
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/JetpackConnectionService.kt
@@ -0,0 +1,219 @@
+/*
+ * 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.core.telecom.internal
+
+import android.os.Build
+import android.os.ParcelUuid
+import android.telecom.Connection
+import android.telecom.ConnectionRequest
+import android.telecom.ConnectionService
+import android.telecom.PhoneAccountHandle
+import android.telecom.TelecomManager
+import android.telecom.VideoProfile
+import androidx.annotation.RequiresApi
+import androidx.annotation.RequiresPermission
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.internal.utils.Utils
+import java.util.UUID
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CompletableDeferred
+
+@RequiresApi(api = Build.VERSION_CODES.O)
+internal class JetpackConnectionService : ConnectionService() {
+    /**
+     * Wrap all the objects that are associated with a new CallSession request into a class
+     */
+    data class PendingConnectionRequest(
+        val callAttributes: CallAttributesCompat,
+        val callChannel: CallChannels,
+        val coroutineContext: CoroutineContext,
+        val completableDeferred: CompletableDeferred<CallSessionLegacy>?
+    )
+
+    companion object {
+        const val CONNECTION_CREATION_TIMEOUT: Long = 5000 // time in milli-seconds
+        var mPendingConnectionRequests: ArrayList<PendingConnectionRequest> = ArrayList()
+    }
+
+    /**
+     * Request the Platform create a new Connection with the properties given by [CallAttributesCompat].
+     * This request will have a timeout of [CONNECTION_CREATION_TIMEOUT] and be removed when the
+     * result is completed.
+     */
+    @RequiresPermission(value = "android.permission.MANAGE_OWN_CALLS")
+    fun createConnectionRequest(
+        telecomManager: TelecomManager,
+        pendingConnectionRequest: PendingConnectionRequest,
+    ) {
+        // add request to list
+        mPendingConnectionRequests.add(pendingConnectionRequest)
+
+        val extras = Utils.getBundleWithPhoneAccountHandle(
+            pendingConnectionRequest.callAttributes,
+            pendingConnectionRequest.callAttributes.mHandle!!
+        )
+
+        // Call into the platform to start call
+        if (pendingConnectionRequest.callAttributes.isOutgoingCall()) {
+            telecomManager.placeCall(
+                pendingConnectionRequest.callAttributes.address,
+                extras
+            )
+        } else {
+            telecomManager.addNewIncomingCall(
+                pendingConnectionRequest.callAttributes.mHandle,
+                extras
+            )
+        }
+    }
+
+    /**
+     *  Outgoing Connections
+     */
+    override fun onCreateOutgoingConnection(
+        connectionManagerAccount: PhoneAccountHandle,
+        request: ConnectionRequest
+    ): Connection? {
+        return createSelfManagedConnection(
+            request,
+            CallAttributesCompat.DIRECTION_OUTGOING
+        )
+    }
+
+    override fun onCreateOutgoingConnectionFailed(
+        connectionManagerPhoneAccount: PhoneAccountHandle,
+        request: ConnectionRequest
+    ) {
+        val pendingRequest: PendingConnectionRequest? =
+            findTargetPendingConnectionRequest(
+                request,
+                CallAttributesCompat.DIRECTION_OUTGOING
+            )
+        pendingRequest?.completableDeferred?.cancel()
+
+        mPendingConnectionRequests.remove(pendingRequest)
+    }
+
+    /**
+     *  Incoming Connections
+     */
+    override fun onCreateIncomingConnection(
+        connectionManagerPhoneAccount: PhoneAccountHandle,
+        request: ConnectionRequest
+    ): Connection? {
+        return createSelfManagedConnection(
+            request,
+            CallAttributesCompat.DIRECTION_INCOMING
+        )
+    }
+
+    override fun onCreateIncomingConnectionFailed(
+        connectionManagerPhoneAccount: PhoneAccountHandle,
+        request: ConnectionRequest
+    ) {
+        val pendingRequest: PendingConnectionRequest? =
+            findTargetPendingConnectionRequest(
+                request,
+                CallAttributesCompat.DIRECTION_INCOMING
+            )
+        pendingRequest?.completableDeferred?.cancel()
+        mPendingConnectionRequests.remove(pendingRequest)
+    }
+
+    internal fun createSelfManagedConnection(request: ConnectionRequest, direction: Int):
+        Connection? {
+        val targetRequest: PendingConnectionRequest =
+            findTargetPendingConnectionRequest(request, direction) ?: return null
+
+        val jetpackConnection = CallSessionLegacy(
+            ParcelUuid.fromString(UUID.randomUUID().toString()),
+            targetRequest.callChannel,
+            targetRequest.coroutineContext
+        )
+
+        // set display name
+        jetpackConnection.setCallerDisplayName(
+            targetRequest.callAttributes.displayName.toString(),
+            TelecomManager.PRESENTATION_ALLOWED
+        )
+
+        // set address
+        jetpackConnection.setAddress(
+            targetRequest.callAttributes.address,
+            TelecomManager.PRESENTATION_ALLOWED
+        )
+
+        // set the call state for the given direction
+        if (direction == CallAttributesCompat.DIRECTION_OUTGOING) {
+            jetpackConnection.setDialing()
+        } else {
+            jetpackConnection.setRinging()
+        }
+
+        // set the callType
+        if (targetRequest.callAttributes.callType
+            == CallAttributesCompat.CALL_TYPE_VIDEO_CALL
+        ) {
+            jetpackConnection.setVideoState(VideoProfile.STATE_BIDIRECTIONAL)
+        } else {
+            jetpackConnection.setVideoState(VideoProfile.STATE_AUDIO_ONLY)
+        }
+
+        // set the call capabilities
+        if (targetRequest.callAttributes.hasSupportsSetInactiveCapability()) {
+            jetpackConnection.setConnectionCapabilities(
+                Connection.CAPABILITY_HOLD or Connection.CAPABILITY_SUPPORT_HOLD
+            )
+        }
+
+        targetRequest.completableDeferred?.complete(jetpackConnection)
+        mPendingConnectionRequests.remove(targetRequest)
+        return jetpackConnection
+    }
+
+    /**
+     *  Helper methods
+     */
+    private fun findTargetPendingConnectionRequest(
+        request: ConnectionRequest,
+        direction: Int
+    ): PendingConnectionRequest? {
+        for (pendingConnectionRequest in mPendingConnectionRequests) {
+            if (isSameAddress(pendingConnectionRequest.callAttributes, request) &&
+                isSameDirection(pendingConnectionRequest.callAttributes, direction) &&
+                isSameHandle(pendingConnectionRequest.callAttributes.mHandle, request)
+            ) {
+                return pendingConnectionRequest
+            }
+        }
+        return null
+    }
+
+    private fun isSameDirection(callAttributes: CallAttributesCompat, direction: Int): Boolean {
+        return (callAttributes.direction == direction)
+    }
+
+    private fun isSameAddress(
+        callAttributes: CallAttributesCompat,
+        request: ConnectionRequest
+    ): Boolean {
+        return request.address?.equals(callAttributes.address) ?: false
+    }
+
+    private fun isSameHandle(handle: PhoneAccountHandle?, request: ConnectionRequest): Boolean {
+        return request.accountHandle?.equals(handle) ?: false
+    }
+}
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt
new file mode 100644
index 0000000..9c40d14
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/BuildVersionAdapter.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.core.telecom.internal.utils
+
+internal interface BuildVersionAdapter {
+    fun hasPlatformV2Apis(): Boolean
+    fun hasInvalidBuildVersion(): Boolean
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/CallAttributesUtils.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/CallAttributesUtils.kt
new file mode 100644
index 0000000..5148edd
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/CallAttributesUtils.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.core.telecom.internal.utils
+
+import android.net.Uri
+import android.telecom.PhoneAccountHandle
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+
+@RequiresApi(34)
+internal class CallAttributesUtils {
+    internal object Api34PlusImpl {
+        @JvmStatic
+        @DoNotInline
+        fun toTelecomCallAttributes(
+            phoneAccountHandle: PhoneAccountHandle,
+            direction: Int,
+            displayName: CharSequence,
+            address: Uri,
+            callType: Int,
+            callCapabilities: Int
+        ): android.telecom.CallAttributes {
+            return android.telecom.CallAttributes.Builder(
+                phoneAccountHandle,
+                direction,
+                displayName,
+                address
+            )
+                .setCallType(remapCallType(callType))
+                .setCallCapabilities(remapCapabilities(callCapabilities))
+                .build()
+        }
+
+        private fun remapCallType(callType: Int): Int {
+            return if (callType == CallAttributesCompat.CALL_TYPE_AUDIO_CALL) {
+                android.telecom.CallAttributes.AUDIO_CALL
+            } else {
+                android.telecom.CallAttributes.VIDEO_CALL
+            }
+        }
+
+        private fun remapCapabilities(callCapabilities: Int): Int {
+            var bitMap: Int = 0
+            if (hasSupportsSetInactiveCapability(callCapabilities)) {
+                bitMap = bitMap or android.telecom.CallAttributes.SUPPORTS_SET_INACTIVE
+            }
+            if (hasStreamCapability(callCapabilities)) {
+                bitMap = bitMap or android.telecom.CallAttributes.SUPPORTS_STREAM
+            }
+            if (hasTransferCapability(callCapabilities)) {
+                bitMap = bitMap or android.telecom.CallAttributes.SUPPORTS_TRANSFER
+            }
+            return bitMap
+        }
+
+        private fun hasSupportsSetInactiveCapability(callCapabilities: Int): Boolean {
+            return Utils.hasCapability(CallAttributesCompat.SUPPORTS_SET_INACTIVE, callCapabilities)
+        }
+
+        private fun hasStreamCapability(callCapabilities: Int): Boolean {
+            return Utils.hasCapability(CallAttributesCompat.SUPPORTS_STREAM, callCapabilities)
+        }
+
+        private fun hasTransferCapability(callCapabilities: Int): Boolean {
+            return Utils.hasCapability(CallAttributesCompat.SUPPORTS_TRANSFER, callCapabilities)
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/EndpointUtils.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/EndpointUtils.kt
new file mode 100644
index 0000000..7075dc5
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/EndpointUtils.kt
@@ -0,0 +1,217 @@
+/*
+ * 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.core.telecom.internal.utils
+
+import android.bluetooth.BluetoothDevice
+import android.os.Build
+import android.os.Build.VERSION.SDK_INT
+import android.os.Build.VERSION_CODES.P
+import android.telecom.CallAudioState
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallEndpointCompat
+
+@RequiresApi(Build.VERSION_CODES.O)
+internal class EndpointUtils {
+
+    companion object {
+        fun toCallEndpointCompat(state: CallAudioState): CallEndpointCompat {
+            val type: Int = mapRouteToType(state.route)
+            return if (type == CallEndpointCompat.TYPE_BLUETOOTH && SDK_INT >= P) {
+                BluetoothApi28PlusImpl.getCallEndpointFromAudioState(state)
+            } else {
+                CallEndpointCompat(endpointTypeToString(type), type)
+            }
+        }
+
+        fun toCallEndpointsCompat(state: CallAudioState): List<CallEndpointCompat> {
+            val endpoints: ArrayList<CallEndpointCompat> = ArrayList()
+            val bitMask = state.supportedRouteMask
+            if (hasEarpieceType(bitMask)) {
+                endpoints.add(
+                    CallEndpointCompat(
+                        endpointTypeToString(CallEndpointCompat.TYPE_EARPIECE),
+                        CallEndpointCompat.TYPE_EARPIECE
+                    )
+                )
+            }
+            if (hasBluetoothType(bitMask)) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                    endpoints.addAll(BluetoothApi28PlusImpl.getBluetoothEndpoints(state))
+                } else {
+                    endpoints.add(
+                        CallEndpointCompat(
+                            endpointTypeToString(CallEndpointCompat.TYPE_BLUETOOTH),
+                            CallEndpointCompat.TYPE_BLUETOOTH
+                        )
+                    )
+                }
+            }
+            if (hasWiredHeadsetType(bitMask)) {
+                endpoints.add(
+                    CallEndpointCompat(
+                        endpointTypeToString(CallEndpointCompat.TYPE_WIRED_HEADSET),
+                        CallEndpointCompat.TYPE_WIRED_HEADSET
+                    )
+                )
+            }
+            if (hasSpeakerType(bitMask)) {
+                endpoints.add(
+                    CallEndpointCompat(
+                        endpointTypeToString(CallEndpointCompat.TYPE_SPEAKER),
+                        CallEndpointCompat.TYPE_SPEAKER
+                    )
+                )
+            }
+            if (hasStreamingType(bitMask)) {
+                endpoints.add(
+                    CallEndpointCompat(
+                        endpointTypeToString(CallEndpointCompat.TYPE_STREAMING),
+                        CallEndpointCompat.TYPE_STREAMING
+                    )
+                )
+            }
+            return endpoints
+        }
+
+        private fun hasEarpieceType(bitMap: Int): Boolean {
+            return (bitMap.and(CallAudioState.ROUTE_EARPIECE)) == CallAudioState.ROUTE_EARPIECE
+        }
+
+        fun hasBluetoothType(bitMap: Int): Boolean {
+            return (bitMap.and(CallAudioState.ROUTE_BLUETOOTH)) == CallAudioState.ROUTE_BLUETOOTH
+        }
+
+        fun hasWiredHeadsetType(bitMap: Int): Boolean {
+            return (bitMap.and(CallAudioState.ROUTE_WIRED_HEADSET)
+                ) == CallAudioState.ROUTE_WIRED_HEADSET
+        }
+
+        fun hasSpeakerType(bitMap: Int): Boolean {
+            return (bitMap.and(CallAudioState.ROUTE_SPEAKER)) == CallAudioState.ROUTE_SPEAKER
+        }
+
+        fun hasStreamingType(bitMap: Int): Boolean {
+            return (bitMap.and(CallAudioState.ROUTE_STREAMING)) == CallAudioState.ROUTE_STREAMING
+        }
+
+        fun mapRouteToType(route: Int): @CallEndpointCompat.Companion.EndpointType Int {
+            return when (route) {
+                CallAudioState.ROUTE_EARPIECE -> CallEndpointCompat.TYPE_EARPIECE
+                CallAudioState.ROUTE_BLUETOOTH -> CallEndpointCompat.TYPE_BLUETOOTH
+                CallAudioState.ROUTE_WIRED_HEADSET -> CallEndpointCompat.TYPE_WIRED_HEADSET
+                CallAudioState.ROUTE_SPEAKER -> CallEndpointCompat.TYPE_SPEAKER
+                CallAudioState.ROUTE_STREAMING -> CallEndpointCompat.TYPE_STREAMING
+                else -> CallEndpointCompat.TYPE_UNKNOWN
+            }
+        }
+
+        fun mapTypeToRoute(route: Int): Int {
+            return when (route) {
+                CallEndpointCompat.TYPE_EARPIECE -> CallAudioState.ROUTE_EARPIECE
+                CallEndpointCompat.TYPE_BLUETOOTH -> CallAudioState.ROUTE_BLUETOOTH
+                CallEndpointCompat.TYPE_WIRED_HEADSET -> CallAudioState.ROUTE_WIRED_HEADSET
+                CallEndpointCompat.TYPE_SPEAKER -> CallAudioState.ROUTE_SPEAKER
+                CallEndpointCompat.TYPE_STREAMING -> CallAudioState.ROUTE_STREAMING
+                else -> CallAudioState.ROUTE_EARPIECE
+            }
+        }
+
+        fun endpointTypeToString(endpointType: Int): String {
+            return when (endpointType) {
+                CallEndpointCompat.TYPE_EARPIECE -> "EARPIECE"
+                CallEndpointCompat.TYPE_BLUETOOTH -> "BLUETOOTH"
+                CallEndpointCompat.TYPE_WIRED_HEADSET -> "WIRED_HEADSET"
+                CallEndpointCompat.TYPE_SPEAKER -> "SPEAKER"
+                CallEndpointCompat.TYPE_STREAMING -> "EXTERNAL"
+                else -> "UNKNOWN ($endpointType)"
+            }
+        }
+    }
+
+    @RequiresApi(34)
+    object Api34PlusImpl {
+        @JvmStatic
+        @DoNotInline
+        fun toCallEndpointCompat(endpoint: android.telecom.CallEndpoint):
+            CallEndpointCompat {
+            return CallEndpointCompat(
+                endpoint.endpointName,
+                endpoint.endpointType,
+                endpoint.identifier
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun toCallEndpointsCompat(endpoints: List<android.telecom.CallEndpoint>):
+            List<CallEndpointCompat> {
+            val res = ArrayList<CallEndpointCompat>()
+            for (e in endpoints) {
+                res.add(CallEndpointCompat(e.endpointName, e.endpointType, e.identifier))
+            }
+            return res
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun toCallEndpoint(e: CallEndpointCompat): android.telecom.CallEndpoint {
+            return android.telecom.CallEndpoint(e.name, e.type, e.identifier)
+        }
+    }
+
+    @RequiresApi(28)
+    object BluetoothApi28PlusImpl {
+        @JvmStatic
+        @DoNotInline
+        fun getBluetoothEndpoints(state: CallAudioState):
+            ArrayList<CallEndpointCompat> {
+            val endpoints: ArrayList<CallEndpointCompat> = ArrayList()
+            val supportedBluetoothDevices = state.supportedBluetoothDevices
+            for (bluetoothDevice in supportedBluetoothDevices) {
+                endpoints.add(getCallEndpointFromBluetoothDevice(bluetoothDevice))
+            }
+            return endpoints
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun getCallEndpointFromBluetoothDevice(btDevice: BluetoothDevice?): CallEndpointCompat {
+            var endpointName: String = "Bluetooth Device"
+            var endpointIdentity: String = "Unknown Address"
+            if (btDevice != null) {
+                endpointIdentity = btDevice.address
+                try {
+                    endpointName = btDevice.name
+                } catch (e: SecurityException) {
+                    // pass through
+                }
+            }
+            return CallEndpointCompat(
+                endpointName,
+                CallEndpointCompat.TYPE_BLUETOOTH,
+                endpointIdentity
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun getCallEndpointFromAudioState(state: CallAudioState): CallEndpointCompat {
+            return getCallEndpointFromBluetoothDevice(state.activeBluetoothDevice)
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt
new file mode 100644
index 0000000..4ab0ec2
--- /dev/null
+++ b/core/core-telecom/src/main/java/androidx/core/telecom/internal/utils/Utils.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.core.telecom.internal.utils
+
+import android.os.Build.VERSION
+import android.os.Build.VERSION_CODES
+import android.os.Bundle
+import android.telecom.PhoneAccount
+import android.telecom.PhoneAccountHandle
+import android.telecom.TelecomManager
+import android.util.Log
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.core.telecom.CallAttributesCompat
+import androidx.core.telecom.CallException
+import androidx.core.telecom.CallsManager
+
+internal class Utils {
+    companion object {
+        private val TAG = Utils.Companion::class.java.simpleName
+
+        private val defaultBuildAdapter =
+            object : BuildVersionAdapter {
+                /**
+                 * Helper method that determines if the device has a build that contains the Telecom V2
+                 * VoIP APIs. These include [TelecomManager#addCall], android.telecom.CallControl,
+                 * android.telecom.CallEventCallback but are not limited to only those classes.
+                 */
+                override fun hasPlatformV2Apis(): Boolean {
+                    Log.i(TAG, "hasPlatformV2Apis: " +
+                        "versionSdkInt=[${VERSION.SDK_INT}]")
+                    return VERSION.SDK_INT >= 34 || VERSION.CODENAME == "UpsideDownCake"
+                }
+
+                override fun hasInvalidBuildVersion(): Boolean {
+                    Log.i(TAG, "hasInvalidBuildVersion: " +
+                        "versionSdkInt=[${VERSION.SDK_INT}]")
+                    return VERSION.SDK_INT < VERSION_CODES.O
+                }
+            }
+        private var mBuildVersion: BuildVersionAdapter = defaultBuildAdapter
+
+        internal fun setUtils(utils: BuildVersionAdapter) {
+            mBuildVersion = utils
+        }
+
+        internal fun resetUtils() {
+            mBuildVersion = defaultBuildAdapter
+        }
+
+        fun hasPlatformV2Apis(): Boolean {
+            return mBuildVersion.hasPlatformV2Apis()
+        }
+
+        fun hasInvalidBuildVersion(): Boolean {
+            return mBuildVersion.hasInvalidBuildVersion()
+        }
+
+        fun verifyBuildVersion() {
+            if (mBuildVersion.hasInvalidBuildVersion()) {
+                throw UnsupportedOperationException(CallException.ERROR_BUILD_VERSION)
+            }
+        }
+
+        fun remapJetpackCapabilitiesToPlatformCapabilities(
+            @CallsManager.Companion.Capability clientBitmapSelection: Int
+        ): Int {
+            var remappedCapabilities = 0
+
+            if (hasJetpackVideoCallingCapability(clientBitmapSelection)) {
+                remappedCapabilities =
+                    PhoneAccount.CAPABILITY_SUPPORTS_VIDEO_CALLING or
+                        remappedCapabilities
+            }
+
+            if (hasJetpackSteamingCapability(clientBitmapSelection)) {
+                remappedCapabilities =
+                    PhoneAccount.CAPABILITY_SUPPORTS_CALL_STREAMING or
+                        remappedCapabilities
+            }
+            return remappedCapabilities
+        }
+
+        fun hasCapability(targetCapability: Int, bitMap: Int): Boolean {
+            return (bitMap.and(targetCapability)) == targetCapability
+        }
+
+        private fun hasJetpackVideoCallingCapability(bitMap: Int): Boolean {
+            return hasCapability(CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING, bitMap)
+        }
+
+        private fun hasJetpackSteamingCapability(bitMap: Int): Boolean {
+            return hasCapability(CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING, bitMap)
+        }
+
+        fun getBundleWithPhoneAccountHandle(
+            callAttributes: CallAttributesCompat,
+            handle: PhoneAccountHandle
+        ): Bundle {
+            return if (VERSION.SDK_INT >= VERSION_CODES.M) {
+                Api23PlusImpl.createExtras(callAttributes, handle)
+            } else {
+                Bundle()
+            }
+        }
+
+        @RequiresApi(VERSION_CODES.M)
+        private object Api23PlusImpl {
+            @JvmStatic
+            @DoNotInline
+            fun createExtras(
+                callAttributes: CallAttributesCompat,
+                handle: PhoneAccountHandle
+            ): Bundle {
+                val extras = Bundle()
+                extras.putParcelable(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+                    handle
+                )
+                if (!callAttributes.isOutgoingCall()) {
+                    extras.putParcelable(
+                        TelecomManager.EXTRA_INCOMING_CALL_ADDRESS,
+                        callAttributes.address
+                    )
+                }
+                return extras
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/core-testing/build.gradle b/core/core-testing/build.gradle
index 1708420..0b16fd2 100644
--- a/core/core-testing/build.gradle
+++ b/core/core-testing/build.gradle
@@ -28,7 +28,7 @@
         implementation(project(":core:core"))
     }
     api(libs.kotlinStdlib)
-    implementation("androidx.annotation:annotation-jvm:1.6.0")
+    implementation("androidx.annotation:annotation:1.6.0")
     api(project(":core:core"))
 
     testImplementation(libs.testCore)
diff --git a/core/core/api/1.11.0-beta01.txt b/core/core/api/1.11.0-beta01.txt
index 128f0c4..fa087dc 100644
--- a/core/core/api/1.11.0-beta01.txt
+++ b/core/core/api/1.11.0-beta01.txt
@@ -1842,19 +1842,12 @@
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
     method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
-    method @Deprecated @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
-    method @Deprecated @ChecksSdkIntAtLeast(api=33, codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
-    method @ChecksSdkIntAtLeast(api=34, codename="UpsideDownCake") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastU();
-    method @ChecksSdkIntAtLeast(codename="VanillaIceCream") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastV();
     field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
   }
 
-  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface BuildCompat.PrereleaseSdkCheck {
-  }
-
   public final class BundleCompat {
     method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
     method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 128f0c4..ca9c5ca 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -156,6 +156,15 @@
     field public static final int TOTAL_INDEX = 0; // 0x0
   }
 
+  public final class GrammaticalInflectionManagerCompat {
+    method @AnyThread public static int getApplicationGrammaticalGender(android.content.Context);
+    method @AnyThread public static void setRequestedApplicationGrammaticalGender(android.content.Context, int);
+    field public static final int GRAMMATICAL_GENDER_FEMININE = 2; // 0x2
+    field public static final int GRAMMATICAL_GENDER_MASCULINE = 3; // 0x3
+    field public static final int GRAMMATICAL_GENDER_NEUTRAL = 1; // 0x1
+    field public static final int GRAMMATICAL_GENDER_NOT_SPECIFIED = 0; // 0x0
+  }
+
   @Deprecated public abstract class JobIntentService extends android.app.Service {
     ctor @Deprecated public JobIntentService();
     method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
@@ -794,6 +803,7 @@
 
   public final class NotificationManagerCompat {
     method public boolean areNotificationsEnabled();
+    method public boolean canUseFullScreenIntent();
     method public void cancel(int);
     method public void cancel(String?, int);
     method public void cancelAll();
@@ -954,6 +964,7 @@
   }
 
   public final class ServiceCompat {
+    method public static void startForeground(android.app.Service, int, android.app.Notification, int);
     method public static void stopForeground(android.app.Service, int);
     field public static final int START_STICKY = 1; // 0x1
     field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
@@ -1107,7 +1118,6 @@
     ctor protected FileProvider(@XmlRes int);
     method public int delete(android.net.Uri, String?, String![]?);
     method public String? getType(android.net.Uri);
-    method public String? getTypeAnonymous(android.net.Uri);
     method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
     method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
     method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
@@ -2057,6 +2067,26 @@
 
 }
 
+package androidx.core.service.quicksettings {
+
+  public class PendingIntentActivityWrapper {
+    ctor public PendingIntentActivityWrapper(android.content.Context, int, android.content.Intent, int, android.os.Bundle?, boolean);
+    ctor public PendingIntentActivityWrapper(android.content.Context, int, android.content.Intent, int, boolean);
+    method public android.content.Context getContext();
+    method public int getFlags();
+    method public android.content.Intent getIntent();
+    method public android.os.Bundle getOptions();
+    method public android.app.PendingIntent? getPendingIntent();
+    method public int getRequestCode();
+    method public boolean isMutable();
+  }
+
+  public class TileServiceCompat {
+    method public static void startActivityAndCollapse(android.service.quicksettings.TileService, androidx.core.service.quicksettings.PendingIntentActivityWrapper);
+  }
+
+}
+
 package androidx.core.telephony {
 
   @RequiresApi(22) public class SubscriptionManagerCompat {
@@ -2205,6 +2235,66 @@
     method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.LOLLIPOP) public final class LocalePreferences {
+    method public static String getCalendarType();
+    method public static String getCalendarType(boolean);
+    method public static String getCalendarType(java.util.Locale);
+    method public static String getCalendarType(java.util.Locale, boolean);
+    method public static String getFirstDayOfWeek();
+    method public static String getFirstDayOfWeek(boolean);
+    method public static String getFirstDayOfWeek(java.util.Locale);
+    method public static String getFirstDayOfWeek(java.util.Locale, boolean);
+    method public static String getHourCycle();
+    method public static String getHourCycle(boolean);
+    method public static String getHourCycle(java.util.Locale);
+    method public static String getHourCycle(java.util.Locale, boolean);
+    method public static String getTemperatureUnit();
+    method public static String getTemperatureUnit(boolean);
+    method public static String getTemperatureUnit(java.util.Locale);
+    method public static String getTemperatureUnit(java.util.Locale, boolean);
+  }
+
+  public static class LocalePreferences.CalendarType {
+    field public static final String CHINESE = "chinese";
+    field public static final String DANGI = "dangi";
+    field public static final String DEFAULT = "";
+    field public static final String GREGORIAN = "gregorian";
+    field public static final String HEBREW = "hebrew";
+    field public static final String INDIAN = "indian";
+    field public static final String ISLAMIC = "islamic";
+    field public static final String ISLAMIC_CIVIL = "islamic-civil";
+    field public static final String ISLAMIC_RGSA = "islamic-rgsa";
+    field public static final String ISLAMIC_TBLA = "islamic-tbla";
+    field public static final String ISLAMIC_UMALQURA = "islamic-umalqura";
+    field public static final String PERSIAN = "persian";
+  }
+
+  public static class LocalePreferences.FirstDayOfWeek {
+    field public static final String DEFAULT = "";
+    field public static final String FRIDAY = "fri";
+    field public static final String MONDAY = "mon";
+    field public static final String SATURDAY = "sat";
+    field public static final String SUNDAY = "sun";
+    field public static final String THURSDAY = "thu";
+    field public static final String TUESDAY = "tue";
+    field public static final String WEDNESDAY = "wed";
+  }
+
+  public static class LocalePreferences.HourCycle {
+    field public static final String DEFAULT = "";
+    field public static final String H11 = "h11";
+    field public static final String H12 = "h12";
+    field public static final String H23 = "h23";
+    field public static final String H24 = "h24";
+  }
+
+  public static class LocalePreferences.TemperatureUnit {
+    field public static final String CELSIUS = "celsius";
+    field public static final String DEFAULT = "";
+    field public static final String FAHRENHEIT = "fahrenhe";
+    field public static final String KELVIN = "kelvin";
+  }
+
 }
 
 package androidx.core.util {
@@ -2224,6 +2314,10 @@
     method public void accept(T!);
   }
 
+  @java.lang.FunctionalInterface public interface Function<T, R> {
+    method public R! apply(T!);
+  }
+
   public class ObjectsCompat {
     method public static boolean equals(Object?, Object?);
     method public static int hash(java.lang.Object!...);
@@ -2286,6 +2380,14 @@
     method public T! get();
   }
 
+  public class TypedValueCompat {
+    method public static float deriveDimension(int, float, android.util.DisplayMetrics);
+    method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static float pxToDp(float, android.util.DisplayMetrics);
+    method public static float pxToSp(float, android.util.DisplayMetrics);
+    method public static float spToPx(float, android.util.DisplayMetrics);
+  }
+
 }
 
 package androidx.core.view {
@@ -2774,9 +2876,12 @@
     method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
   }
 
-  @Deprecated public final class VelocityTrackerCompat {
+  public final class VelocityTrackerCompat {
+    method public static float getAxisVelocity(android.view.VelocityTracker, int);
+    method public static float getAxisVelocity(android.view.VelocityTracker, int, int);
     method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
     method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+    method public static boolean isAxisSupported(android.view.VelocityTracker, int);
   }
 
   public class ViewCompat {
@@ -3005,6 +3110,8 @@
   public final class ViewConfigurationCompat {
     method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
     method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method public static int getScaledMaximumFlingVelocity(android.content.Context, android.view.ViewConfiguration, int, int, int);
+    method public static int getScaledMinimumFlingVelocity(android.content.Context, android.view.ViewConfiguration, int, int, int);
     method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
     method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
     method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
@@ -3301,6 +3408,7 @@
     field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
     field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
     field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 67108864; // 0x4000000
     field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
     field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
     field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
@@ -3393,6 +3501,7 @@
     method public boolean isEnabled();
     method public boolean isFocusable();
     method public boolean isFocused();
+    method public boolean isGranularScrollingSupported();
     method public boolean isHeading();
     method public boolean isImportantForAccessibility();
     method public boolean isLongClickable();
@@ -3437,6 +3546,7 @@
     method public void setError(CharSequence!);
     method public void setFocusable(boolean);
     method public void setFocused(boolean);
+    method public void setGranularScrollingSupported(boolean);
     method public void setHeading(boolean);
     method public void setHintText(CharSequence?);
     method public void setImportantForAccessibility(boolean);
@@ -3483,6 +3593,7 @@
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
     field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
     field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_DIRECTION_INT = "androidx.core.view.accessibility.action.ARGUMENT_DIRECTION_INT";
     field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
@@ -3491,6 +3602,7 @@
     field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
     field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
     field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT = "androidx.core.view.accessibility.action.ARGUMENT_SCROLL_AMOUNT_FLOAT";
     field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
     field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
     field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
@@ -3564,6 +3676,7 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_IN_DIRECTION;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
@@ -3736,6 +3849,7 @@
   }
 
   public class AccessibilityWindowInfoCompat {
+    ctor public AccessibilityWindowInfoCompat();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
     method public void getBoundsInScreen(android.graphics.Rect);
     method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
diff --git a/core/core/api/public_plus_experimental_1.11.0-beta01.txt b/core/core/api/public_plus_experimental_1.11.0-beta01.txt
new file mode 100644
index 0000000..0c385e3
--- /dev/null
+++ b/core/core/api/public_plus_experimental_1.11.0-beta01.txt
@@ -0,0 +1,4061 @@
+// Signature format: 4.0
+package androidx.core.accessibilityservice {
+
+  public final class AccessibilityServiceInfoCompat {
+    method public static String capabilityToString(int);
+    method public static String feedbackTypeToString(int);
+    method public static String? flagToString(int);
+    method public static int getCapabilities(android.accessibilityservice.AccessibilityServiceInfo);
+    method public static String? loadDescription(android.accessibilityservice.AccessibilityServiceInfo, android.content.pm.PackageManager);
+    field public static final int CAPABILITY_CAN_FILTER_KEY_EVENTS = 8; // 0x8
+    field public static final int CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 4; // 0x4
+    field public static final int CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION = 2; // 0x2
+    field public static final int CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT = 1; // 0x1
+    field public static final int FEEDBACK_ALL_MASK = -1; // 0xffffffff
+    field public static final int FEEDBACK_BRAILLE = 32; // 0x20
+    field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
+    field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
+    field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+  }
+
+}
+
+package androidx.core.app {
+
+  public class ActivityCompat extends androidx.core.content.ContextCompat {
+    ctor protected ActivityCompat();
+    method public static void finishAffinity(android.app.Activity);
+    method public static void finishAfterTransition(android.app.Activity);
+    method public static android.net.Uri? getReferrer(android.app.Activity);
+    method @Deprecated public static boolean invalidateOptionsMenu(android.app.Activity!);
+    method public static boolean isLaunchedFromBubble(android.app.Activity);
+    method public static void postponeEnterTransition(android.app.Activity);
+    method public static void recreate(android.app.Activity);
+    method public static androidx.core.view.DragAndDropPermissionsCompat? requestDragAndDropPermissions(android.app.Activity, android.view.DragEvent);
+    method public static void requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+    method public static <T extends android.view.View> T requireViewById(android.app.Activity, @IdRes int);
+    method public static void setEnterSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setExitSharedElementCallback(android.app.Activity, androidx.core.app.SharedElementCallback?);
+    method public static void setLocusContext(android.app.Activity, androidx.core.content.LocusIdCompat?, android.os.Bundle?);
+    method public static void setPermissionCompatDelegate(androidx.core.app.ActivityCompat.PermissionCompatDelegate?);
+    method public static boolean shouldShowRequestPermissionRationale(android.app.Activity, String);
+    method public static void startActivityForResult(android.app.Activity, android.content.Intent, int, android.os.Bundle?);
+    method public static void startIntentSenderForResult(android.app.Activity, android.content.IntentSender, int, android.content.Intent?, int, int, int, android.os.Bundle?) throws android.content.IntentSender.SendIntentException;
+    method public static void startPostponedEnterTransition(android.app.Activity);
+  }
+
+  public static interface ActivityCompat.OnRequestPermissionsResultCallback {
+    method public void onRequestPermissionsResult(int, String![], int[]);
+  }
+
+  public static interface ActivityCompat.PermissionCompatDelegate {
+    method public boolean onActivityResult(android.app.Activity, @IntRange(from=0) int, int, android.content.Intent?);
+    method public boolean requestPermissions(android.app.Activity, String![], @IntRange(from=0) int);
+  }
+
+  public final class ActivityManagerCompat {
+    method public static boolean isLowRamDevice(android.app.ActivityManager);
+  }
+
+  public class ActivityOptionsCompat {
+    ctor protected ActivityOptionsCompat();
+    method public android.graphics.Rect? getLaunchBounds();
+    method public static androidx.core.app.ActivityOptionsCompat makeBasic();
+    method public static androidx.core.app.ActivityOptionsCompat makeClipRevealAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeCustomAnimation(android.content.Context, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, android.view.View, String);
+    method public static androidx.core.app.ActivityOptionsCompat makeSceneTransitionAnimation(android.app.Activity, androidx.core.util.Pair<android.view.View!,java.lang.String!>!...);
+    method public static androidx.core.app.ActivityOptionsCompat makeTaskLaunchBehind();
+    method public static androidx.core.app.ActivityOptionsCompat makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
+    method public void requestUsageTimeReport(android.app.PendingIntent);
+    method public androidx.core.app.ActivityOptionsCompat setLaunchBounds(android.graphics.Rect?);
+    method public android.os.Bundle? toBundle();
+    method public void update(androidx.core.app.ActivityOptionsCompat);
+    field public static final String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+    field public static final String EXTRA_USAGE_TIME_REPORT_PACKAGES = "android.usage_time_packages";
+  }
+
+  public final class AlarmManagerCompat {
+    method public static void setAlarmClock(android.app.AlarmManager, long, android.app.PendingIntent, android.app.PendingIntent);
+    method public static void setAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExact(android.app.AlarmManager, int, long, android.app.PendingIntent);
+    method public static void setExactAndAllowWhileIdle(android.app.AlarmManager, int, long, android.app.PendingIntent);
+  }
+
+  @RequiresApi(28) public class AppComponentFactory extends android.app.AppComponentFactory {
+    ctor public AppComponentFactory();
+    method public final android.app.Activity instantiateActivity(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Activity instantiateActivityCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Application instantiateApplication(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Application instantiateApplicationCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.ContentProvider instantiateProvider(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.ContentProvider instantiateProviderCompat(ClassLoader, String) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.content.BroadcastReceiver instantiateReceiver(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.content.BroadcastReceiver instantiateReceiverCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public final android.app.Service instantiateService(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public android.app.Service instantiateServiceCompat(ClassLoader, String, android.content.Intent?) throws java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+  }
+
+  public class AppLaunchChecker {
+    ctor @Deprecated public AppLaunchChecker();
+    method public static boolean hasStartedFromLauncher(android.content.Context);
+    method public static void onActivityCreate(android.app.Activity);
+  }
+
+  public final class AppOpsManagerCompat {
+    method public static int checkOrNoteProxyOp(android.content.Context, int, String, String);
+    method public static int noteOp(android.content.Context, String, int, String);
+    method public static int noteOpNoThrow(android.content.Context, String, int, String);
+    method public static int noteProxyOp(android.content.Context, String, String);
+    method public static int noteProxyOpNoThrow(android.content.Context, String, String);
+    method public static String? permissionToOp(String);
+    field public static final int MODE_ALLOWED = 0; // 0x0
+    field public static final int MODE_DEFAULT = 3; // 0x3
+    field public static final int MODE_ERRORED = 2; // 0x2
+    field public static final int MODE_IGNORED = 1; // 0x1
+  }
+
+  @Deprecated public final class BundleCompat {
+    method @Deprecated public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method @Deprecated public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  }
+
+  public class DialogCompat {
+    method public static android.view.View requireViewById(android.app.Dialog, int);
+  }
+
+  public class FrameMetricsAggregator {
+    ctor public FrameMetricsAggregator();
+    ctor public FrameMetricsAggregator(int);
+    method public void add(android.app.Activity);
+    method public android.util.SparseIntArray![]? getMetrics();
+    method public android.util.SparseIntArray![]? remove(android.app.Activity);
+    method public android.util.SparseIntArray![]? reset();
+    method public android.util.SparseIntArray![]? stop();
+    field public static final int ANIMATION_DURATION = 256; // 0x100
+    field public static final int ANIMATION_INDEX = 8; // 0x8
+    field public static final int COMMAND_DURATION = 32; // 0x20
+    field public static final int COMMAND_INDEX = 5; // 0x5
+    field public static final int DELAY_DURATION = 128; // 0x80
+    field public static final int DELAY_INDEX = 7; // 0x7
+    field public static final int DRAW_DURATION = 8; // 0x8
+    field public static final int DRAW_INDEX = 3; // 0x3
+    field public static final int EVERY_DURATION = 511; // 0x1ff
+    field public static final int INPUT_DURATION = 2; // 0x2
+    field public static final int INPUT_INDEX = 1; // 0x1
+    field public static final int LAYOUT_MEASURE_DURATION = 4; // 0x4
+    field public static final int LAYOUT_MEASURE_INDEX = 2; // 0x2
+    field public static final int SWAP_DURATION = 64; // 0x40
+    field public static final int SWAP_INDEX = 6; // 0x6
+    field public static final int SYNC_DURATION = 16; // 0x10
+    field public static final int SYNC_INDEX = 4; // 0x4
+    field public static final int TOTAL_DURATION = 1; // 0x1
+    field public static final int TOTAL_INDEX = 0; // 0x0
+  }
+
+  @Deprecated public abstract class JobIntentService extends android.app.Service {
+    ctor @Deprecated public JobIntentService();
+    method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
+    method @Deprecated public static void enqueueWork(android.content.Context, Class<?>, int, android.content.Intent);
+    method @Deprecated public boolean isStopped();
+    method @Deprecated public android.os.IBinder! onBind(android.content.Intent);
+    method @Deprecated protected abstract void onHandleWork(android.content.Intent);
+    method @Deprecated public boolean onStopCurrentWork();
+    method @Deprecated public void setInterruptIfStopped(boolean);
+  }
+
+  public final class LocaleManagerCompat {
+    method @AnyThread public static androidx.core.os.LocaleListCompat getApplicationLocales(android.content.Context);
+    method @AnyThread public static androidx.core.os.LocaleListCompat getSystemLocales(android.content.Context);
+  }
+
+  public final class MultiWindowModeChangedInfo {
+    ctor public MultiWindowModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public MultiWindowModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInMultiWindowMode();
+  }
+
+  public final class NavUtils {
+    method public static android.content.Intent? getParentActivityIntent(android.app.Activity);
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static android.content.Intent? getParentActivityIntent(android.content.Context, Class<?>) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static String? getParentActivityName(android.app.Activity);
+    method public static String? getParentActivityName(android.content.Context, android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void navigateUpFromSameTask(android.app.Activity);
+    method public static void navigateUpTo(android.app.Activity, android.content.Intent);
+    method public static boolean shouldUpRecreateTask(android.app.Activity, android.content.Intent);
+    field public static final String PARENT_ACTIVITY = "android.support.PARENT_ACTIVITY";
+  }
+
+  public class NotificationChannelCompat {
+    method public boolean canBubble();
+    method public boolean canBypassDnd();
+    method public boolean canShowBadge();
+    method public android.media.AudioAttributes? getAudioAttributes();
+    method public String? getConversationId();
+    method public String? getDescription();
+    method public String? getGroup();
+    method public String getId();
+    method public int getImportance();
+    method public int getLightColor();
+    method public int getLockscreenVisibility();
+    method public CharSequence? getName();
+    method public String? getParentChannelId();
+    method public android.net.Uri? getSound();
+    method public long[]? getVibrationPattern();
+    method public boolean isImportantConversation();
+    method public boolean shouldShowLights();
+    method public boolean shouldVibrate();
+    method public androidx.core.app.NotificationChannelCompat.Builder toBuilder();
+    field public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
+  }
+
+  public static class NotificationChannelCompat.Builder {
+    ctor public NotificationChannelCompat.Builder(String, int);
+    method public androidx.core.app.NotificationChannelCompat build();
+    method public androidx.core.app.NotificationChannelCompat.Builder setConversationId(String, String);
+    method public androidx.core.app.NotificationChannelCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setImportance(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightColor(int);
+    method public androidx.core.app.NotificationChannelCompat.Builder setLightsEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setName(CharSequence?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setShowBadge(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setSound(android.net.Uri?, android.media.AudioAttributes?);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationEnabled(boolean);
+    method public androidx.core.app.NotificationChannelCompat.Builder setVibrationPattern(long[]?);
+  }
+
+  public class NotificationChannelGroupCompat {
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getChannels();
+    method public String? getDescription();
+    method public String getId();
+    method public CharSequence? getName();
+    method public boolean isBlocked();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder toBuilder();
+  }
+
+  public static class NotificationChannelGroupCompat.Builder {
+    ctor public NotificationChannelGroupCompat.Builder(String);
+    method public androidx.core.app.NotificationChannelGroupCompat build();
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setDescription(String?);
+    method public androidx.core.app.NotificationChannelGroupCompat.Builder setName(CharSequence?);
+  }
+
+  public class NotificationCompat {
+    ctor @Deprecated public NotificationCompat();
+    method public static androidx.core.app.NotificationCompat.Action? getAction(android.app.Notification, int);
+    method public static int getActionCount(android.app.Notification);
+    method public static boolean getAllowSystemGeneratedContextualActions(android.app.Notification);
+    method public static boolean getAutoCancel(android.app.Notification);
+    method public static int getBadgeIconType(android.app.Notification);
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? getBubbleMetadata(android.app.Notification);
+    method public static String? getCategory(android.app.Notification);
+    method public static String? getChannelId(android.app.Notification);
+    method public static int getColor(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentInfo(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentText(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getContentTitle(android.app.Notification);
+    method public static android.os.Bundle? getExtras(android.app.Notification);
+    method public static String? getGroup(android.app.Notification);
+    method public static int getGroupAlertBehavior(android.app.Notification);
+    method @RequiresApi(21) public static java.util.List<androidx.core.app.NotificationCompat.Action!> getInvisibleActions(android.app.Notification);
+    method public static boolean getLocalOnly(android.app.Notification);
+    method public static androidx.core.content.LocusIdCompat? getLocusId(android.app.Notification);
+    method public static boolean getOngoing(android.app.Notification);
+    method public static boolean getOnlyAlertOnce(android.app.Notification);
+    method public static java.util.List<androidx.core.app.Person!> getPeople(android.app.Notification);
+    method public static android.app.Notification? getPublicVersion(android.app.Notification);
+    method public static CharSequence? getSettingsText(android.app.Notification);
+    method public static String? getShortcutId(android.app.Notification);
+    method @RequiresApi(19) public static boolean getShowWhen(android.app.Notification);
+    method public static String? getSortKey(android.app.Notification);
+    method @RequiresApi(19) public static CharSequence? getSubText(android.app.Notification);
+    method public static long getTimeoutAfter(android.app.Notification);
+    method @RequiresApi(19) public static boolean getUsesChronometer(android.app.Notification);
+    method public static int getVisibility(android.app.Notification);
+    method public static boolean isGroupSummary(android.app.Notification);
+    method public static android.graphics.Bitmap? reduceLargeIconSize(android.content.Context, android.graphics.Bitmap?);
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
+    field public static final String CATEGORY_ALARM = "alarm";
+    field public static final String CATEGORY_CALL = "call";
+    field public static final String CATEGORY_EMAIL = "email";
+    field public static final String CATEGORY_ERROR = "err";
+    field public static final String CATEGORY_EVENT = "event";
+    field public static final String CATEGORY_LOCATION_SHARING = "location_sharing";
+    field public static final String CATEGORY_MESSAGE = "msg";
+    field public static final String CATEGORY_MISSED_CALL = "missed_call";
+    field public static final String CATEGORY_NAVIGATION = "navigation";
+    field public static final String CATEGORY_PROGRESS = "progress";
+    field public static final String CATEGORY_PROMO = "promo";
+    field public static final String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final String CATEGORY_REMINDER = "reminder";
+    field public static final String CATEGORY_SERVICE = "service";
+    field public static final String CATEGORY_SOCIAL = "social";
+    field public static final String CATEGORY_STATUS = "status";
+    field public static final String CATEGORY_STOPWATCH = "stopwatch";
+    field public static final String CATEGORY_SYSTEM = "sys";
+    field public static final String CATEGORY_TRANSPORT = "transport";
+    field public static final String CATEGORY_WORKOUT = "workout";
+    field @ColorInt public static final int COLOR_DEFAULT = 0; // 0x0
+    field public static final int DEFAULT_ALL = -1; // 0xffffffff
+    field public static final int DEFAULT_LIGHTS = 4; // 0x4
+    field public static final int DEFAULT_SOUND = 1; // 0x1
+    field public static final int DEFAULT_VIBRATE = 2; // 0x2
+    field public static final String EXTRA_ANSWER_COLOR = "android.answerColor";
+    field public static final String EXTRA_ANSWER_INTENT = "android.answerIntent";
+    field public static final String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
+    field public static final String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
+    field public static final String EXTRA_BIG_TEXT = "android.bigText";
+    field public static final String EXTRA_CALL_IS_VIDEO = "android.callIsVideo";
+    field public static final String EXTRA_CALL_PERSON = "android.callPerson";
+    field public static final String EXTRA_CALL_PERSON_COMPAT = "android.callPersonCompat";
+    field public static final String EXTRA_CALL_TYPE = "android.callType";
+    field public static final String EXTRA_CHANNEL_GROUP_ID = "android.intent.extra.CHANNEL_GROUP_ID";
+    field public static final String EXTRA_CHANNEL_ID = "android.intent.extra.CHANNEL_ID";
+    field public static final String EXTRA_CHRONOMETER_COUNT_DOWN = "android.chronometerCountDown";
+    field public static final String EXTRA_COLORIZED = "android.colorized";
+    field public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions";
+    field public static final String EXTRA_COMPAT_TEMPLATE = "androidx.core.app.extra.COMPAT_TEMPLATE";
+    field public static final String EXTRA_CONVERSATION_TITLE = "android.conversationTitle";
+    field public static final String EXTRA_DECLINE_COLOR = "android.declineColor";
+    field public static final String EXTRA_DECLINE_INTENT = "android.declineIntent";
+    field public static final String EXTRA_HANG_UP_INTENT = "android.hangUpIntent";
+    field public static final String EXTRA_HIDDEN_CONVERSATION_TITLE = "android.hiddenConversationTitle";
+    field public static final String EXTRA_HISTORIC_MESSAGES = "android.messages.historic";
+    field public static final String EXTRA_INFO_TEXT = "android.infoText";
+    field public static final String EXTRA_IS_GROUP_CONVERSATION = "android.isGroupConversation";
+    field public static final String EXTRA_LARGE_ICON = "android.largeIcon";
+    field public static final String EXTRA_LARGE_ICON_BIG = "android.largeIcon.big";
+    field public static final String EXTRA_MEDIA_SESSION = "android.mediaSession";
+    field public static final String EXTRA_MESSAGES = "android.messages";
+    field public static final String EXTRA_MESSAGING_STYLE_USER = "android.messagingStyleUser";
+    field public static final String EXTRA_NOTIFICATION_ID = "android.intent.extra.NOTIFICATION_ID";
+    field public static final String EXTRA_NOTIFICATION_TAG = "android.intent.extra.NOTIFICATION_TAG";
+    field @Deprecated public static final String EXTRA_PEOPLE = "android.people";
+    field public static final String EXTRA_PEOPLE_LIST = "android.people.list";
+    field public static final String EXTRA_PICTURE = "android.picture";
+    field public static final String EXTRA_PICTURE_CONTENT_DESCRIPTION = "android.pictureContentDescription";
+    field public static final String EXTRA_PICTURE_ICON = "android.pictureIcon";
+    field public static final String EXTRA_PROGRESS = "android.progress";
+    field public static final String EXTRA_PROGRESS_INDETERMINATE = "android.progressIndeterminate";
+    field public static final String EXTRA_PROGRESS_MAX = "android.progressMax";
+    field public static final String EXTRA_REMOTE_INPUT_HISTORY = "android.remoteInputHistory";
+    field public static final String EXTRA_SELF_DISPLAY_NAME = "android.selfDisplayName";
+    field public static final String EXTRA_SHOW_BIG_PICTURE_WHEN_COLLAPSED = "android.showBigPictureWhenCollapsed";
+    field public static final String EXTRA_SHOW_CHRONOMETER = "android.showChronometer";
+    field public static final String EXTRA_SHOW_WHEN = "android.showWhen";
+    field public static final String EXTRA_SMALL_ICON = "android.icon";
+    field public static final String EXTRA_SUB_TEXT = "android.subText";
+    field public static final String EXTRA_SUMMARY_TEXT = "android.summaryText";
+    field public static final String EXTRA_TEMPLATE = "android.template";
+    field public static final String EXTRA_TEXT = "android.text";
+    field public static final String EXTRA_TEXT_LINES = "android.textLines";
+    field public static final String EXTRA_TITLE = "android.title";
+    field public static final String EXTRA_TITLE_BIG = "android.title.big";
+    field public static final String EXTRA_VERIFICATION_ICON = "android.verificationIcon";
+    field public static final String EXTRA_VERIFICATION_ICON_COMPAT = "android.verificationIconCompat";
+    field public static final String EXTRA_VERIFICATION_TEXT = "android.verificationText";
+    field public static final int FLAG_AUTO_CANCEL = 16; // 0x10
+    field public static final int FLAG_BUBBLE = 4096; // 0x1000
+    field public static final int FLAG_FOREGROUND_SERVICE = 64; // 0x40
+    field public static final int FLAG_GROUP_SUMMARY = 512; // 0x200
+    field @Deprecated public static final int FLAG_HIGH_PRIORITY = 128; // 0x80
+    field public static final int FLAG_INSISTENT = 4; // 0x4
+    field public static final int FLAG_LOCAL_ONLY = 256; // 0x100
+    field public static final int FLAG_NO_CLEAR = 32; // 0x20
+    field public static final int FLAG_ONGOING_EVENT = 2; // 0x2
+    field public static final int FLAG_ONLY_ALERT_ONCE = 8; // 0x8
+    field public static final int FLAG_SHOW_LIGHTS = 1; // 0x1
+    field public static final int FOREGROUND_SERVICE_DEFAULT = 0; // 0x0
+    field public static final int FOREGROUND_SERVICE_DEFERRED = 2; // 0x2
+    field public static final int FOREGROUND_SERVICE_IMMEDIATE = 1; // 0x1
+    field public static final int GROUP_ALERT_ALL = 0; // 0x0
+    field public static final int GROUP_ALERT_CHILDREN = 2; // 0x2
+    field public static final int GROUP_ALERT_SUMMARY = 1; // 0x1
+    field public static final String GROUP_KEY_SILENT = "silent";
+    field public static final String INTENT_CATEGORY_NOTIFICATION_PREFERENCES = "android.intent.category.NOTIFICATION_PREFERENCES";
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = -1; // 0xffffffff
+    field public static final int PRIORITY_MAX = 2; // 0x2
+    field public static final int PRIORITY_MIN = -2; // 0xfffffffe
+    field public static final int STREAM_DEFAULT = -1; // 0xffffffff
+    field public static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
+  }
+
+  public static class NotificationCompat.Action {
+    ctor public NotificationCompat.Action(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action(int, CharSequence?, android.app.PendingIntent?);
+    method public android.app.PendingIntent? getActionIntent();
+    method public boolean getAllowGeneratedReplies();
+    method public androidx.core.app.RemoteInput![]? getDataOnlyRemoteInputs();
+    method public android.os.Bundle getExtras();
+    method @Deprecated public int getIcon();
+    method public androidx.core.graphics.drawable.IconCompat? getIconCompat();
+    method public androidx.core.app.RemoteInput![]? getRemoteInputs();
+    method @androidx.core.app.NotificationCompat.Action.SemanticAction public int getSemanticAction();
+    method public boolean getShowsUserInterface();
+    method public CharSequence? getTitle();
+    method public boolean isAuthenticationRequired();
+    method public boolean isContextual();
+    field public static final int SEMANTIC_ACTION_ARCHIVE = 5; // 0x5
+    field public static final int SEMANTIC_ACTION_CALL = 10; // 0xa
+    field public static final int SEMANTIC_ACTION_DELETE = 4; // 0x4
+    field public static final int SEMANTIC_ACTION_MARK_AS_READ = 2; // 0x2
+    field public static final int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; // 0x3
+    field public static final int SEMANTIC_ACTION_MUTE = 6; // 0x6
+    field public static final int SEMANTIC_ACTION_NONE = 0; // 0x0
+    field public static final int SEMANTIC_ACTION_REPLY = 1; // 0x1
+    field public static final int SEMANTIC_ACTION_THUMBS_DOWN = 9; // 0x9
+    field public static final int SEMANTIC_ACTION_THUMBS_UP = 8; // 0x8
+    field public static final int SEMANTIC_ACTION_UNMUTE = 7; // 0x7
+    field public android.app.PendingIntent? actionIntent;
+    field @Deprecated public int icon;
+    field public CharSequence! title;
+  }
+
+  public static final class NotificationCompat.Action.Builder {
+    ctor public NotificationCompat.Action.Builder(androidx.core.app.NotificationCompat.Action);
+    ctor public NotificationCompat.Action.Builder(androidx.core.graphics.drawable.IconCompat?, CharSequence?, android.app.PendingIntent?);
+    ctor public NotificationCompat.Action.Builder(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Action.Builder addExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Action.Builder addRemoteInput(androidx.core.app.RemoteInput?);
+    method public androidx.core.app.NotificationCompat.Action build();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Extender);
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.NotificationCompat.Action.Builder setAllowGeneratedReplies(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setAuthenticationRequired(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setContextual(boolean);
+    method public androidx.core.app.NotificationCompat.Action.Builder setSemanticAction(@androidx.core.app.NotificationCompat.Action.SemanticAction int);
+    method public androidx.core.app.NotificationCompat.Action.Builder setShowsUserInterface(boolean);
+  }
+
+  public static interface NotificationCompat.Action.Extender {
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+  }
+
+  @IntDef({androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_NONE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_REPLY, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_UNREAD, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_DELETE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_ARCHIVE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_MUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_UNMUTE, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_UP, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_THUMBS_DOWN, androidx.core.app.NotificationCompat.Action.SEMANTIC_ACTION_CALL}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NotificationCompat.Action.SemanticAction {
+  }
+
+  public static final class NotificationCompat.Action.WearableExtender implements androidx.core.app.NotificationCompat.Action.Extender {
+    ctor public NotificationCompat.Action.WearableExtender();
+    ctor public NotificationCompat.Action.WearableExtender(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Action.Builder extend(androidx.core.app.NotificationCompat.Action.Builder);
+    method @Deprecated public CharSequence? getCancelLabel();
+    method @Deprecated public CharSequence? getConfirmLabel();
+    method public boolean getHintDisplayActionInline();
+    method public boolean getHintLaunchesActivity();
+    method @Deprecated public CharSequence? getInProgressLabel();
+    method public boolean isAvailableOffline();
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setCancelLabel(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setConfirmLabel(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintDisplayActionInline(boolean);
+    method public androidx.core.app.NotificationCompat.Action.WearableExtender setHintLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.Action.WearableExtender setInProgressLabel(CharSequence?);
+  }
+
+  public static class NotificationCompat.BigPictureStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigPictureStyle();
+    ctor public NotificationCompat.BigPictureStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.Bitmap?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle bigPicture(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setBigContentTitle(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle setContentDescription(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigPictureStyle setSummaryText(CharSequence?);
+    method @RequiresApi(31) public androidx.core.app.NotificationCompat.BigPictureStyle showBigPictureWhenCollapsed(boolean);
+  }
+
+  public static class NotificationCompat.BigTextStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.BigTextStyle();
+    ctor public NotificationCompat.BigTextStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle bigText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.BigTextStyle setSummaryText(CharSequence?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata {
+    method public static androidx.core.app.NotificationCompat.BubbleMetadata? fromPlatform(android.app.Notification.BubbleMetadata?);
+    method public boolean getAutoExpandBubble();
+    method public android.app.PendingIntent? getDeleteIntent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getDesiredHeight();
+    method @DimenRes public int getDesiredHeightResId();
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public android.app.PendingIntent? getIntent();
+    method public String? getShortcutId();
+    method public boolean isNotificationSuppressed();
+    method public static android.app.Notification.BubbleMetadata? toPlatform(androidx.core.app.NotificationCompat.BubbleMetadata?);
+  }
+
+  public static final class NotificationCompat.BubbleMetadata.Builder {
+    ctor @Deprecated public NotificationCompat.BubbleMetadata.Builder();
+    ctor public NotificationCompat.BubbleMetadata.Builder(android.app.PendingIntent, androidx.core.graphics.drawable.IconCompat);
+    ctor @RequiresApi(30) public NotificationCompat.BubbleMetadata.Builder(String);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata build();
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setAutoExpandBubble(boolean);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeight(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setIntent(android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.BubbleMetadata.Builder setSuppressNotification(boolean);
+  }
+
+  public static class NotificationCompat.Builder {
+    ctor @Deprecated public NotificationCompat.Builder(android.content.Context);
+    ctor @RequiresApi(19) public NotificationCompat.Builder(android.content.Context, android.app.Notification);
+    ctor public NotificationCompat.Builder(android.content.Context, String);
+    method public androidx.core.app.NotificationCompat.Builder addAction(androidx.core.app.NotificationCompat.Action?);
+    method public androidx.core.app.NotificationCompat.Builder addAction(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder addExtras(android.os.Bundle?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(androidx.core.app.NotificationCompat.Action?);
+    method @RequiresApi(21) public androidx.core.app.NotificationCompat.Builder addInvisibleAction(int, CharSequence?, android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder addPerson(androidx.core.app.Person?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder addPerson(String?);
+    method public android.app.Notification build();
+    method public androidx.core.app.NotificationCompat.Builder clearActions();
+    method public androidx.core.app.NotificationCompat.Builder clearInvisibleActions();
+    method public androidx.core.app.NotificationCompat.Builder clearPeople();
+    method public android.widget.RemoteViews? createBigContentView();
+    method public android.widget.RemoteViews? createContentView();
+    method public android.widget.RemoteViews? createHeadsUpContentView();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Extender);
+    method public android.os.Bundle getExtras();
+    method @Deprecated public android.app.Notification getNotification();
+    method protected static CharSequence? limitCharSequenceLength(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setAllowSystemGeneratedContextualActions(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setAutoCancel(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setBadgeIconType(int);
+    method public androidx.core.app.NotificationCompat.Builder setBubbleMetadata(androidx.core.app.NotificationCompat.BubbleMetadata?);
+    method public androidx.core.app.NotificationCompat.Builder setCategory(String?);
+    method public androidx.core.app.NotificationCompat.Builder setChannelId(String);
+    method @RequiresApi(24) public androidx.core.app.NotificationCompat.Builder setChronometerCountDown(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.Builder setColorized(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setContent(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setContentInfo(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setContentText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomBigContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setCustomHeadsUpContentView(android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setDefaults(int);
+    method public androidx.core.app.NotificationCompat.Builder setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.app.NotificationCompat.Builder setForegroundServiceBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setFullScreenIntent(android.app.PendingIntent?, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setGroup(String?);
+    method public androidx.core.app.NotificationCompat.Builder setGroupAlertBehavior(int);
+    method public androidx.core.app.NotificationCompat.Builder setGroupSummary(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setLargeIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.Builder setLights(@ColorInt int, int, int);
+    method public androidx.core.app.NotificationCompat.Builder setLocalOnly(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setNotificationSilent();
+    method public androidx.core.app.NotificationCompat.Builder setNumber(int);
+    method public androidx.core.app.NotificationCompat.Builder setOngoing(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setOnlyAlertOnce(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPriority(int);
+    method public androidx.core.app.NotificationCompat.Builder setProgress(int, int, boolean);
+    method public androidx.core.app.NotificationCompat.Builder setPublicVersion(android.app.Notification?);
+    method public androidx.core.app.NotificationCompat.Builder setRemoteInputHistory(CharSequence![]?);
+    method public androidx.core.app.NotificationCompat.Builder setSettingsText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutId(String?);
+    method public androidx.core.app.NotificationCompat.Builder setShortcutInfo(androidx.core.content.pm.ShortcutInfoCompat?);
+    method public androidx.core.app.NotificationCompat.Builder setShowWhen(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setSilent(boolean);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.Builder setSmallIcon(androidx.core.graphics.drawable.IconCompat);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int);
+    method public androidx.core.app.NotificationCompat.Builder setSmallIcon(int, int);
+    method public androidx.core.app.NotificationCompat.Builder setSortKey(String?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?);
+    method public androidx.core.app.NotificationCompat.Builder setSound(android.net.Uri?, int);
+    method public androidx.core.app.NotificationCompat.Builder setStyle(androidx.core.app.NotificationCompat.Style?);
+    method public androidx.core.app.NotificationCompat.Builder setSubText(CharSequence?);
+    method public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?);
+    method @Deprecated public androidx.core.app.NotificationCompat.Builder setTicker(CharSequence?, android.widget.RemoteViews?);
+    method public androidx.core.app.NotificationCompat.Builder setTimeoutAfter(long);
+    method public androidx.core.app.NotificationCompat.Builder setUsesChronometer(boolean);
+    method public androidx.core.app.NotificationCompat.Builder setVibrate(long[]?);
+    method public androidx.core.app.NotificationCompat.Builder setVisibility(int);
+    method public androidx.core.app.NotificationCompat.Builder setWhen(long);
+    field @Deprecated public java.util.ArrayList<java.lang.String!>! mPeople;
+  }
+
+  public static class NotificationCompat.CallStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.CallStyle();
+    ctor public NotificationCompat.CallStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public static androidx.core.app.NotificationCompat.CallStyle forIncomingCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forOngoingCall(androidx.core.app.Person, android.app.PendingIntent);
+    method public static androidx.core.app.NotificationCompat.CallStyle forScreeningCall(androidx.core.app.Person, android.app.PendingIntent, android.app.PendingIntent);
+    method public androidx.core.app.NotificationCompat.CallStyle setAnswerButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setDeclineButtonColorHint(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CallStyle setIsVideo(boolean);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.Bitmap?);
+    method @RequiresApi(23) public androidx.core.app.NotificationCompat.CallStyle setVerificationIcon(android.graphics.drawable.Icon?);
+    method public androidx.core.app.NotificationCompat.CallStyle setVerificationText(CharSequence?);
+    field public static final int CALL_TYPE_INCOMING = 1; // 0x1
+    field public static final int CALL_TYPE_ONGOING = 2; // 0x2
+    field public static final int CALL_TYPE_SCREENING = 3; // 0x3
+    field public static final int CALL_TYPE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class NotificationCompat.CarExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.CarExtender();
+    ctor public NotificationCompat.CarExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method @ColorInt public int getColor();
+    method public android.graphics.Bitmap? getLargeIcon();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation? getUnreadConversation();
+    method public androidx.core.app.NotificationCompat.CarExtender setColor(@ColorInt int);
+    method public androidx.core.app.NotificationCompat.CarExtender setLargeIcon(android.graphics.Bitmap?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender setUnreadConversation(androidx.core.app.NotificationCompat.CarExtender.UnreadConversation?);
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation {
+    method @Deprecated public long getLatestTimestamp();
+    method @Deprecated public String![]? getMessages();
+    method @Deprecated public String? getParticipant();
+    method @Deprecated public String![]? getParticipants();
+    method @Deprecated public android.app.PendingIntent? getReadPendingIntent();
+    method @Deprecated public androidx.core.app.RemoteInput? getRemoteInput();
+    method @Deprecated public android.app.PendingIntent? getReplyPendingIntent();
+  }
+
+  @Deprecated public static class NotificationCompat.CarExtender.UnreadConversation.Builder {
+    ctor @Deprecated public NotificationCompat.CarExtender.UnreadConversation.Builder(String);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder addMessage(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation build();
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setLatestTimestamp(long);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReadPendingIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.CarExtender.UnreadConversation.Builder setReplyAction(android.app.PendingIntent?, androidx.core.app.RemoteInput?);
+  }
+
+  public static class NotificationCompat.DecoratedCustomViewStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.DecoratedCustomViewStyle();
+  }
+
+  public static interface NotificationCompat.Extender {
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+  }
+
+  public static class NotificationCompat.InboxStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.InboxStyle();
+    ctor public NotificationCompat.InboxStyle(androidx.core.app.NotificationCompat.Builder?);
+    method public androidx.core.app.NotificationCompat.InboxStyle addLine(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setBigContentTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.InboxStyle setSummaryText(CharSequence?);
+  }
+
+  public static class NotificationCompat.MessagingStyle extends androidx.core.app.NotificationCompat.Style {
+    ctor public NotificationCompat.MessagingStyle(androidx.core.app.Person);
+    ctor @Deprecated public NotificationCompat.MessagingStyle(CharSequence);
+    method public void addCompatExtras(android.os.Bundle);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addHistoricMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(androidx.core.app.NotificationCompat.MessagingStyle.Message?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, androidx.core.app.Person?);
+    method @Deprecated public androidx.core.app.NotificationCompat.MessagingStyle addMessage(CharSequence?, long, CharSequence?);
+    method public static androidx.core.app.NotificationCompat.MessagingStyle? extractMessagingStyleFromNotification(android.app.Notification);
+    method public CharSequence? getConversationTitle();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getHistoricMessages();
+    method public java.util.List<androidx.core.app.NotificationCompat.MessagingStyle.Message!> getMessages();
+    method public androidx.core.app.Person getUser();
+    method @Deprecated public CharSequence? getUserDisplayName();
+    method public boolean isGroupConversation();
+    method public androidx.core.app.NotificationCompat.MessagingStyle setConversationTitle(CharSequence?);
+    method public androidx.core.app.NotificationCompat.MessagingStyle setGroupConversation(boolean);
+    field public static final int MAXIMUM_RETAINED_MESSAGES = 25; // 0x19
+  }
+
+  public static final class NotificationCompat.MessagingStyle.Message {
+    ctor public NotificationCompat.MessagingStyle.Message(CharSequence?, long, androidx.core.app.Person?);
+    ctor @Deprecated public NotificationCompat.MessagingStyle.Message(CharSequence?, long, CharSequence?);
+    method public String? getDataMimeType();
+    method public android.net.Uri? getDataUri();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.Person? getPerson();
+    method @Deprecated public CharSequence? getSender();
+    method public CharSequence? getText();
+    method public long getTimestamp();
+    method public androidx.core.app.NotificationCompat.MessagingStyle.Message setData(String?, android.net.Uri?);
+  }
+
+  public abstract static class NotificationCompat.Style {
+    ctor public NotificationCompat.Style();
+    method public android.app.Notification? build();
+    method public void setBuilder(androidx.core.app.NotificationCompat.Builder?);
+  }
+
+  public static final class NotificationCompat.TvExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.TvExtender();
+    ctor public NotificationCompat.TvExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method public String? getChannelId();
+    method public android.app.PendingIntent? getContentIntent();
+    method public android.app.PendingIntent? getDeleteIntent();
+    method public boolean isAvailableOnTv();
+    method public boolean isSuppressShowOverApps();
+    method public androidx.core.app.NotificationCompat.TvExtender setChannelId(String?);
+    method public androidx.core.app.NotificationCompat.TvExtender setContentIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.TvExtender setDeleteIntent(android.app.PendingIntent?);
+    method public androidx.core.app.NotificationCompat.TvExtender setSuppressShowOverApps(boolean);
+  }
+
+  public static final class NotificationCompat.WearableExtender implements androidx.core.app.NotificationCompat.Extender {
+    ctor public NotificationCompat.WearableExtender();
+    ctor public NotificationCompat.WearableExtender(android.app.Notification);
+    method public androidx.core.app.NotificationCompat.WearableExtender addAction(androidx.core.app.NotificationCompat.Action);
+    method public androidx.core.app.NotificationCompat.WearableExtender addActions(java.util.List<androidx.core.app.NotificationCompat.Action!>);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPage(android.app.Notification);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender addPages(java.util.List<android.app.Notification!>);
+    method public androidx.core.app.NotificationCompat.WearableExtender clearActions();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender clearPages();
+    method public androidx.core.app.NotificationCompat.WearableExtender clone();
+    method public androidx.core.app.NotificationCompat.Builder extend(androidx.core.app.NotificationCompat.Builder);
+    method public java.util.List<androidx.core.app.NotificationCompat.Action!> getActions();
+    method @Deprecated public android.graphics.Bitmap? getBackground();
+    method public String? getBridgeTag();
+    method public int getContentAction();
+    method @Deprecated public int getContentIcon();
+    method @Deprecated public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method @Deprecated public int getCustomContentHeight();
+    method @Deprecated public int getCustomSizePreset();
+    method public String? getDismissalId();
+    method @Deprecated public android.app.PendingIntent? getDisplayIntent();
+    method @Deprecated public int getGravity();
+    method @Deprecated public boolean getHintAmbientBigPicture();
+    method @Deprecated public boolean getHintAvoidBackgroundClipping();
+    method public boolean getHintContentIntentLaunchesActivity();
+    method @Deprecated public boolean getHintHideIcon();
+    method @Deprecated public int getHintScreenTimeout();
+    method @Deprecated public boolean getHintShowBackgroundOnly();
+    method @Deprecated public java.util.List<android.app.Notification!> getPages();
+    method public boolean getStartScrollBottom();
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setBackground(android.graphics.Bitmap?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setBridgeTag(String?);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentAction(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIcon(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setContentIconGravity(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setContentIntentAvailableOffline(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomContentHeight(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setCustomSizePreset(int);
+    method public androidx.core.app.NotificationCompat.WearableExtender setDismissalId(String?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setDisplayIntent(android.app.PendingIntent?);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setGravity(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAmbientBigPicture(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintAvoidBackgroundClipping(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setHintContentIntentLaunchesActivity(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintHideIcon(boolean);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintScreenTimeout(int);
+    method @Deprecated public androidx.core.app.NotificationCompat.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public androidx.core.app.NotificationCompat.WearableExtender setStartScrollBottom(boolean);
+    field @Deprecated public static final int SCREEN_TIMEOUT_LONG = -1; // 0xffffffff
+    field @Deprecated public static final int SCREEN_TIMEOUT_SHORT = 0; // 0x0
+    field @Deprecated public static final int SIZE_DEFAULT = 0; // 0x0
+    field @Deprecated public static final int SIZE_FULL_SCREEN = 5; // 0x5
+    field @Deprecated public static final int SIZE_LARGE = 4; // 0x4
+    field @Deprecated public static final int SIZE_MEDIUM = 3; // 0x3
+    field @Deprecated public static final int SIZE_SMALL = 2; // 0x2
+    field @Deprecated public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
+  public final class NotificationCompatExtras {
+    field public static final String EXTRA_ACTION_EXTRAS = "android.support.actionExtras";
+    field public static final String EXTRA_GROUP_KEY = "android.support.groupKey";
+    field public static final String EXTRA_GROUP_SUMMARY = "android.support.isGroupSummary";
+    field public static final String EXTRA_LOCAL_ONLY = "android.support.localOnly";
+    field public static final String EXTRA_REMOTE_INPUTS = "android.support.remoteInputs";
+    field public static final String EXTRA_SORT_KEY = "android.support.sortKey";
+  }
+
+  public abstract class NotificationCompatSideChannelService extends android.app.Service {
+    ctor public NotificationCompatSideChannelService();
+    method public abstract void cancel(String!, int, String!);
+    method public abstract void cancelAll(String!);
+    method public abstract void notify(String!, int, String!, android.app.Notification!);
+    method public android.os.IBinder! onBind(android.content.Intent!);
+  }
+
+  public final class NotificationManagerCompat {
+    method public boolean areNotificationsEnabled();
+    method public void cancel(int);
+    method public void cancel(String?, int);
+    method public void cancelAll();
+    method public void createNotificationChannel(android.app.NotificationChannel);
+    method public void createNotificationChannel(androidx.core.app.NotificationChannelCompat);
+    method public void createNotificationChannelGroup(android.app.NotificationChannelGroup);
+    method public void createNotificationChannelGroup(androidx.core.app.NotificationChannelGroupCompat);
+    method public void createNotificationChannelGroups(java.util.List<android.app.NotificationChannelGroup!>);
+    method public void createNotificationChannelGroupsCompat(java.util.List<androidx.core.app.NotificationChannelGroupCompat!>);
+    method public void createNotificationChannels(java.util.List<android.app.NotificationChannel!>);
+    method public void createNotificationChannelsCompat(java.util.List<androidx.core.app.NotificationChannelCompat!>);
+    method public void deleteNotificationChannel(String);
+    method public void deleteNotificationChannelGroup(String);
+    method public void deleteUnlistedNotificationChannels(java.util.Collection<java.lang.String!>);
+    method public static androidx.core.app.NotificationManagerCompat from(android.content.Context);
+    method public java.util.List<android.service.notification.StatusBarNotification!> getActiveNotifications();
+    method public int getCurrentInterruptionFilter();
+    method public static java.util.Set<java.lang.String!> getEnabledListenerPackages(android.content.Context);
+    method public int getImportance();
+    method public android.app.NotificationChannel? getNotificationChannel(String);
+    method public android.app.NotificationChannel? getNotificationChannel(String, String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String);
+    method public androidx.core.app.NotificationChannelCompat? getNotificationChannelCompat(String, String);
+    method public android.app.NotificationChannelGroup? getNotificationChannelGroup(String);
+    method public androidx.core.app.NotificationChannelGroupCompat? getNotificationChannelGroupCompat(String);
+    method public java.util.List<android.app.NotificationChannelGroup!> getNotificationChannelGroups();
+    method public java.util.List<androidx.core.app.NotificationChannelGroupCompat!> getNotificationChannelGroupsCompat();
+    method public java.util.List<android.app.NotificationChannel!> getNotificationChannels();
+    method public java.util.List<androidx.core.app.NotificationChannelCompat!> getNotificationChannelsCompat();
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(int, android.app.Notification);
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(String?, int, android.app.Notification);
+    method @RequiresPermission(android.Manifest.permission.POST_NOTIFICATIONS) public void notify(java.util.List<androidx.core.app.NotificationManagerCompat.NotificationWithIdAndTag!>);
+    field public static final String ACTION_BIND_SIDE_CHANNEL = "android.support.BIND_NOTIFICATION_SIDE_CHANNEL";
+    field public static final String EXTRA_USE_SIDE_CHANNEL = "android.support.useSideChannel";
+    field public static final int IMPORTANCE_DEFAULT = 3; // 0x3
+    field public static final int IMPORTANCE_HIGH = 4; // 0x4
+    field public static final int IMPORTANCE_LOW = 2; // 0x2
+    field public static final int IMPORTANCE_MAX = 5; // 0x5
+    field public static final int IMPORTANCE_MIN = 1; // 0x1
+    field public static final int IMPORTANCE_NONE = 0; // 0x0
+    field public static final int IMPORTANCE_UNSPECIFIED = -1000; // 0xfffffc18
+    field public static final int INTERRUPTION_FILTER_ALARMS = 4; // 0x4
+    field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
+    field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
+    field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+    field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
+  }
+
+  public static class NotificationManagerCompat.NotificationWithIdAndTag {
+    ctor public NotificationManagerCompat.NotificationWithIdAndTag(int, android.app.Notification);
+    ctor public NotificationManagerCompat.NotificationWithIdAndTag(String?, int, android.app.Notification);
+  }
+
+  public interface OnMultiWindowModeChangedProvider {
+    method public void addOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+    method public void removeOnMultiWindowModeChangedListener(androidx.core.util.Consumer<androidx.core.app.MultiWindowModeChangedInfo!>);
+  }
+
+  public interface OnNewIntentProvider {
+    method public void addOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+    method public void removeOnNewIntentListener(androidx.core.util.Consumer<android.content.Intent!>);
+  }
+
+  public interface OnPictureInPictureModeChangedProvider {
+    method public void addOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+    method public void removeOnPictureInPictureModeChangedListener(androidx.core.util.Consumer<androidx.core.app.PictureInPictureModeChangedInfo!>);
+  }
+
+  public final class PendingIntentCompat {
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getActivities(android.content.Context, int, android.content.Intent![], int, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, android.os.Bundle, boolean);
+    method public static android.app.PendingIntent getActivity(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent? getBroadcast(android.content.Context, int, android.content.Intent, int, boolean);
+    method @RequiresApi(26) public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int, boolean);
+    method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int, boolean);
+  }
+
+  public class Person {
+    method public static androidx.core.app.Person fromBundle(android.os.Bundle);
+    method public androidx.core.graphics.drawable.IconCompat? getIcon();
+    method public String? getKey();
+    method public CharSequence? getName();
+    method public String? getUri();
+    method public boolean isBot();
+    method public boolean isImportant();
+    method public androidx.core.app.Person.Builder toBuilder();
+    method public android.os.Bundle toBundle();
+  }
+
+  public static class Person.Builder {
+    ctor public Person.Builder();
+    method public androidx.core.app.Person build();
+    method public androidx.core.app.Person.Builder setBot(boolean);
+    method public androidx.core.app.Person.Builder setIcon(androidx.core.graphics.drawable.IconCompat?);
+    method public androidx.core.app.Person.Builder setImportant(boolean);
+    method public androidx.core.app.Person.Builder setKey(String?);
+    method public androidx.core.app.Person.Builder setName(CharSequence?);
+    method public androidx.core.app.Person.Builder setUri(String?);
+  }
+
+  public final class PictureInPictureModeChangedInfo {
+    ctor public PictureInPictureModeChangedInfo(boolean);
+    ctor @RequiresApi(26) public PictureInPictureModeChangedInfo(boolean, android.content.res.Configuration);
+    method @RequiresApi(26) public android.content.res.Configuration getNewConfig();
+    method public boolean isInPictureInPictureMode();
+  }
+
+  public final class RemoteActionCompat implements androidx.versionedparcelable.VersionedParcelable {
+    ctor public RemoteActionCompat(androidx.core.app.RemoteActionCompat);
+    ctor public RemoteActionCompat(androidx.core.graphics.drawable.IconCompat, CharSequence, CharSequence, android.app.PendingIntent);
+    method @RequiresApi(26) public static androidx.core.app.RemoteActionCompat createFromRemoteAction(android.app.RemoteAction);
+    method public android.app.PendingIntent getActionIntent();
+    method public CharSequence getContentDescription();
+    method public androidx.core.graphics.drawable.IconCompat getIcon();
+    method public CharSequence getTitle();
+    method public boolean isEnabled();
+    method public void setEnabled(boolean);
+    method public void setShouldShowIcon(boolean);
+    method public boolean shouldShowIcon();
+    method @RequiresApi(26) public android.app.RemoteAction toRemoteAction();
+  }
+
+  public final class RemoteInput {
+    method public static void addDataResultToIntent(androidx.core.app.RemoteInput, android.content.Intent, java.util.Map<java.lang.String!,android.net.Uri!>);
+    method public static void addResultsToIntent(androidx.core.app.RemoteInput![], android.content.Intent, android.os.Bundle);
+    method public boolean getAllowFreeFormInput();
+    method public java.util.Set<java.lang.String!>? getAllowedDataTypes();
+    method public CharSequence![]? getChoices();
+    method public static java.util.Map<java.lang.String!,android.net.Uri!>? getDataResultsFromIntent(android.content.Intent, String);
+    method public int getEditChoicesBeforeSending();
+    method public android.os.Bundle getExtras();
+    method public CharSequence? getLabel();
+    method public String getResultKey();
+    method public static android.os.Bundle? getResultsFromIntent(android.content.Intent);
+    method public static int getResultsSource(android.content.Intent);
+    method public boolean isDataOnly();
+    method public static void setResultsSource(android.content.Intent, int);
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_AUTO = 0; // 0x0
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_DISABLED = 1; // 0x1
+    field public static final int EDIT_CHOICES_BEFORE_SENDING_ENABLED = 2; // 0x2
+    field public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
+    field public static final String RESULTS_CLIP_LABEL = "android.remoteinput.results";
+    field public static final int SOURCE_CHOICE = 1; // 0x1
+    field public static final int SOURCE_FREE_FORM_INPUT = 0; // 0x0
+  }
+
+  public static final class RemoteInput.Builder {
+    ctor public RemoteInput.Builder(String);
+    method public androidx.core.app.RemoteInput.Builder addExtras(android.os.Bundle);
+    method public androidx.core.app.RemoteInput build();
+    method public android.os.Bundle getExtras();
+    method public androidx.core.app.RemoteInput.Builder setAllowDataType(String, boolean);
+    method public androidx.core.app.RemoteInput.Builder setAllowFreeFormInput(boolean);
+    method public androidx.core.app.RemoteInput.Builder setChoices(CharSequence![]?);
+    method public androidx.core.app.RemoteInput.Builder setEditChoicesBeforeSending(int);
+    method public androidx.core.app.RemoteInput.Builder setLabel(CharSequence?);
+  }
+
+  public final class ServiceCompat {
+    method public static void stopForeground(android.app.Service, int);
+    field public static final int START_STICKY = 1; // 0x1
+    field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
+    field public static final int STOP_FOREGROUND_REMOVE = 1; // 0x1
+  }
+
+  public final class ShareCompat {
+    method @Deprecated public static void configureMenuItem(android.view.Menu, @IdRes int, androidx.core.app.ShareCompat.IntentBuilder);
+    method @Deprecated public static void configureMenuItem(android.view.MenuItem, androidx.core.app.ShareCompat.IntentBuilder);
+    method public static android.content.ComponentName? getCallingActivity(android.app.Activity);
+    method public static String? getCallingPackage(android.app.Activity);
+    field public static final String EXTRA_CALLING_ACTIVITY = "androidx.core.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_ACTIVITY_INTEROP = "android.support.v4.app.EXTRA_CALLING_ACTIVITY";
+    field public static final String EXTRA_CALLING_PACKAGE = "androidx.core.app.EXTRA_CALLING_PACKAGE";
+    field public static final String EXTRA_CALLING_PACKAGE_INTEROP = "android.support.v4.app.EXTRA_CALLING_PACKAGE";
+  }
+
+  public static class ShareCompat.IntentBuilder {
+    ctor public ShareCompat.IntentBuilder(android.content.Context);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailBcc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailCc(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String);
+    method public androidx.core.app.ShareCompat.IntentBuilder addEmailTo(String![]);
+    method public androidx.core.app.ShareCompat.IntentBuilder addStream(android.net.Uri);
+    method public android.content.Intent createChooserIntent();
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentBuilder from(android.app.Activity);
+    method public android.content.Intent getIntent();
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(@StringRes int);
+    method public androidx.core.app.ShareCompat.IntentBuilder setChooserTitle(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailBcc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailCc(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setEmailTo(String![]?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setHtmlText(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setStream(android.net.Uri?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setSubject(String?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setText(CharSequence?);
+    method public androidx.core.app.ShareCompat.IntentBuilder setType(String?);
+    method public void startChooser();
+  }
+
+  public static class ShareCompat.IntentReader {
+    ctor public ShareCompat.IntentReader(android.app.Activity);
+    ctor public ShareCompat.IntentReader(android.content.Context, android.content.Intent);
+    method @Deprecated public static androidx.core.app.ShareCompat.IntentReader from(android.app.Activity);
+    method public android.content.ComponentName? getCallingActivity();
+    method public android.graphics.drawable.Drawable? getCallingActivityIcon();
+    method public android.graphics.drawable.Drawable? getCallingApplicationIcon();
+    method public CharSequence? getCallingApplicationLabel();
+    method public String? getCallingPackage();
+    method public String![]? getEmailBcc();
+    method public String![]? getEmailCc();
+    method public String![]? getEmailTo();
+    method public String? getHtmlText();
+    method public android.net.Uri? getStream();
+    method public android.net.Uri? getStream(int);
+    method public int getStreamCount();
+    method public String? getSubject();
+    method public CharSequence? getText();
+    method public String? getType();
+    method public boolean isMultipleShare();
+    method public boolean isShareIntent();
+    method public boolean isSingleShare();
+  }
+
+  public abstract class SharedElementCallback {
+    ctor public SharedElementCallback();
+    method public android.os.Parcelable! onCaptureSharedElementSnapshot(android.view.View!, android.graphics.Matrix!, android.graphics.RectF!);
+    method public android.view.View! onCreateSnapshotView(android.content.Context!, android.os.Parcelable!);
+    method public void onMapSharedElements(java.util.List<java.lang.String!>!, java.util.Map<java.lang.String!,android.view.View!>!);
+    method public void onRejectSharedElements(java.util.List<android.view.View!>!);
+    method public void onSharedElementEnd(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementStart(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, java.util.List<android.view.View!>!);
+    method public void onSharedElementsArrived(java.util.List<java.lang.String!>!, java.util.List<android.view.View!>!, androidx.core.app.SharedElementCallback.OnSharedElementsReadyListener!);
+  }
+
+  public static interface SharedElementCallback.OnSharedElementsReadyListener {
+    method public void onSharedElementsReady();
+  }
+
+  public final class TaskStackBuilder implements java.lang.Iterable<android.content.Intent> {
+    method public androidx.core.app.TaskStackBuilder addNextIntent(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addNextIntentWithParentStack(android.content.Intent);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.app.Activity);
+    method public androidx.core.app.TaskStackBuilder addParentStack(android.content.ComponentName);
+    method public androidx.core.app.TaskStackBuilder addParentStack(Class<?>);
+    method public static androidx.core.app.TaskStackBuilder create(android.content.Context);
+    method public android.content.Intent? editIntentAt(int);
+    method @Deprecated public static androidx.core.app.TaskStackBuilder! from(android.content.Context!);
+    method @Deprecated public android.content.Intent! getIntent(int);
+    method public int getIntentCount();
+    method public android.content.Intent![] getIntents();
+    method public android.app.PendingIntent? getPendingIntent(int, int);
+    method public android.app.PendingIntent? getPendingIntent(int, int, android.os.Bundle?);
+    method @Deprecated public java.util.Iterator<android.content.Intent!> iterator();
+    method public void startActivities();
+    method public void startActivities(android.os.Bundle?);
+  }
+
+  public static interface TaskStackBuilder.SupportParentable {
+    method public android.content.Intent? getSupportParentActivityIntent();
+  }
+
+}
+
+package androidx.core.content {
+
+  public final class ContentProviderCompat {
+    method public static android.content.Context requireContext(android.content.ContentProvider);
+  }
+
+  public final class ContentResolverCompat {
+    method public static android.database.Cursor? query(android.content.ContentResolver, android.net.Uri, String![]?, String?, String![]?, String?, androidx.core.os.CancellationSignal?);
+  }
+
+  public class ContextCompat {
+    ctor protected ContextCompat();
+    method public static int checkSelfPermission(android.content.Context, String);
+    method public static android.content.Context? createDeviceProtectedStorageContext(android.content.Context);
+    method public static String? getAttributionTag(android.content.Context);
+    method public static java.io.File getCodeCacheDir(android.content.Context);
+    method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
+    method public static android.content.Context getContextForLanguage(android.content.Context);
+    method public static java.io.File? getDataDir(android.content.Context);
+    method public static android.view.Display getDisplayOrDefault(@DisplayContext android.content.Context);
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
+    method public static java.io.File![] getExternalCacheDirs(android.content.Context);
+    method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
+    method public static java.util.concurrent.Executor getMainExecutor(android.content.Context);
+    method public static java.io.File? getNoBackupFilesDir(android.content.Context);
+    method public static java.io.File![] getObbDirs(android.content.Context);
+    method public static String getString(android.content.Context, int);
+    method public static <T> T? getSystemService(android.content.Context, Class<T!>);
+    method public static String? getSystemServiceName(android.content.Context, Class<?>);
+    method public static boolean isDeviceProtectedStorage(android.content.Context);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, int);
+    method public static android.content.Intent? registerReceiver(android.content.Context, android.content.BroadcastReceiver?, android.content.IntentFilter, String?, android.os.Handler?, int);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![]);
+    method public static boolean startActivities(android.content.Context, android.content.Intent![], android.os.Bundle?);
+    method public static void startActivity(android.content.Context, android.content.Intent, android.os.Bundle?);
+    method public static void startForegroundService(android.content.Context, android.content.Intent);
+    field public static final int RECEIVER_EXPORTED = 2; // 0x2
+    field public static final int RECEIVER_NOT_EXPORTED = 4; // 0x4
+    field public static final int RECEIVER_VISIBLE_TO_INSTANT_APPS = 1; // 0x1
+  }
+
+  public class FileProvider extends android.content.ContentProvider {
+    ctor public FileProvider();
+    ctor protected FileProvider(@XmlRes int);
+    method public int delete(android.net.Uri, String?, String![]?);
+    method public String? getType(android.net.Uri);
+    method public String? getTypeAnonymous(android.net.Uri);
+    method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
+    method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
+    method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
+    method public boolean onCreate();
+    method public android.database.Cursor query(android.net.Uri, String![]?, String?, String![]?, String?);
+    method public int update(android.net.Uri, android.content.ContentValues, String?, String![]?);
+  }
+
+  public final class IntentCompat {
+    method public static android.content.Intent createManageUnusedAppRestrictionsIntent(android.content.Context, String);
+    method public static android.os.Parcelable![]? getParcelableArrayExtra(android.content.Intent, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayListExtra(android.content.Intent, String?, Class<? extends T>);
+    method public static <T> T? getParcelableExtra(android.content.Intent, String?, Class<T!>);
+    method public static android.content.Intent makeMainSelectorActivity(String, String);
+    field public static final String ACTION_CREATE_REMINDER = "android.intent.action.CREATE_REMINDER";
+    field public static final String CATEGORY_LEANBACK_LAUNCHER = "android.intent.category.LEANBACK_LAUNCHER";
+    field public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
+    field public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+    field public static final String EXTRA_TIME = "android.intent.extra.TIME";
+  }
+
+  public class IntentSanitizer {
+    method public android.content.Intent sanitize(android.content.Intent, androidx.core.util.Consumer<java.lang.String!>);
+    method public android.content.Intent sanitizeByFiltering(android.content.Intent);
+    method public android.content.Intent sanitizeByThrowing(android.content.Intent);
+  }
+
+  public static final class IntentSanitizer.Builder {
+    ctor public IntentSanitizer.Builder();
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowAction(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowAnyComponent();
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowCategory(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipData(androidx.core.util.Predicate<android.content.ClipData!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataText();
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUri(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowClipDataUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(android.content.ComponentName);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponent(androidx.core.util.Predicate<android.content.ComponentName!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowComponentWithPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowData(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowDataWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, androidx.core.util.Predicate<java.lang.Object!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<?>);
+    method public <T> androidx.core.content.IntentSanitizer.Builder allowExtra(String, Class<T!>, androidx.core.util.Predicate<T!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraOutput(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStream(androidx.core.util.Predicate<android.net.Uri!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowExtraStreamUriWithAuthority(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowFlags(int);
+    method public androidx.core.content.IntentSanitizer.Builder allowHistoryStackFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowIdentifier();
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowPackage(String);
+    method public androidx.core.content.IntentSanitizer.Builder allowReceiverFlags();
+    method public androidx.core.content.IntentSanitizer.Builder allowSelector();
+    method public androidx.core.content.IntentSanitizer.Builder allowSourceBounds();
+    method public androidx.core.content.IntentSanitizer.Builder allowType(androidx.core.util.Predicate<java.lang.String!>);
+    method public androidx.core.content.IntentSanitizer.Builder allowType(String);
+    method public androidx.core.content.IntentSanitizer build();
+  }
+
+  public final class LocusIdCompat {
+    ctor public LocusIdCompat(String);
+    method public String getId();
+    method @RequiresApi(29) public android.content.LocusId toLocusId();
+    method @RequiresApi(29) public static androidx.core.content.LocusIdCompat toLocusIdCompat(android.content.LocusId);
+  }
+
+  public final class MimeTypeFilter {
+    method public static boolean matches(String?, String);
+    method public static String? matches(String?, String![]);
+    method public static String? matches(String![]?, String);
+    method public static String![] matchesMany(String![]?, String);
+  }
+
+  public interface OnConfigurationChangedProvider {
+    method public void addOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+    method public void removeOnConfigurationChangedListener(androidx.core.util.Consumer<android.content.res.Configuration!>);
+  }
+
+  public interface OnTrimMemoryProvider {
+    method public void addOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+    method public void removeOnTrimMemoryListener(androidx.core.util.Consumer<java.lang.Integer!>);
+  }
+
+  public final class PackageManagerCompat {
+    method public static com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> getUnusedAppRestrictionsStatus(android.content.Context);
+    field public static final String ACTION_PERMISSION_REVOCATION_SETTINGS = "android.intent.action.AUTO_REVOKE_PERMISSIONS";
+  }
+
+  public final class PermissionChecker {
+    method public static int checkCallingOrSelfPermission(android.content.Context, String);
+    method public static int checkCallingPermission(android.content.Context, String, String?);
+    method public static int checkPermission(android.content.Context, String, int, int, String?);
+    method public static int checkSelfPermission(android.content.Context, String);
+    field public static final int PERMISSION_DENIED = -1; // 0xffffffff
+    field public static final int PERMISSION_DENIED_APP_OP = -2; // 0xfffffffe
+    field public static final int PERMISSION_GRANTED = 0; // 0x0
+  }
+
+  @Deprecated public final class SharedPreferencesCompat {
+  }
+
+  @Deprecated public static final class SharedPreferencesCompat.EditorCompat {
+    method @Deprecated public void apply(android.content.SharedPreferences.Editor);
+    method @Deprecated public static androidx.core.content.SharedPreferencesCompat.EditorCompat! getInstance();
+  }
+
+  public class UnusedAppRestrictionsBackportCallback {
+    method public void onResult(boolean, boolean) throws android.os.RemoteException;
+  }
+
+  public abstract class UnusedAppRestrictionsBackportService extends android.app.Service {
+    ctor public UnusedAppRestrictionsBackportService();
+    method protected abstract void isPermissionRevocationEnabled(androidx.core.content.UnusedAppRestrictionsBackportCallback);
+    method public android.os.IBinder? onBind(android.content.Intent?);
+    field public static final String ACTION_UNUSED_APP_RESTRICTIONS_BACKPORT_CONNECTION = "android.support.unusedapprestrictions.action.CustomUnusedAppRestrictionsBackportService";
+  }
+
+  public final class UnusedAppRestrictionsConstants {
+    field public static final int API_30 = 4; // 0x4
+    field public static final int API_30_BACKPORT = 3; // 0x3
+    field public static final int API_31 = 5; // 0x5
+    field public static final int DISABLED = 2; // 0x2
+    field public static final int ERROR = 0; // 0x0
+    field public static final int FEATURE_NOT_AVAILABLE = 1; // 0x1
+  }
+
+  public class UriMatcherCompat {
+    method public static androidx.core.util.Predicate<android.net.Uri!> asPredicate(android.content.UriMatcher);
+  }
+
+}
+
+package androidx.core.content.pm {
+
+  @Deprecated public final class ActivityInfoCompat {
+    field @Deprecated public static final int CONFIG_UI_MODE = 512; // 0x200
+  }
+
+  public final class PackageInfoCompat {
+    method public static long getLongVersionCode(android.content.pm.PackageInfo);
+    method public static java.util.List<android.content.pm.Signature!> getSignatures(android.content.pm.PackageManager, String) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static boolean hasSignatures(android.content.pm.PackageManager, String, @Size(min=1) java.util.Map<byte[]!,java.lang.Integer!>, boolean) throws android.content.pm.PackageManager.NameNotFoundException;
+  }
+
+  public final class PermissionInfoCompat {
+    method public static int getProtection(android.content.pm.PermissionInfo);
+    method public static int getProtectionFlags(android.content.pm.PermissionInfo);
+  }
+
+  public class ShortcutInfoCompat {
+    method public android.content.ComponentName? getActivity();
+    method public java.util.Set<java.lang.String!>? getCategories();
+    method public CharSequence? getDisabledMessage();
+    method public int getDisabledReason();
+    method public int getExcludedFromSurfaces();
+    method public android.os.PersistableBundle? getExtras();
+    method public String getId();
+    method public android.content.Intent getIntent();
+    method public android.content.Intent![] getIntents();
+    method public long getLastChangedTimestamp();
+    method public androidx.core.content.LocusIdCompat? getLocusId();
+    method public CharSequence? getLongLabel();
+    method public String getPackage();
+    method public int getRank();
+    method public CharSequence getShortLabel();
+    method public android.os.UserHandle? getUserHandle();
+    method public boolean hasKeyFieldsOnly();
+    method public boolean isCached();
+    method public boolean isDeclaredInManifest();
+    method public boolean isDynamic();
+    method public boolean isEnabled();
+    method public boolean isExcludedFromSurfaces(int);
+    method public boolean isImmutable();
+    method public boolean isPinned();
+    method @RequiresApi(25) public android.content.pm.ShortcutInfo! toShortcutInfo();
+    field public static final int SURFACE_LAUNCHER = 1; // 0x1
+  }
+
+  public static class ShortcutInfoCompat.Builder {
+    ctor public ShortcutInfoCompat.Builder(android.content.Context, String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder addCapabilityBinding(String, String, java.util.List<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat build();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setActivity(android.content.ComponentName);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setAlwaysBadged();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setCategories(java.util.Set<java.lang.String!>);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setDisabledMessage(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExcludedFromSurfaces(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setExtras(android.os.PersistableBundle);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIcon(androidx.core.graphics.drawable.IconCompat!);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntent(android.content.Intent);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIntents(android.content.Intent![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setIsConversation();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLocusId(androidx.core.content.LocusIdCompat?);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLabel(CharSequence);
+    method @Deprecated public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived();
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setLongLived(boolean);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPerson(androidx.core.app.Person);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setPersons(androidx.core.app.Person![]);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setRank(int);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setShortLabel(CharSequence);
+    method public androidx.core.content.pm.ShortcutInfoCompat.Builder setSliceUri(android.net.Uri);
+  }
+
+  public class ShortcutManagerCompat {
+    method public static boolean addDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static android.content.Intent createShortcutResultIntent(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void disableShortcuts(android.content.Context, java.util.List<java.lang.String!>, CharSequence?);
+    method public static void enableShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getDynamicShortcuts(android.content.Context);
+    method public static int getIconMaxHeight(android.content.Context);
+    method public static int getIconMaxWidth(android.content.Context);
+    method public static int getMaxShortcutCountPerActivity(android.content.Context);
+    method public static java.util.List<androidx.core.content.pm.ShortcutInfoCompat!> getShortcuts(android.content.Context, int);
+    method public static boolean isRateLimitingActive(android.content.Context);
+    method public static boolean isRequestPinShortcutSupported(android.content.Context);
+    method public static boolean pushDynamicShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat);
+    method public static void removeAllDynamicShortcuts(android.content.Context);
+    method public static void removeDynamicShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void removeLongLivedShortcuts(android.content.Context, java.util.List<java.lang.String!>);
+    method public static void reportShortcutUsed(android.content.Context, String);
+    method public static boolean requestPinShortcut(android.content.Context, androidx.core.content.pm.ShortcutInfoCompat, android.content.IntentSender?);
+    method public static boolean setDynamicShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    method public static boolean updateShortcuts(android.content.Context, java.util.List<androidx.core.content.pm.ShortcutInfoCompat!>);
+    field public static final String EXTRA_SHORTCUT_ID = "android.intent.extra.shortcut.ID";
+    field public static final int FLAG_MATCH_CACHED = 8; // 0x8
+    field public static final int FLAG_MATCH_DYNAMIC = 2; // 0x2
+    field public static final int FLAG_MATCH_MANIFEST = 1; // 0x1
+    field public static final int FLAG_MATCH_PINNED = 4; // 0x4
+  }
+
+}
+
+package androidx.core.content.res {
+
+  public final class ConfigurationHelper {
+    method public static int getDensityDpi(android.content.res.Resources);
+  }
+
+  public final class ResourcesCompat {
+    method public static void clearCachesForTheme(android.content.res.Resources.Theme);
+    method public static android.graphics.Typeface? getCachedFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method @ColorInt public static int getColor(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.content.res.ColorStateList? getColorStateList(android.content.res.Resources, @ColorRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawable(android.content.res.Resources, @DrawableRes int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static android.graphics.drawable.Drawable? getDrawableForDensity(android.content.res.Resources, @DrawableRes int, int, android.content.res.Resources.Theme?) throws android.content.res.Resources.NotFoundException;
+    method public static float getFloat(android.content.res.Resources, @DimenRes int);
+    method public static android.graphics.Typeface? getFont(android.content.Context, @FontRes int) throws android.content.res.Resources.NotFoundException;
+    method public static void getFont(android.content.Context, @FontRes int, androidx.core.content.res.ResourcesCompat.FontCallback, android.os.Handler?) throws android.content.res.Resources.NotFoundException;
+    field @AnyRes public static final int ID_NULL = 0; // 0x0
+  }
+
+  public abstract static class ResourcesCompat.FontCallback {
+    ctor public ResourcesCompat.FontCallback();
+    method public abstract void onFontRetrievalFailed(int);
+    method public abstract void onFontRetrieved(android.graphics.Typeface);
+  }
+
+  public static final class ResourcesCompat.ThemeCompat {
+    method public static void rebase(android.content.res.Resources.Theme);
+  }
+
+}
+
+package androidx.core.database {
+
+  public final class CursorWindowCompat {
+    method public static android.database.CursorWindow create(String?, long);
+  }
+
+  @Deprecated public final class DatabaseUtilsCompat {
+    method @Deprecated public static String![]! appendSelectionArgs(String![]!, String![]!);
+    method @Deprecated public static String! concatenateWhere(String!, String!);
+  }
+
+}
+
+package androidx.core.database.sqlite {
+
+  public final class SQLiteCursorCompat {
+    method public static void setFillWindowForwardOnly(android.database.sqlite.SQLiteCursor, boolean);
+  }
+
+}
+
+package androidx.core.graphics {
+
+  public final class BitmapCompat {
+    method public static android.graphics.Bitmap createScaledBitmap(android.graphics.Bitmap, int, int, android.graphics.Rect?, boolean);
+    method public static int getAllocationByteCount(android.graphics.Bitmap);
+    method public static boolean hasMipMap(android.graphics.Bitmap);
+    method public static void setHasMipMap(android.graphics.Bitmap, boolean);
+  }
+
+  public class BlendModeColorFilterCompat {
+    method public static android.graphics.ColorFilter? createBlendModeColorFilterCompat(int, androidx.core.graphics.BlendModeCompat);
+  }
+
+  public enum BlendModeCompat {
+    enum_constant public static final androidx.core.graphics.BlendModeCompat CLEAR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_BURN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat COLOR_DODGE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DARKEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat DIFFERENCE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat DST_OVER;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat EXCLUSION;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HARD_LIGHT;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat HUE;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat LIGHTEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat LUMINOSITY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat MODULATE;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat MULTIPLY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat OVERLAY;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat PLUS;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SATURATION;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SCREEN;
+    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.Q) public static final androidx.core.graphics.BlendModeCompat SOFT_LIGHT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_ATOP;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_IN;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OUT;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat SRC_OVER;
+    enum_constant public static final androidx.core.graphics.BlendModeCompat XOR;
+  }
+
+  public final class ColorUtils {
+    method @ColorInt public static int HSLToColor(float[]);
+    method @ColorInt public static int LABToColor(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double);
+    method public static void LABToXYZ(@FloatRange(from=0.0f, to=100) double, @FloatRange(from=0xffffff80, to=127) double, @FloatRange(from=0xffffff80, to=127) double, double[]);
+    method @ColorInt public static int M3HCTtoColor(float, float, float);
+    method public static void RGBToHSL(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, float[]);
+    method public static void RGBToLAB(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method public static void RGBToXYZ(@IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, @IntRange(from=0, to=255) int, double[]);
+    method @ColorInt public static int XYZToColor(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double);
+    method public static void XYZToLAB(@FloatRange(from=0.0f, to=95.047) double, @FloatRange(from=0.0f, to=0x64) double, @FloatRange(from=0.0f, to=108.883) double, double[]);
+    method @ColorInt public static int blendARGB(@ColorInt int, @ColorInt int, @FloatRange(from=0.0, to=1.0) float);
+    method public static void blendHSL(float[], float[], @FloatRange(from=0.0, to=1.0) float, float[]);
+    method public static void blendLAB(double[], double[], @FloatRange(from=0.0, to=1.0) double, double[]);
+    method public static double calculateContrast(@ColorInt int, @ColorInt int);
+    method @FloatRange(from=0.0, to=1.0) public static double calculateLuminance(@ColorInt int);
+    method public static int calculateMinimumAlpha(@ColorInt int, @ColorInt int, float);
+    method public static void colorToHSL(@ColorInt int, float[]);
+    method public static void colorToLAB(@ColorInt int, double[]);
+    method public static void colorToM3HCT(@ColorInt int, float[]);
+    method public static void colorToXYZ(@ColorInt int, double[]);
+    method @RequiresApi(26) public static android.graphics.Color compositeColors(android.graphics.Color, android.graphics.Color);
+    method public static int compositeColors(@ColorInt int, @ColorInt int);
+    method public static double distanceEuclidean(double[], double[]);
+    method @ColorInt public static int setAlphaComponent(@ColorInt int, @IntRange(from=0, to=255) int);
+  }
+
+  public final class Insets {
+    method public static androidx.core.graphics.Insets add(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets max(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets min(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public static androidx.core.graphics.Insets of(android.graphics.Rect);
+    method public static androidx.core.graphics.Insets of(int, int, int, int);
+    method public static androidx.core.graphics.Insets subtract(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method @RequiresApi(api=29) public static androidx.core.graphics.Insets toCompatInsets(android.graphics.Insets);
+    method @RequiresApi(29) public android.graphics.Insets toPlatformInsets();
+    field public static final androidx.core.graphics.Insets NONE;
+    field public final int bottom;
+    field public final int left;
+    field public final int right;
+    field public final int top;
+  }
+
+  public final class PaintCompat {
+    method public static boolean hasGlyph(android.graphics.Paint, String);
+    method public static boolean setBlendMode(android.graphics.Paint, androidx.core.graphics.BlendModeCompat?);
+  }
+
+  public final class PathSegment {
+    ctor public PathSegment(android.graphics.PointF, float, android.graphics.PointF, float);
+    method public android.graphics.PointF getEnd();
+    method public float getEndFraction();
+    method public android.graphics.PointF getStart();
+    method public float getStartFraction();
+  }
+
+  public final class PathUtils {
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path);
+    method @RequiresApi(26) public static java.util.Collection<androidx.core.graphics.PathSegment!> flatten(android.graphics.Path, @FloatRange(from=0) float);
+  }
+
+  public class TypefaceCompat {
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, int);
+    method public static android.graphics.Typeface create(android.content.Context, android.graphics.Typeface?, @IntRange(from=1, to=1000) int, boolean);
+  }
+
+}
+
+package androidx.core.graphics.drawable {
+
+  public final class DrawableCompat {
+    method public static void applyTheme(android.graphics.drawable.Drawable, android.content.res.Resources.Theme);
+    method public static boolean canApplyTheme(android.graphics.drawable.Drawable);
+    method public static void clearColorFilter(android.graphics.drawable.Drawable);
+    method public static int getAlpha(android.graphics.drawable.Drawable);
+    method public static android.graphics.ColorFilter? getColorFilter(android.graphics.drawable.Drawable);
+    method public static int getLayoutDirection(android.graphics.drawable.Drawable);
+    method public static void inflate(android.graphics.drawable.Drawable, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme?) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static boolean isAutoMirrored(android.graphics.drawable.Drawable);
+    method @Deprecated public static void jumpToCurrentState(android.graphics.drawable.Drawable);
+    method public static void setAutoMirrored(android.graphics.drawable.Drawable, boolean);
+    method public static void setHotspot(android.graphics.drawable.Drawable, float, float);
+    method public static void setHotspotBounds(android.graphics.drawable.Drawable, int, int, int, int);
+    method public static boolean setLayoutDirection(android.graphics.drawable.Drawable, int);
+    method public static void setTint(android.graphics.drawable.Drawable, @ColorInt int);
+    method public static void setTintList(android.graphics.drawable.Drawable, android.content.res.ColorStateList?);
+    method public static void setTintMode(android.graphics.drawable.Drawable, android.graphics.PorterDuff.Mode?);
+    method public static <T extends android.graphics.drawable.Drawable> T! unwrap(android.graphics.drawable.Drawable);
+    method public static android.graphics.drawable.Drawable wrap(android.graphics.drawable.Drawable);
+  }
+
+  public class IconCompat implements androidx.versionedparcelable.VersionedParcelable {
+    method public static androidx.core.graphics.drawable.IconCompat? createFromBundle(android.os.Bundle);
+    method @RequiresApi(23) public static androidx.core.graphics.drawable.IconCompat? createFromIcon(android.content.Context, android.graphics.drawable.Icon);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithAdaptiveBitmapContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithBitmap(android.graphics.Bitmap);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(android.net.Uri);
+    method public static androidx.core.graphics.drawable.IconCompat createWithContentUri(String);
+    method public static androidx.core.graphics.drawable.IconCompat createWithData(byte[], int, int);
+    method public static androidx.core.graphics.drawable.IconCompat createWithResource(android.content.Context, @DrawableRes int);
+    method @DrawableRes public int getResId();
+    method public String getResPackage();
+    method public int getType();
+    method public android.net.Uri getUri();
+    method public android.graphics.drawable.Drawable? loadDrawable(android.content.Context);
+    method public void onPostParceling();
+    method public void onPreParceling(boolean);
+    method public androidx.core.graphics.drawable.IconCompat setTint(@ColorInt int);
+    method public androidx.core.graphics.drawable.IconCompat setTintList(android.content.res.ColorStateList?);
+    method public androidx.core.graphics.drawable.IconCompat setTintMode(android.graphics.PorterDuff.Mode?);
+    method public android.os.Bundle toBundle();
+    method @Deprecated @RequiresApi(23) public android.graphics.drawable.Icon toIcon();
+    method @RequiresApi(23) public android.graphics.drawable.Icon toIcon(android.content.Context?);
+    field public static final int TYPE_ADAPTIVE_BITMAP = 5; // 0x5
+    field public static final int TYPE_BITMAP = 1; // 0x1
+    field public static final int TYPE_DATA = 3; // 0x3
+    field public static final int TYPE_RESOURCE = 2; // 0x2
+    field public static final int TYPE_UNKNOWN = -1; // 0xffffffff
+    field public static final int TYPE_URI = 4; // 0x4
+    field public static final int TYPE_URI_ADAPTIVE_BITMAP = 6; // 0x6
+  }
+
+  public abstract class RoundedBitmapDrawable extends android.graphics.drawable.Drawable {
+    method public void draw(android.graphics.Canvas);
+    method public final android.graphics.Bitmap? getBitmap();
+    method public float getCornerRadius();
+    method public int getGravity();
+    method public int getOpacity();
+    method public final android.graphics.Paint getPaint();
+    method public boolean hasAntiAlias();
+    method public boolean hasMipMap();
+    method public boolean isCircular();
+    method public void setAlpha(int);
+    method public void setAntiAlias(boolean);
+    method public void setCircular(boolean);
+    method public void setColorFilter(android.graphics.ColorFilter!);
+    method public void setCornerRadius(float);
+    method public void setDither(boolean);
+    method public void setGravity(int);
+    method public void setMipMap(boolean);
+    method public void setTargetDensity(android.graphics.Canvas);
+    method public void setTargetDensity(android.util.DisplayMetrics);
+    method public void setTargetDensity(int);
+  }
+
+  public final class RoundedBitmapDrawableFactory {
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, android.graphics.Bitmap?);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, java.io.InputStream);
+    method public static androidx.core.graphics.drawable.RoundedBitmapDrawable create(android.content.res.Resources, String);
+  }
+
+}
+
+package androidx.core.hardware.display {
+
+  public final class DisplayManagerCompat {
+    method public android.view.Display? getDisplay(int);
+    method public android.view.Display![] getDisplays();
+    method public android.view.Display![] getDisplays(String?);
+    method public static androidx.core.hardware.display.DisplayManagerCompat getInstance(android.content.Context);
+    field public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION";
+  }
+
+}
+
+package androidx.core.hardware.fingerprint {
+
+  @Deprecated public class FingerprintManagerCompat {
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public void authenticate(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject?, int, androidx.core.os.CancellationSignal?, androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationCallback, android.os.Handler?);
+    method @Deprecated public static androidx.core.hardware.fingerprint.FingerprintManagerCompat from(android.content.Context);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected();
+  }
+
+  @Deprecated public abstract static class FingerprintManagerCompat.AuthenticationCallback {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationCallback();
+    method @Deprecated public void onAuthenticationError(int, CharSequence!);
+    method @Deprecated public void onAuthenticationFailed();
+    method @Deprecated public void onAuthenticationHelp(int, CharSequence!);
+    method @Deprecated public void onAuthenticationSucceeded(androidx.core.hardware.fingerprint.FingerprintManagerCompat.AuthenticationResult!);
+  }
+
+  @Deprecated public static final class FingerprintManagerCompat.AuthenticationResult {
+    ctor @Deprecated public FingerprintManagerCompat.AuthenticationResult(androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject!);
+    method @Deprecated public androidx.core.hardware.fingerprint.FingerprintManagerCompat.CryptoObject! getCryptoObject();
+  }
+
+  @Deprecated public static class FingerprintManagerCompat.CryptoObject {
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(java.security.Signature);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Cipher);
+    ctor @Deprecated public FingerprintManagerCompat.CryptoObject(javax.crypto.Mac);
+    method @Deprecated public javax.crypto.Cipher? getCipher();
+    method @Deprecated public javax.crypto.Mac? getMac();
+    method @Deprecated public java.security.Signature? getSignature();
+  }
+
+}
+
+package androidx.core.location {
+
+  public abstract class GnssStatusCompat {
+    method @FloatRange(from=0, to=360) public abstract float getAzimuthDegrees(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getBasebandCn0DbHz(@IntRange(from=0) int);
+    method @FloatRange(from=0) public abstract float getCarrierFrequencyHz(@IntRange(from=0) int);
+    method @FloatRange(from=0, to=63) public abstract float getCn0DbHz(@IntRange(from=0) int);
+    method public abstract int getConstellationType(@IntRange(from=0) int);
+    method @FloatRange(from=0xffffffa6, to=90) public abstract float getElevationDegrees(@IntRange(from=0) int);
+    method @IntRange(from=0) public abstract int getSatelliteCount();
+    method @IntRange(from=1, to=200) public abstract int getSvid(@IntRange(from=0) int);
+    method public abstract boolean hasAlmanacData(@IntRange(from=0) int);
+    method public abstract boolean hasBasebandCn0DbHz(@IntRange(from=0) int);
+    method public abstract boolean hasCarrierFrequencyHz(@IntRange(from=0) int);
+    method public abstract boolean hasEphemerisData(@IntRange(from=0) int);
+    method public abstract boolean usedInFix(@IntRange(from=0) int);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static androidx.core.location.GnssStatusCompat wrap(android.location.GnssStatus);
+    method public static androidx.core.location.GnssStatusCompat wrap(android.location.GpsStatus);
+    field public static final int CONSTELLATION_BEIDOU = 5; // 0x5
+    field public static final int CONSTELLATION_GALILEO = 6; // 0x6
+    field public static final int CONSTELLATION_GLONASS = 3; // 0x3
+    field public static final int CONSTELLATION_GPS = 1; // 0x1
+    field public static final int CONSTELLATION_IRNSS = 7; // 0x7
+    field public static final int CONSTELLATION_QZSS = 4; // 0x4
+    field public static final int CONSTELLATION_SBAS = 2; // 0x2
+    field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0
+  }
+
+  public abstract static class GnssStatusCompat.Callback {
+    ctor public GnssStatusCompat.Callback();
+    method public void onFirstFix(@IntRange(from=0) int);
+    method public void onSatelliteStatusChanged(androidx.core.location.GnssStatusCompat);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public final class LocationCompat {
+    method public static float getBearingAccuracyDegrees(android.location.Location);
+    method public static long getElapsedRealtimeMillis(android.location.Location);
+    method public static long getElapsedRealtimeNanos(android.location.Location);
+    method @FloatRange(from=0.0) public static float getMslAltitudeAccuracyMeters(android.location.Location);
+    method public static double getMslAltitudeMeters(android.location.Location);
+    method public static float getSpeedAccuracyMetersPerSecond(android.location.Location);
+    method public static float getVerticalAccuracyMeters(android.location.Location);
+    method public static boolean hasBearingAccuracy(android.location.Location);
+    method public static boolean hasMslAltitude(android.location.Location);
+    method public static boolean hasMslAltitudeAccuracy(android.location.Location);
+    method public static boolean hasSpeedAccuracy(android.location.Location);
+    method public static boolean hasVerticalAccuracy(android.location.Location);
+    method public static boolean isMock(android.location.Location);
+    method public static void removeMslAltitude(android.location.Location);
+    method public static void removeMslAltitudeAccuracy(android.location.Location);
+    method public static void setBearingAccuracyDegrees(android.location.Location, float);
+    method public static void setMock(android.location.Location, boolean);
+    method public static void setMslAltitudeAccuracyMeters(android.location.Location, @FloatRange(from=0.0) float);
+    method public static void setMslAltitudeMeters(android.location.Location, double);
+    method public static void setSpeedAccuracyMetersPerSecond(android.location.Location, float);
+    method public static void setVerticalAccuracyMeters(android.location.Location, float);
+    field public static final String EXTRA_BEARING_ACCURACY = "bearingAccuracy";
+    field public static final String EXTRA_IS_MOCK = "mockLocation";
+    field public static final String EXTRA_MSL_ALTITUDE = "androidx.core.location.extra.MSL_ALTITUDE";
+    field public static final String EXTRA_MSL_ALTITUDE_ACCURACY = "androidx.core.location.extra.MSL_ALTITUDE_ACCURACY";
+    field public static final String EXTRA_SPEED_ACCURACY = "speedAccuracy";
+    field public static final String EXTRA_VERTICAL_ACCURACY = "verticalAccuracy";
+  }
+
+  public interface LocationListenerCompat extends android.location.LocationListener {
+    method public default void onStatusChanged(String, int, android.os.Bundle?);
+  }
+
+  public final class LocationManagerCompat {
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void getCurrentLocation(android.location.LocationManager, String, androidx.core.os.CancellationSignal?, java.util.concurrent.Executor, androidx.core.util.Consumer<android.location.Location!>);
+    method public static String? getGnssHardwareModelName(android.location.LocationManager);
+    method public static int getGnssYearOfHardware(android.location.LocationManager);
+    method public static boolean hasProvider(android.location.LocationManager, String);
+    method public static boolean isLocationEnabled(android.location.LocationManager);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssMeasurementsCallback(android.location.LocationManager, java.util.concurrent.Executor, android.location.GnssMeasurementsEvent.Callback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback, android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static boolean registerGnssStatusCallback(android.location.LocationManager, java.util.concurrent.Executor, androidx.core.location.GnssStatusCompat.Callback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void removeUpdates(android.location.LocationManager, androidx.core.location.LocationListenerCompat);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, androidx.core.location.LocationListenerCompat, android.os.Looper);
+    method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static void requestLocationUpdates(android.location.LocationManager, String, androidx.core.location.LocationRequestCompat, java.util.concurrent.Executor, androidx.core.location.LocationListenerCompat);
+    method @RequiresApi(android.os.Build.VERSION_CODES.N) public static void unregisterGnssMeasurementsCallback(android.location.LocationManager, android.location.GnssMeasurementsEvent.Callback);
+    method public static void unregisterGnssStatusCallback(android.location.LocationManager, androidx.core.location.GnssStatusCompat.Callback);
+  }
+
+  public final class LocationRequestCompat {
+    method @IntRange(from=1) public long getDurationMillis();
+    method @IntRange(from=0) public long getIntervalMillis();
+    method @IntRange(from=0) public long getMaxUpdateDelayMillis();
+    method @IntRange(from=1, to=java.lang.Integer.MAX_VALUE) public int getMaxUpdates();
+    method @FloatRange(from=0, to=java.lang.Float.MAX_VALUE) public float getMinUpdateDistanceMeters();
+    method @IntRange(from=0) public long getMinUpdateIntervalMillis();
+    method public int getQuality();
+    method @RequiresApi(31) public android.location.LocationRequest toLocationRequest();
+    method @RequiresApi(19) public android.location.LocationRequest? toLocationRequest(String);
+    field public static final long PASSIVE_INTERVAL = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final int QUALITY_BALANCED_POWER_ACCURACY = 102; // 0x66
+    field public static final int QUALITY_HIGH_ACCURACY = 100; // 0x64
+    field public static final int QUALITY_LOW_POWER = 104; // 0x68
+  }
+
+  public static final class LocationRequestCompat.Builder {
+    ctor public LocationRequestCompat.Builder(androidx.core.location.LocationRequestCompat);
+    ctor public LocationRequestCompat.Builder(long);
+    method public androidx.core.location.LocationRequestCompat build();
+    method public androidx.core.location.LocationRequestCompat.Builder clearMinUpdateIntervalMillis();
+    method public androidx.core.location.LocationRequestCompat.Builder setDurationMillis(@IntRange(from=1) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdateDelayMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setMaxUpdates(@IntRange(from=1, to=java.lang.Integer.MAX_VALUE) int);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateDistanceMeters(@FloatRange(from=0, to=java.lang.Float.MAX_VALUE) float);
+    method public androidx.core.location.LocationRequestCompat.Builder setMinUpdateIntervalMillis(@IntRange(from=0) long);
+    method public androidx.core.location.LocationRequestCompat.Builder setQuality(int);
+  }
+
+}
+
+package androidx.core.math {
+
+  public class MathUtils {
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static double clamp(double, double, double);
+    method public static float clamp(float, float, float);
+    method public static int clamp(int, int, int);
+    method public static long clamp(long, long, long);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static int toIntExact(long);
+  }
+
+}
+
+package androidx.core.net {
+
+  public final class ConnectivityManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static android.net.NetworkInfo? getNetworkInfoFromBroadcast(android.net.ConnectivityManager, android.content.Intent);
+    method public static int getRestrictBackgroundStatus(android.net.ConnectivityManager);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public static boolean isActiveNetworkMetered(android.net.ConnectivityManager);
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+  }
+
+  public final class MailTo {
+    method public String? getBcc();
+    method public String? getBody();
+    method public String? getCc();
+    method public java.util.Map<java.lang.String!,java.lang.String!>? getHeaders();
+    method public String? getSubject();
+    method public String? getTo();
+    method public static boolean isMailTo(android.net.Uri?);
+    method public static boolean isMailTo(String?);
+    method public static androidx.core.net.MailTo parse(android.net.Uri) throws androidx.core.net.ParseException;
+    method public static androidx.core.net.MailTo parse(String) throws androidx.core.net.ParseException;
+    field public static final String MAILTO_SCHEME = "mailto:";
+  }
+
+  public class ParseException extends java.lang.RuntimeException {
+    field public final String response;
+  }
+
+  public final class TrafficStatsCompat {
+    method @Deprecated public static void clearThreadStatsTag();
+    method @Deprecated public static int getThreadStatsTag();
+    method @Deprecated public static void incrementOperationCount(int);
+    method @Deprecated public static void incrementOperationCount(int, int);
+    method @Deprecated public static void setThreadStatsTag(int);
+    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void tagSocket(java.net.Socket!) throws java.net.SocketException;
+    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
+    method @Deprecated public static void untagSocket(java.net.Socket!) throws java.net.SocketException;
+  }
+
+  public final class UriCompat {
+    method public static String toSafeString(android.net.Uri);
+  }
+
+}
+
+package androidx.core.os {
+
+  public class BuildCompat {
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N) public static boolean isAtLeastN();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.N_MR1) public static boolean isAtLeastNMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O) public static boolean isAtLeastO();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.O_MR1) public static boolean isAtLeastOMR1();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.P) public static boolean isAtLeastP();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
+    method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
+    method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
+    method @Deprecated @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
+    method @Deprecated @ChecksSdkIntAtLeast(api=33, codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
+    method @ChecksSdkIntAtLeast(api=34, codename="UpsideDownCake") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastU();
+    method @ChecksSdkIntAtLeast(codename="VanillaIceCream") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastV();
+    field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
+    field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
+  }
+
+  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface BuildCompat.PrereleaseSdkCheck {
+  }
+
+  public final class BundleCompat {
+    method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
+    method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
+    method public static android.os.Parcelable![]? getParcelableArray(android.os.Bundle, String?, Class<? extends android.os.Parcelable>);
+    method public static <T> java.util.ArrayList<T!>? getParcelableArrayList(android.os.Bundle, String?, Class<? extends T>);
+    method public static <T> android.util.SparseArray<T!>? getSparseParcelableArray(android.os.Bundle, String?, Class<? extends T>);
+    method public static void putBinder(android.os.Bundle, String?, android.os.IBinder?);
+  }
+
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public Object? getCancellationSignalObject();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(androidx.core.os.CancellationSignal.OnCancelListener?);
+    method public void throwIfCanceled();
+  }
+
+  public static interface CancellationSignal.OnCancelListener {
+    method public void onCancel();
+  }
+
+  public final class ConfigurationCompat {
+    method public static androidx.core.os.LocaleListCompat getLocales(android.content.res.Configuration);
+    method public static void setLocales(android.content.res.Configuration, androidx.core.os.LocaleListCompat);
+  }
+
+  public final class EnvironmentCompat {
+    method public static String getStorageState(java.io.File);
+    field public static final String MEDIA_UNKNOWN = "unknown";
+  }
+
+  public final class ExecutorCompat {
+    method public static java.util.concurrent.Executor create(android.os.Handler);
+  }
+
+  public final class HandlerCompat {
+    method public static android.os.Handler createAsync(android.os.Looper);
+    method public static android.os.Handler createAsync(android.os.Looper, android.os.Handler.Callback);
+    method @RequiresApi(16) public static boolean hasCallbacks(android.os.Handler, Runnable);
+    method public static boolean postDelayed(android.os.Handler, Runnable, Object?, long);
+  }
+
+  public final class LocaleListCompat {
+    method public static androidx.core.os.LocaleListCompat create(java.util.Locale!...);
+    method public static androidx.core.os.LocaleListCompat forLanguageTags(String?);
+    method public java.util.Locale? get(int);
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getAdjustedDefault();
+    method @Size(min=1) public static androidx.core.os.LocaleListCompat getDefault();
+    method public static androidx.core.os.LocaleListCompat getEmptyLocaleList();
+    method public java.util.Locale? getFirstMatch(String![]);
+    method @IntRange(from=0xffffffff) public int indexOf(java.util.Locale?);
+    method public boolean isEmpty();
+    method @RequiresApi(21) public static boolean matchesLanguageAndScript(java.util.Locale, java.util.Locale);
+    method @IntRange(from=0) public int size();
+    method public String toLanguageTags();
+    method public Object? unwrap();
+    method @RequiresApi(24) public static androidx.core.os.LocaleListCompat wrap(android.os.LocaleList);
+    method @Deprecated @RequiresApi(24) public static androidx.core.os.LocaleListCompat! wrap(Object!);
+  }
+
+  public final class MessageCompat {
+    method public static boolean isAsynchronous(android.os.Message);
+    method public static void setAsynchronous(android.os.Message, boolean);
+  }
+
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(String?);
+  }
+
+  public final class ParcelCompat {
+    method public static <T> Object![]? readArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> java.util.ArrayList<T!>? readArrayList(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static boolean readBoolean(android.os.Parcel);
+    method public static <K, V> java.util.HashMap<K!,V!>? readHashMap(android.os.Parcel, ClassLoader?, Class<? extends K>, Class<? extends V>);
+    method public static <T> void readList(android.os.Parcel, java.util.List<? super T>, ClassLoader?, Class<T!>);
+    method public static <K, V> void readMap(android.os.Parcel, java.util.Map<? super K,? super V>, ClassLoader?, Class<K!>, Class<V!>);
+    method public static <T extends android.os.Parcelable> T? readParcelable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @Deprecated public static <T> T![]? readParcelableArray(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.os.Parcelable![]? readParcelableArrayTyped(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(30) public static <T> android.os.Parcelable.Creator<T!>? readParcelableCreator(android.os.Parcel, ClassLoader?, Class<T!>);
+    method @RequiresApi(api=android.os.Build.VERSION_CODES.Q) public static <T> java.util.List<T!> readParcelableList(android.os.Parcel, java.util.List<T!>, ClassLoader?, Class<T!>);
+    method public static <T extends java.io.Serializable> T? readSerializable(android.os.Parcel, ClassLoader?, Class<T!>);
+    method public static <T> android.util.SparseArray<T!>? readSparseArray(android.os.Parcel, ClassLoader?, Class<? extends T>);
+    method public static void writeBoolean(android.os.Parcel, boolean);
+  }
+
+  @Deprecated public final class ParcelableCompat {
+    method @Deprecated public static <T> android.os.Parcelable.Creator<T!>! newCreator(androidx.core.os.ParcelableCompatCreatorCallbacks<T!>!);
+  }
+
+  @Deprecated public interface ParcelableCompatCreatorCallbacks<T> {
+    method @Deprecated public T! createFromParcel(android.os.Parcel!, ClassLoader!);
+    method @Deprecated public T![]! newArray(int);
+  }
+
+  public final class ProcessCompat {
+    method public static boolean isApplicationUid(int);
+  }
+
+  @Deprecated public final class TraceCompat {
+    method @Deprecated public static void beginAsyncSection(String, int);
+    method @Deprecated public static void beginSection(String);
+    method @Deprecated public static void endAsyncSection(String, int);
+    method @Deprecated public static void endSection();
+    method @Deprecated public static boolean isEnabled();
+    method @Deprecated public static void setCounter(String, int);
+  }
+
+  @RequiresApi(17) public class UserHandleCompat {
+    method public static android.os.UserHandle getUserHandleForUid(int);
+  }
+
+  public class UserManagerCompat {
+    method public static boolean isUserUnlocked(android.content.Context);
+  }
+
+}
+
+package androidx.core.provider {
+
+  public final class DocumentsContractCompat {
+    method public static android.net.Uri? buildChildDocumentsUri(String, String?);
+    method public static android.net.Uri? buildChildDocumentsUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildDocumentUri(String, String);
+    method public static android.net.Uri? buildDocumentUriUsingTree(android.net.Uri, String);
+    method public static android.net.Uri? buildTreeDocumentUri(String, String);
+    method public static android.net.Uri? createDocument(android.content.ContentResolver, android.net.Uri, String, String) throws java.io.FileNotFoundException;
+    method public static String? getDocumentId(android.net.Uri);
+    method public static String? getTreeDocumentId(android.net.Uri);
+    method public static boolean isDocumentUri(android.content.Context, android.net.Uri?);
+    method public static boolean isTreeUri(android.net.Uri);
+    method public static boolean removeDocument(android.content.ContentResolver, android.net.Uri, android.net.Uri) throws java.io.FileNotFoundException;
+    method public static android.net.Uri? renameDocument(android.content.ContentResolver, android.net.Uri, String) throws java.io.FileNotFoundException;
+  }
+
+  public static final class DocumentsContractCompat.DocumentCompat {
+    field public static final int FLAG_VIRTUAL_DOCUMENT = 512; // 0x200
+  }
+
+  public final class FontRequest {
+    ctor public FontRequest(String, String, String, @ArrayRes int);
+    ctor public FontRequest(String, String, String, java.util.List<java.util.List<byte[]!>!>);
+    method public java.util.List<java.util.List<byte[]!>!>? getCertificates();
+    method @ArrayRes public int getCertificatesArrayResId();
+    method public String getProviderAuthority();
+    method public String getProviderPackage();
+    method public String getQuery();
+  }
+
+  public class FontsContractCompat {
+    method public static android.graphics.Typeface? buildTypeface(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontsContractCompat.FontInfo![]);
+    method public static androidx.core.provider.FontsContractCompat.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal?, androidx.core.provider.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public static void requestFont(android.content.Context, androidx.core.provider.FontRequest, androidx.core.provider.FontsContractCompat.FontRequestCallback, android.os.Handler);
+  }
+
+  public static final class FontsContractCompat.Columns implements android.provider.BaseColumns {
+    ctor public FontsContractCompat.Columns();
+    field public static final String FILE_ID = "file_id";
+    field public static final String ITALIC = "font_italic";
+    field public static final String RESULT_CODE = "result_code";
+    field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
+    field public static final int RESULT_CODE_OK = 0; // 0x0
+    field public static final String TTC_INDEX = "font_ttc_index";
+    field public static final String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final String WEIGHT = "font_weight";
+  }
+
+  public static class FontsContractCompat.FontFamilyResult {
+    method public androidx.core.provider.FontsContractCompat.FontInfo![]! getFonts();
+    method public int getStatusCode();
+    field public static final int STATUS_OK = 0; // 0x0
+    field public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; // 0x2
+    field public static final int STATUS_WRONG_CERTIFICATES = 1; // 0x1
+  }
+
+  public static class FontsContractCompat.FontInfo {
+    method public int getResultCode();
+    method @IntRange(from=0) public int getTtcIndex();
+    method public android.net.Uri getUri();
+    method @IntRange(from=1, to=1000) public int getWeight();
+    method public boolean isItalic();
+  }
+
+  public static class FontsContractCompat.FontRequestCallback {
+    ctor public FontsContractCompat.FontRequestCallback();
+    method public void onTypefaceRequestFailed(int);
+    method public void onTypefaceRetrieved(android.graphics.Typeface!);
+    field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd
+    field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1
+    field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2
+    field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3
+    field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff
+    field public static final int FAIL_REASON_SECURITY_VIOLATION = -4; // 0xfffffffc
+    field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe
+  }
+
+}
+
+package androidx.core.telephony {
+
+  @RequiresApi(22) public class SubscriptionManagerCompat {
+    method public static int getSlotIndex(int);
+  }
+
+  public class TelephonyManagerCompat {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static String? getImei(android.telephony.TelephonyManager);
+    method public static int getSubscriptionId(android.telephony.TelephonyManager);
+  }
+
+}
+
+package androidx.core.telephony.mbms {
+
+  public final class MbmsHelper {
+    method public static CharSequence? getBestNameForService(android.content.Context, android.telephony.mbms.ServiceInfo);
+  }
+
+}
+
+package androidx.core.text {
+
+  public final class BidiFormatter {
+    method public static androidx.core.text.BidiFormatter! getInstance();
+    method public static androidx.core.text.BidiFormatter! getInstance(boolean);
+    method public static androidx.core.text.BidiFormatter! getInstance(java.util.Locale!);
+    method public boolean getStereoReset();
+    method public boolean isRtl(CharSequence!);
+    method public boolean isRtl(String!);
+    method public boolean isRtlContext();
+    method public CharSequence! unicodeWrap(CharSequence!);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public CharSequence! unicodeWrap(CharSequence!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public CharSequence! unicodeWrap(CharSequence!, boolean);
+    method public String! unicodeWrap(String!);
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!);
+    method public String! unicodeWrap(String!, androidx.core.text.TextDirectionHeuristicCompat!, boolean);
+    method public String! unicodeWrap(String!, boolean);
+  }
+
+  public static final class BidiFormatter.Builder {
+    ctor public BidiFormatter.Builder();
+    ctor public BidiFormatter.Builder(boolean);
+    ctor public BidiFormatter.Builder(java.util.Locale!);
+    method public androidx.core.text.BidiFormatter! build();
+    method public androidx.core.text.BidiFormatter.Builder! setTextDirectionHeuristic(androidx.core.text.TextDirectionHeuristicCompat!);
+    method public androidx.core.text.BidiFormatter.Builder! stereoReset(boolean);
+  }
+
+  public final class HtmlCompat {
+    method public static android.text.Spanned fromHtml(String, int);
+    method public static android.text.Spanned fromHtml(String, int, android.text.Html.ImageGetter?, android.text.Html.TagHandler?);
+    method public static String toHtml(android.text.Spanned, int);
+    field public static final int FROM_HTML_MODE_COMPACT = 63; // 0x3f
+    field public static final int FROM_HTML_MODE_LEGACY = 0; // 0x0
+    field public static final int FROM_HTML_OPTION_USE_CSS_COLORS = 256; // 0x100
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_BLOCKQUOTE = 32; // 0x20
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_DIV = 16; // 0x10
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_HEADING = 2; // 0x2
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST = 8; // 0x8
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_LIST_ITEM = 4; // 0x4
+    field public static final int FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH = 1; // 0x1
+    field public static final int TO_HTML_PARAGRAPH_LINES_CONSECUTIVE = 0; // 0x0
+    field public static final int TO_HTML_PARAGRAPH_LINES_INDIVIDUAL = 1; // 0x1
+  }
+
+  public final class ICUCompat {
+    method public static String? maximizeAndGetScript(java.util.Locale);
+  }
+
+  public class PrecomputedTextCompat implements android.text.Spannable {
+    method public char charAt(int);
+    method public static androidx.core.text.PrecomputedTextCompat! create(CharSequence, androidx.core.text.PrecomputedTextCompat.Params);
+    method @IntRange(from=0) public int getParagraphCount();
+    method @IntRange(from=0) public int getParagraphEnd(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getParagraphStart(@IntRange(from=0) int);
+    method public androidx.core.text.PrecomputedTextCompat.Params getParams();
+    method public int getSpanEnd(Object!);
+    method public int getSpanFlags(Object!);
+    method public int getSpanStart(Object!);
+    method public <T> T![]! getSpans(int, int, Class<T!>!);
+    method @UiThread public static java.util.concurrent.Future<androidx.core.text.PrecomputedTextCompat!>! getTextFuture(CharSequence, androidx.core.text.PrecomputedTextCompat.Params, java.util.concurrent.Executor?);
+    method public int length();
+    method public int nextSpanTransition(int, int, Class!);
+    method public void removeSpan(Object!);
+    method public void setSpan(Object!, int, int, int);
+    method public CharSequence! subSequence(int, int);
+  }
+
+  public static final class PrecomputedTextCompat.Params {
+    ctor @RequiresApi(28) public PrecomputedTextCompat.Params(android.text.PrecomputedText.Params);
+    method @RequiresApi(23) public int getBreakStrategy();
+    method @RequiresApi(23) public int getHyphenationFrequency();
+    method @RequiresApi(18) public android.text.TextDirectionHeuristic? getTextDirection();
+    method public android.text.TextPaint getTextPaint();
+  }
+
+  public static class PrecomputedTextCompat.Params.Builder {
+    ctor public PrecomputedTextCompat.Params.Builder(android.text.TextPaint);
+    method public androidx.core.text.PrecomputedTextCompat.Params build();
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setBreakStrategy(int);
+    method @RequiresApi(23) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setHyphenationFrequency(int);
+    method @RequiresApi(18) public androidx.core.text.PrecomputedTextCompat.Params.Builder! setTextDirection(android.text.TextDirectionHeuristic);
+  }
+
+  public interface TextDirectionHeuristicCompat {
+    method public boolean isRtl(char[]!, int, int);
+    method public boolean isRtl(CharSequence!, int, int);
+  }
+
+  public final class TextDirectionHeuristicsCompat {
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! ANYRTL_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! FIRSTSTRONG_RTL;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LOCALE;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! LTR;
+    field public static final androidx.core.text.TextDirectionHeuristicCompat! RTL;
+  }
+
+  public final class TextUtilsCompat {
+    method public static int getLayoutDirectionFromLocale(java.util.Locale?);
+    method public static String htmlEncode(String);
+  }
+
+}
+
+package androidx.core.text.method {
+
+  public class LinkMovementMethodCompat extends android.text.method.LinkMovementMethod {
+    method public static androidx.core.text.method.LinkMovementMethodCompat getInstance();
+  }
+
+}
+
+package androidx.core.text.util {
+
+  public final class LinkifyCompat {
+    method public static boolean addLinks(android.text.Spannable, int);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.text.Spannable, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static boolean addLinks(android.widget.TextView, int);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+    method public static void addLinks(android.widget.TextView, java.util.regex.Pattern, String?, String![]?, android.text.util.Linkify.MatchFilter?, android.text.util.Linkify.TransformFilter?);
+  }
+
+}
+
+package androidx.core.util {
+
+  public class AtomicFile {
+    ctor public AtomicFile(java.io.File);
+    method public void delete();
+    method public void failWrite(java.io.FileOutputStream?);
+    method public void finishWrite(java.io.FileOutputStream?);
+    method public java.io.File getBaseFile();
+    method public java.io.FileInputStream openRead() throws java.io.FileNotFoundException;
+    method public byte[] readFully() throws java.io.IOException;
+    method public java.io.FileOutputStream startWrite() throws java.io.IOException;
+  }
+
+  public interface Consumer<T> {
+    method public void accept(T!);
+  }
+
+  public class ObjectsCompat {
+    method public static boolean equals(Object?, Object?);
+    method public static int hash(java.lang.Object!...);
+    method public static int hashCode(Object?);
+    method public static <T> T requireNonNull(T?);
+    method public static <T> T requireNonNull(T?, String);
+    method public static String? toString(Object?, String?);
+  }
+
+  public class Pair<F, S> {
+    ctor public Pair(F!, S!);
+    method public static <A, B> androidx.core.util.Pair<A!,B!> create(A!, B!);
+    field public final F! first;
+    field public final S! second;
+  }
+
+  public final class PatternsCompat {
+    field public static final java.util.regex.Pattern DOMAIN_NAME;
+    field public static final java.util.regex.Pattern EMAIL_ADDRESS;
+    field public static final java.util.regex.Pattern IP_ADDRESS;
+    field public static final java.util.regex.Pattern WEB_URL;
+  }
+
+  public final class Pools {
+  }
+
+  public static interface Pools.Pool<T> {
+    method public T? acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SimplePool<T> implements androidx.core.util.Pools.Pool<T> {
+    ctor public Pools.SimplePool(int);
+    method public T! acquire();
+    method public boolean release(T);
+  }
+
+  public static class Pools.SynchronizedPool<T> extends androidx.core.util.Pools.SimplePool<T> {
+    ctor public Pools.SynchronizedPool(int);
+  }
+
+  public interface Predicate<T> {
+    method public default androidx.core.util.Predicate<T!>! and(androidx.core.util.Predicate<? super T>!);
+    method public static <T> androidx.core.util.Predicate<T!>! isEqual(Object!);
+    method public default androidx.core.util.Predicate<T!>! negate();
+    method public static <T> androidx.core.util.Predicate<T!>! not(androidx.core.util.Predicate<? super T>!);
+    method public default androidx.core.util.Predicate<T!>! or(androidx.core.util.Predicate<? super T>!);
+    method public boolean test(T!);
+  }
+
+  public final class SizeFCompat {
+    ctor public SizeFCompat(float, float);
+    method public float getHeight();
+    method public float getWidth();
+    method @RequiresApi(21) public android.util.SizeF toSizeF();
+    method @RequiresApi(21) public static androidx.core.util.SizeFCompat toSizeFCompat(android.util.SizeF);
+  }
+
+  public interface Supplier<T> {
+    method public T! get();
+  }
+
+}
+
+package androidx.core.view {
+
+  public class AccessibilityDelegateCompat {
+    ctor public AccessibilityDelegateCompat();
+    method public boolean dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method public void onInitializeAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public void sendAccessibilityEvent(android.view.View, int);
+    method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
+  }
+
+  public abstract class ActionProvider {
+    ctor public ActionProvider(android.content.Context);
+    method public android.content.Context getContext();
+    method public boolean hasSubMenu();
+    method public boolean isVisible();
+    method public abstract android.view.View onCreateActionView();
+    method public android.view.View onCreateActionView(android.view.MenuItem);
+    method public boolean onPerformDefaultAction();
+    method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(androidx.core.view.ActionProvider.VisibilityListener?);
+  }
+
+  public static interface ActionProvider.VisibilityListener {
+    method public void onActionProviderVisibilityChanged(boolean);
+  }
+
+  public final class ContentInfoCompat {
+    method public android.content.ClipData getClip();
+    method public android.os.Bundle? getExtras();
+    method public int getFlags();
+    method public android.net.Uri? getLinkUri();
+    method public int getSource();
+    method @RequiresApi(31) public static android.util.Pair<android.view.ContentInfo!,android.view.ContentInfo!> partition(android.view.ContentInfo, java.util.function.Predicate<android.content.ClipData.Item!>);
+    method public android.util.Pair<androidx.core.view.ContentInfoCompat!,androidx.core.view.ContentInfoCompat!> partition(androidx.core.util.Predicate<android.content.ClipData.Item!>);
+    method @RequiresApi(31) public android.view.ContentInfo toContentInfo();
+    method @RequiresApi(31) public static androidx.core.view.ContentInfoCompat toContentInfoCompat(android.view.ContentInfo);
+    field public static final int FLAG_CONVERT_TO_PLAIN_TEXT = 1; // 0x1
+    field public static final int SOURCE_APP = 0; // 0x0
+    field public static final int SOURCE_AUTOFILL = 4; // 0x4
+    field public static final int SOURCE_CLIPBOARD = 1; // 0x1
+    field public static final int SOURCE_DRAG_AND_DROP = 3; // 0x3
+    field public static final int SOURCE_INPUT_METHOD = 2; // 0x2
+    field public static final int SOURCE_PROCESS_TEXT = 5; // 0x5
+  }
+
+  public static final class ContentInfoCompat.Builder {
+    ctor public ContentInfoCompat.Builder(android.content.ClipData, int);
+    ctor public ContentInfoCompat.Builder(androidx.core.view.ContentInfoCompat);
+    method public androidx.core.view.ContentInfoCompat build();
+    method public androidx.core.view.ContentInfoCompat.Builder setClip(android.content.ClipData);
+    method public androidx.core.view.ContentInfoCompat.Builder setExtras(android.os.Bundle?);
+    method public androidx.core.view.ContentInfoCompat.Builder setFlags(int);
+    method public androidx.core.view.ContentInfoCompat.Builder setLinkUri(android.net.Uri?);
+    method public androidx.core.view.ContentInfoCompat.Builder setSource(int);
+  }
+
+  public final class DisplayCompat {
+    method public static androidx.core.view.DisplayCompat.ModeCompat getMode(android.content.Context, android.view.Display);
+    method public static androidx.core.view.DisplayCompat.ModeCompat![] getSupportedModes(android.content.Context, android.view.Display);
+  }
+
+  public static final class DisplayCompat.ModeCompat {
+    method public int getPhysicalHeight();
+    method public int getPhysicalWidth();
+    method @Deprecated public boolean isNative();
+    method @RequiresApi(android.os.Build.VERSION_CODES.M) public android.view.Display.Mode? toMode();
+  }
+
+  public final class DisplayCutoutCompat {
+    ctor public DisplayCutoutCompat(android.graphics.Rect?, java.util.List<android.graphics.Rect!>?);
+    ctor public DisplayCutoutCompat(androidx.core.graphics.Insets, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, android.graphics.Rect?, androidx.core.graphics.Insets);
+    method public java.util.List<android.graphics.Rect!> getBoundingRects();
+    method public int getSafeInsetBottom();
+    method public int getSafeInsetLeft();
+    method public int getSafeInsetRight();
+    method public int getSafeInsetTop();
+    method public androidx.core.graphics.Insets getWaterfallInsets();
+  }
+
+  public final class DragAndDropPermissionsCompat {
+    method public void release();
+  }
+
+  public class DragStartHelper {
+    ctor public DragStartHelper(android.view.View, androidx.core.view.DragStartHelper.OnDragStartListener);
+    method public void attach();
+    method public void detach();
+    method public void getTouchPosition(android.graphics.Point);
+    method public boolean onLongClick(android.view.View);
+    method public boolean onTouch(android.view.View, android.view.MotionEvent);
+  }
+
+  public static interface DragStartHelper.OnDragStartListener {
+    method public boolean onDragStart(android.view.View, androidx.core.view.DragStartHelper);
+  }
+
+  public final class GestureDetectorCompat {
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener);
+    ctor public GestureDetectorCompat(android.content.Context, android.view.GestureDetector.OnGestureListener, android.os.Handler?);
+    method public boolean isLongpressEnabled();
+    method public boolean onTouchEvent(android.view.MotionEvent);
+    method public void setIsLongpressEnabled(boolean);
+    method public void setOnDoubleTapListener(android.view.GestureDetector.OnDoubleTapListener?);
+  }
+
+  public final class GravityCompat {
+    method public static void apply(int, int, int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static void apply(int, int, int, android.graphics.Rect, int, int, android.graphics.Rect, int);
+    method public static void applyDisplay(int, android.graphics.Rect, android.graphics.Rect, int);
+    method public static int getAbsoluteGravity(int, int);
+    field public static final int END = 8388613; // 0x800005
+    field public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = 8388615; // 0x800007
+    field public static final int RELATIVE_LAYOUT_DIRECTION = 8388608; // 0x800000
+    field public static final int START = 8388611; // 0x800003
+  }
+
+  public final class HapticFeedbackConstantsCompat {
+    field public static final int CLOCK_TICK = 4; // 0x4
+    field public static final int CONFIRM = 16; // 0x10
+    field public static final int CONTEXT_CLICK = 6; // 0x6
+    field public static final int DRAG_START = 25; // 0x19
+    field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
+    field public static final int GESTURE_END = 13; // 0xd
+    field public static final int GESTURE_START = 12; // 0xc
+    field public static final int GESTURE_THRESHOLD_ACTIVATE = 23; // 0x17
+    field public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; // 0x18
+    field public static final int KEYBOARD_PRESS = 3; // 0x3
+    field public static final int KEYBOARD_RELEASE = 7; // 0x7
+    field public static final int KEYBOARD_TAP = 3; // 0x3
+    field public static final int LONG_PRESS = 0; // 0x0
+    field public static final int NO_HAPTICS = -1; // 0xffffffff
+    field public static final int REJECT = 17; // 0x11
+    field public static final int SEGMENT_FREQUENT_TICK = 27; // 0x1b
+    field public static final int SEGMENT_TICK = 26; // 0x1a
+    field public static final int TEXT_HANDLE_MOVE = 9; // 0x9
+    field public static final int TOGGLE_OFF = 22; // 0x16
+    field public static final int TOGGLE_ON = 21; // 0x15
+    field public static final int VIRTUAL_KEY = 1; // 0x1
+    field public static final int VIRTUAL_KEY_RELEASE = 8; // 0x8
+  }
+
+  public final class InputDeviceCompat {
+    field public static final int SOURCE_ANY = -256; // 0xffffff00
+    field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
+    field public static final int SOURCE_CLASS_JOYSTICK = 16; // 0x10
+    field public static final int SOURCE_CLASS_MASK = 255; // 0xff
+    field public static final int SOURCE_CLASS_NONE = 0; // 0x0
+    field public static final int SOURCE_CLASS_POINTER = 2; // 0x2
+    field public static final int SOURCE_CLASS_POSITION = 8; // 0x8
+    field public static final int SOURCE_CLASS_TRACKBALL = 4; // 0x4
+    field public static final int SOURCE_DPAD = 513; // 0x201
+    field public static final int SOURCE_GAMEPAD = 1025; // 0x401
+    field public static final int SOURCE_HDMI = 33554433; // 0x2000001
+    field public static final int SOURCE_JOYSTICK = 16777232; // 0x1000010
+    field public static final int SOURCE_KEYBOARD = 257; // 0x101
+    field public static final int SOURCE_MOUSE = 8194; // 0x2002
+    field public static final int SOURCE_ROTARY_ENCODER = 4194304; // 0x400000
+    field public static final int SOURCE_STYLUS = 16386; // 0x4002
+    field public static final int SOURCE_TOUCHPAD = 1048584; // 0x100008
+    field public static final int SOURCE_TOUCHSCREEN = 4098; // 0x1002
+    field public static final int SOURCE_TOUCH_NAVIGATION = 2097152; // 0x200000
+    field public static final int SOURCE_TRACKBALL = 65540; // 0x10004
+    field public static final int SOURCE_UNKNOWN = 0; // 0x0
+  }
+
+  public final class LayoutInflaterCompat {
+    method @Deprecated public static androidx.core.view.LayoutInflaterFactory! getFactory(android.view.LayoutInflater!);
+    method @Deprecated public static void setFactory(android.view.LayoutInflater, androidx.core.view.LayoutInflaterFactory);
+    method public static void setFactory2(android.view.LayoutInflater, android.view.LayoutInflater.Factory2);
+  }
+
+  @Deprecated public interface LayoutInflaterFactory {
+    method @Deprecated public android.view.View! onCreateView(android.view.View!, String!, android.content.Context!, android.util.AttributeSet!);
+  }
+
+  public final class MarginLayoutParamsCompat {
+    method public static int getLayoutDirection(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginEnd(android.view.ViewGroup.MarginLayoutParams);
+    method public static int getMarginStart(android.view.ViewGroup.MarginLayoutParams);
+    method public static boolean isMarginRelative(android.view.ViewGroup.MarginLayoutParams);
+    method public static void resolveLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setLayoutDirection(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginEnd(android.view.ViewGroup.MarginLayoutParams, int);
+    method public static void setMarginStart(android.view.ViewGroup.MarginLayoutParams, int);
+  }
+
+  public final class MenuCompat {
+    method public static void setGroupDividerEnabled(android.view.Menu, boolean);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+  }
+
+  public interface MenuHost {
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void invalidateMenu();
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public class MenuHostHelper {
+    ctor public MenuHostHelper(Runnable);
+    method public void addMenuProvider(androidx.core.view.MenuProvider);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner);
+    method public void addMenuProvider(androidx.core.view.MenuProvider, androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State);
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public void onPrepareMenu(android.view.Menu);
+    method public void removeMenuProvider(androidx.core.view.MenuProvider);
+  }
+
+  public final class MenuItemCompat {
+    method @Deprecated public static boolean collapseActionView(android.view.MenuItem!);
+    method @Deprecated public static boolean expandActionView(android.view.MenuItem!);
+    method public static androidx.core.view.ActionProvider? getActionProvider(android.view.MenuItem);
+    method @Deprecated public static android.view.View! getActionView(android.view.MenuItem!);
+    method public static int getAlphabeticModifiers(android.view.MenuItem);
+    method public static CharSequence? getContentDescription(android.view.MenuItem);
+    method public static android.content.res.ColorStateList? getIconTintList(android.view.MenuItem);
+    method public static android.graphics.PorterDuff.Mode? getIconTintMode(android.view.MenuItem);
+    method public static int getNumericModifiers(android.view.MenuItem);
+    method public static CharSequence? getTooltipText(android.view.MenuItem);
+    method @Deprecated public static boolean isActionViewExpanded(android.view.MenuItem!);
+    method public static android.view.MenuItem? setActionProvider(android.view.MenuItem, androidx.core.view.ActionProvider?);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, android.view.View!);
+    method @Deprecated public static android.view.MenuItem! setActionView(android.view.MenuItem!, int);
+    method public static void setAlphabeticShortcut(android.view.MenuItem, char, int);
+    method public static void setContentDescription(android.view.MenuItem, CharSequence?);
+    method public static void setIconTintList(android.view.MenuItem, android.content.res.ColorStateList?);
+    method public static void setIconTintMode(android.view.MenuItem, android.graphics.PorterDuff.Mode?);
+    method public static void setNumericShortcut(android.view.MenuItem, char, int);
+    method @Deprecated public static android.view.MenuItem! setOnActionExpandListener(android.view.MenuItem!, androidx.core.view.MenuItemCompat.OnActionExpandListener!);
+    method public static void setShortcut(android.view.MenuItem, char, char, int, int);
+    method @Deprecated public static void setShowAsAction(android.view.MenuItem!, int);
+    method public static void setTooltipText(android.view.MenuItem, CharSequence?);
+    field @Deprecated public static final int SHOW_AS_ACTION_ALWAYS = 2; // 0x2
+    field @Deprecated public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8; // 0x8
+    field @Deprecated public static final int SHOW_AS_ACTION_IF_ROOM = 1; // 0x1
+    field @Deprecated public static final int SHOW_AS_ACTION_NEVER = 0; // 0x0
+    field @Deprecated public static final int SHOW_AS_ACTION_WITH_TEXT = 4; // 0x4
+  }
+
+  @Deprecated public static interface MenuItemCompat.OnActionExpandListener {
+    method @Deprecated public boolean onMenuItemActionCollapse(android.view.MenuItem!);
+    method @Deprecated public boolean onMenuItemActionExpand(android.view.MenuItem!);
+  }
+
+  public interface MenuProvider {
+    method public void onCreateMenu(android.view.Menu, android.view.MenuInflater);
+    method public default void onMenuClosed(android.view.Menu);
+    method public boolean onMenuItemSelected(android.view.MenuItem);
+    method public default void onPrepareMenu(android.view.Menu);
+  }
+
+  public final class MotionEventCompat {
+    method @Deprecated public static int findPointerIndex(android.view.MotionEvent!, int);
+    method @Deprecated public static int getActionIndex(android.view.MotionEvent!);
+    method @Deprecated public static int getActionMasked(android.view.MotionEvent!);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int);
+    method @Deprecated public static float getAxisValue(android.view.MotionEvent!, int, int);
+    method @Deprecated public static int getButtonState(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerCount(android.view.MotionEvent!);
+    method @Deprecated public static int getPointerId(android.view.MotionEvent!, int);
+    method @Deprecated public static int getSource(android.view.MotionEvent!);
+    method @Deprecated public static float getX(android.view.MotionEvent!, int);
+    method @Deprecated public static float getY(android.view.MotionEvent!, int);
+    method public static boolean isFromSource(android.view.MotionEvent, int);
+    field @Deprecated public static final int ACTION_HOVER_ENTER = 9; // 0x9
+    field @Deprecated public static final int ACTION_HOVER_EXIT = 10; // 0xa
+    field @Deprecated public static final int ACTION_HOVER_MOVE = 7; // 0x7
+    field @Deprecated public static final int ACTION_MASK = 255; // 0xff
+    field @Deprecated public static final int ACTION_POINTER_DOWN = 5; // 0x5
+    field @Deprecated public static final int ACTION_POINTER_INDEX_MASK = 65280; // 0xff00
+    field @Deprecated public static final int ACTION_POINTER_INDEX_SHIFT = 8; // 0x8
+    field @Deprecated public static final int ACTION_POINTER_UP = 6; // 0x6
+    field @Deprecated public static final int ACTION_SCROLL = 8; // 0x8
+    field @Deprecated public static final int AXIS_BRAKE = 23; // 0x17
+    field @Deprecated public static final int AXIS_DISTANCE = 24; // 0x18
+    field @Deprecated public static final int AXIS_GAS = 22; // 0x16
+    field @Deprecated public static final int AXIS_GENERIC_1 = 32; // 0x20
+    field @Deprecated public static final int AXIS_GENERIC_10 = 41; // 0x29
+    field @Deprecated public static final int AXIS_GENERIC_11 = 42; // 0x2a
+    field @Deprecated public static final int AXIS_GENERIC_12 = 43; // 0x2b
+    field @Deprecated public static final int AXIS_GENERIC_13 = 44; // 0x2c
+    field @Deprecated public static final int AXIS_GENERIC_14 = 45; // 0x2d
+    field @Deprecated public static final int AXIS_GENERIC_15 = 46; // 0x2e
+    field @Deprecated public static final int AXIS_GENERIC_16 = 47; // 0x2f
+    field @Deprecated public static final int AXIS_GENERIC_2 = 33; // 0x21
+    field @Deprecated public static final int AXIS_GENERIC_3 = 34; // 0x22
+    field @Deprecated public static final int AXIS_GENERIC_4 = 35; // 0x23
+    field @Deprecated public static final int AXIS_GENERIC_5 = 36; // 0x24
+    field @Deprecated public static final int AXIS_GENERIC_6 = 37; // 0x25
+    field @Deprecated public static final int AXIS_GENERIC_7 = 38; // 0x26
+    field @Deprecated public static final int AXIS_GENERIC_8 = 39; // 0x27
+    field @Deprecated public static final int AXIS_GENERIC_9 = 40; // 0x28
+    field @Deprecated public static final int AXIS_HAT_X = 15; // 0xf
+    field @Deprecated public static final int AXIS_HAT_Y = 16; // 0x10
+    field @Deprecated public static final int AXIS_HSCROLL = 10; // 0xa
+    field @Deprecated public static final int AXIS_LTRIGGER = 17; // 0x11
+    field @Deprecated public static final int AXIS_ORIENTATION = 8; // 0x8
+    field @Deprecated public static final int AXIS_PRESSURE = 2; // 0x2
+    field public static final int AXIS_RELATIVE_X = 27; // 0x1b
+    field public static final int AXIS_RELATIVE_Y = 28; // 0x1c
+    field @Deprecated public static final int AXIS_RTRIGGER = 18; // 0x12
+    field @Deprecated public static final int AXIS_RUDDER = 20; // 0x14
+    field @Deprecated public static final int AXIS_RX = 12; // 0xc
+    field @Deprecated public static final int AXIS_RY = 13; // 0xd
+    field @Deprecated public static final int AXIS_RZ = 14; // 0xe
+    field public static final int AXIS_SCROLL = 26; // 0x1a
+    field @Deprecated public static final int AXIS_SIZE = 3; // 0x3
+    field @Deprecated public static final int AXIS_THROTTLE = 19; // 0x13
+    field @Deprecated public static final int AXIS_TILT = 25; // 0x19
+    field @Deprecated public static final int AXIS_TOOL_MAJOR = 6; // 0x6
+    field @Deprecated public static final int AXIS_TOOL_MINOR = 7; // 0x7
+    field @Deprecated public static final int AXIS_TOUCH_MAJOR = 4; // 0x4
+    field @Deprecated public static final int AXIS_TOUCH_MINOR = 5; // 0x5
+    field @Deprecated public static final int AXIS_VSCROLL = 9; // 0x9
+    field @Deprecated public static final int AXIS_WHEEL = 21; // 0x15
+    field @Deprecated public static final int AXIS_X = 0; // 0x0
+    field @Deprecated public static final int AXIS_Y = 1; // 0x1
+    field @Deprecated public static final int AXIS_Z = 11; // 0xb
+    field @Deprecated public static final int BUTTON_PRIMARY = 1; // 0x1
+  }
+
+  public interface NestedScrollingChild {
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean isNestedScrollingEnabled();
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public void stopNestedScroll();
+  }
+
+  public interface NestedScrollingChild2 extends androidx.core.view.NestedScrollingChild {
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingChild3 extends androidx.core.view.NestedScrollingChild2 {
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+  }
+
+  public class NestedScrollingChildHelper {
+    ctor public NestedScrollingChildHelper(android.view.View);
+    method public boolean dispatchNestedFling(float, float, boolean);
+    method public boolean dispatchNestedPreFling(float, float);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?);
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]?);
+    method public boolean hasNestedScrollingParent();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isNestedScrollingEnabled();
+    method public void onDetachedFromWindow();
+    method public void onStopNestedScroll(android.view.View);
+    method public void setNestedScrollingEnabled(boolean);
+    method public boolean startNestedScroll(int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll();
+    method public void stopNestedScroll(int);
+  }
+
+  public interface NestedScrollingParent {
+    method public int getNestedScrollAxes();
+    method public boolean onNestedFling(android.view.View, float, float, boolean);
+    method public boolean onNestedPreFling(android.view.View, float, float);
+    method public void onNestedPreScroll(android.view.View, int, int, int[]);
+    method public void onNestedScroll(android.view.View, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int);
+    method public void onStopNestedScroll(android.view.View);
+  }
+
+  public interface NestedScrollingParent2 extends androidx.core.view.NestedScrollingParent {
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface NestedScrollingParent3 extends androidx.core.view.NestedScrollingParent2 {
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+  }
+
+  public class NestedScrollingParentHelper {
+    ctor public NestedScrollingParentHelper(android.view.ViewGroup);
+    method public int getNestedScrollAxes();
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View);
+    method public void onStopNestedScroll(android.view.View, int);
+  }
+
+  public interface OnApplyWindowInsetsListener {
+    method public androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+  }
+
+  public interface OnReceiveContentListener {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+  }
+
+  public interface OnReceiveContentViewBehavior {
+    method public androidx.core.view.ContentInfoCompat? onReceiveContent(androidx.core.view.ContentInfoCompat);
+  }
+
+  public final class OneShotPreDrawListener implements android.view.View.OnAttachStateChangeListener android.view.ViewTreeObserver.OnPreDrawListener {
+    method public static androidx.core.view.OneShotPreDrawListener add(android.view.View, Runnable);
+    method public boolean onPreDraw();
+    method public void onViewAttachedToWindow(android.view.View);
+    method public void onViewDetachedFromWindow(android.view.View);
+    method public void removeListener();
+  }
+
+  public final class PointerIconCompat {
+    method public static androidx.core.view.PointerIconCompat create(android.graphics.Bitmap, float, float);
+    method public static androidx.core.view.PointerIconCompat getSystemIcon(android.content.Context, int);
+    method public static androidx.core.view.PointerIconCompat load(android.content.res.Resources, int);
+    field public static final int TYPE_ALIAS = 1010; // 0x3f2
+    field public static final int TYPE_ALL_SCROLL = 1013; // 0x3f5
+    field public static final int TYPE_ARROW = 1000; // 0x3e8
+    field public static final int TYPE_CELL = 1006; // 0x3ee
+    field public static final int TYPE_CONTEXT_MENU = 1001; // 0x3e9
+    field public static final int TYPE_COPY = 1011; // 0x3f3
+    field public static final int TYPE_CROSSHAIR = 1007; // 0x3ef
+    field public static final int TYPE_DEFAULT = 1000; // 0x3e8
+    field public static final int TYPE_GRAB = 1020; // 0x3fc
+    field public static final int TYPE_GRABBING = 1021; // 0x3fd
+    field public static final int TYPE_HAND = 1002; // 0x3ea
+    field public static final int TYPE_HELP = 1003; // 0x3eb
+    field public static final int TYPE_HORIZONTAL_DOUBLE_ARROW = 1014; // 0x3f6
+    field public static final int TYPE_NO_DROP = 1012; // 0x3f4
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_TEXT = 1008; // 0x3f0
+    field public static final int TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW = 1017; // 0x3f9
+    field public static final int TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW = 1016; // 0x3f8
+    field public static final int TYPE_VERTICAL_DOUBLE_ARROW = 1015; // 0x3f7
+    field public static final int TYPE_VERTICAL_TEXT = 1009; // 0x3f1
+    field public static final int TYPE_WAIT = 1004; // 0x3ec
+    field public static final int TYPE_ZOOM_IN = 1018; // 0x3fa
+    field public static final int TYPE_ZOOM_OUT = 1019; // 0x3fb
+  }
+
+  public final class ScaleGestureDetectorCompat {
+    method public static boolean isQuickScaleEnabled(android.view.ScaleGestureDetector);
+    method @Deprecated public static boolean isQuickScaleEnabled(Object!);
+    method public static void setQuickScaleEnabled(android.view.ScaleGestureDetector, boolean);
+    method @Deprecated public static void setQuickScaleEnabled(Object!, boolean);
+  }
+
+  public interface ScrollingView {
+    method public int computeHorizontalScrollExtent();
+    method public int computeHorizontalScrollOffset();
+    method public int computeHorizontalScrollRange();
+    method public int computeVerticalScrollExtent();
+    method public int computeVerticalScrollOffset();
+    method public int computeVerticalScrollRange();
+  }
+
+  public final class SoftwareKeyboardControllerCompat {
+    ctor public SoftwareKeyboardControllerCompat(android.view.View);
+    method public void hide();
+    method public void show();
+  }
+
+  public interface TintableBackgroundView {
+    method public android.content.res.ColorStateList? getSupportBackgroundTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportBackgroundTintMode();
+    method public void setSupportBackgroundTintList(android.content.res.ColorStateList?);
+    method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  @Deprecated public final class VelocityTrackerCompat {
+    method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
+    method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+  }
+
+  public class ViewCompat {
+    ctor @Deprecated protected ViewCompat();
+    method public static int addAccessibilityAction(android.view.View, CharSequence, androidx.core.view.accessibility.AccessibilityViewCommand);
+    method public static void addKeyboardNavigationClusters(android.view.View, java.util.Collection<android.view.View!>, int);
+    method public static void addOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static androidx.core.view.ViewPropertyAnimatorCompat animate(android.view.View);
+    method @Deprecated public static boolean canScrollHorizontally(android.view.View!, int);
+    method @Deprecated public static boolean canScrollVertically(android.view.View!, int);
+    method public static void cancelDragAndDrop(android.view.View);
+    method @Deprecated public static int combineMeasuredStates(int, int);
+    method public static androidx.core.view.WindowInsetsCompat computeSystemWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat, android.graphics.Rect);
+    method public static androidx.core.view.WindowInsetsCompat dispatchApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method public static void dispatchFinishTemporaryDetach(android.view.View);
+    method public static boolean dispatchNestedFling(android.view.View, float, float, boolean);
+    method public static boolean dispatchNestedPreFling(android.view.View, float, float);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?);
+    method public static boolean dispatchNestedPreScroll(android.view.View, int, int, int[]?, int[]?, int);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?);
+    method public static boolean dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int);
+    method public static void dispatchNestedScroll(android.view.View, int, int, int, int, int[]?, int, int[]);
+    method public static void dispatchStartTemporaryDetach(android.view.View);
+    method public static void enableAccessibleClickableSpanSupport(android.view.View);
+    method public static int generateViewId();
+    method public static androidx.core.view.AccessibilityDelegateCompat? getAccessibilityDelegate(android.view.View);
+    method public static int getAccessibilityLiveRegion(android.view.View);
+    method public static androidx.core.view.accessibility.AccessibilityNodeProviderCompat? getAccessibilityNodeProvider(android.view.View);
+    method @UiThread public static CharSequence? getAccessibilityPaneTitle(android.view.View);
+    method @Deprecated public static float getAlpha(android.view.View!);
+    method public static androidx.core.view.autofill.AutofillIdCompat? getAutofillId(android.view.View);
+    method public static android.content.res.ColorStateList? getBackgroundTintList(android.view.View);
+    method public static android.graphics.PorterDuff.Mode? getBackgroundTintMode(android.view.View);
+    method public static android.graphics.Rect? getClipBounds(android.view.View);
+    method public static androidx.core.view.contentcapture.ContentCaptureSessionCompat? getContentCaptureSession(android.view.View);
+    method public static android.view.Display? getDisplay(android.view.View);
+    method public static float getElevation(android.view.View);
+    method public static boolean getFitsSystemWindows(android.view.View);
+    method public static int getImportantForAccessibility(android.view.View);
+    method public static int getImportantForAutofill(android.view.View);
+    method public static int getImportantForContentCapture(android.view.View);
+    method public static int getLabelFor(android.view.View);
+    method @Deprecated public static int getLayerType(android.view.View!);
+    method public static int getLayoutDirection(android.view.View);
+    method @Deprecated public static android.graphics.Matrix? getMatrix(android.view.View!);
+    method @Deprecated public static int getMeasuredHeightAndState(android.view.View!);
+    method @Deprecated public static int getMeasuredState(android.view.View!);
+    method @Deprecated public static int getMeasuredWidthAndState(android.view.View!);
+    method public static int getMinimumHeight(android.view.View);
+    method public static int getMinimumWidth(android.view.View);
+    method public static int getNextClusterForwardId(android.view.View);
+    method public static String![]? getOnReceiveContentMimeTypes(android.view.View);
+    method @Deprecated public static int getOverScrollMode(android.view.View!);
+    method @Px public static int getPaddingEnd(android.view.View);
+    method @Px public static int getPaddingStart(android.view.View);
+    method public static android.view.ViewParent? getParentForAccessibility(android.view.View);
+    method @Deprecated public static float getPivotX(android.view.View!);
+    method @Deprecated public static float getPivotY(android.view.View!);
+    method public static androidx.core.view.WindowInsetsCompat? getRootWindowInsets(android.view.View);
+    method @Deprecated public static float getRotation(android.view.View!);
+    method @Deprecated public static float getRotationX(android.view.View!);
+    method @Deprecated public static float getRotationY(android.view.View!);
+    method @Deprecated public static float getScaleX(android.view.View!);
+    method @Deprecated public static float getScaleY(android.view.View!);
+    method public static int getScrollIndicators(android.view.View);
+    method @UiThread public static CharSequence? getStateDescription(android.view.View);
+    method public static java.util.List<android.graphics.Rect!> getSystemGestureExclusionRects(android.view.View);
+    method public static String? getTransitionName(android.view.View);
+    method @Deprecated public static float getTranslationX(android.view.View!);
+    method @Deprecated public static float getTranslationY(android.view.View!);
+    method public static float getTranslationZ(android.view.View);
+    method @Deprecated public static androidx.core.view.WindowInsetsControllerCompat? getWindowInsetsController(android.view.View);
+    method @Deprecated public static int getWindowSystemUiVisibility(android.view.View);
+    method @Deprecated public static float getX(android.view.View!);
+    method @Deprecated public static float getY(android.view.View!);
+    method public static float getZ(android.view.View);
+    method public static boolean hasAccessibilityDelegate(android.view.View);
+    method public static boolean hasExplicitFocusable(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View);
+    method public static boolean hasNestedScrollingParent(android.view.View, int);
+    method public static boolean hasOnClickListeners(android.view.View);
+    method public static boolean hasOverlappingRendering(android.view.View);
+    method public static boolean hasTransientState(android.view.View);
+    method @UiThread public static boolean isAccessibilityHeading(android.view.View);
+    method public static boolean isAttachedToWindow(android.view.View);
+    method public static boolean isFocusedByDefault(android.view.View);
+    method public static boolean isImportantForAccessibility(android.view.View);
+    method public static boolean isImportantForAutofill(android.view.View);
+    method public static boolean isImportantForContentCapture(android.view.View);
+    method public static boolean isInLayout(android.view.View);
+    method public static boolean isKeyboardNavigationCluster(android.view.View);
+    method public static boolean isLaidOut(android.view.View);
+    method public static boolean isLayoutDirectionResolved(android.view.View);
+    method public static boolean isNestedScrollingEnabled(android.view.View);
+    method @Deprecated public static boolean isOpaque(android.view.View!);
+    method public static boolean isPaddingRelative(android.view.View);
+    method @UiThread public static boolean isScreenReaderFocusable(android.view.View);
+    method @Deprecated public static void jumpDrawablesToCurrentState(android.view.View!);
+    method public static android.view.View? keyboardNavigationClusterSearch(android.view.View, android.view.View?, int);
+    method public static void offsetLeftAndRight(android.view.View, int);
+    method public static void offsetTopAndBottom(android.view.View, int);
+    method public static androidx.core.view.WindowInsetsCompat onApplyWindowInsets(android.view.View, androidx.core.view.WindowInsetsCompat);
+    method @Deprecated public static void onInitializeAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
+    method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+    method public static boolean performHapticFeedback(android.view.View, int);
+    method public static boolean performHapticFeedback(android.view.View, int, int);
+    method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
+    method public static void postInvalidateOnAnimation(android.view.View);
+    method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
+    method public static void postOnAnimation(android.view.View, Runnable);
+    method public static void postOnAnimationDelayed(android.view.View, Runnable, long);
+    method public static void removeAccessibilityAction(android.view.View, int);
+    method public static void removeOnUnhandledKeyEventListener(android.view.View, androidx.core.view.ViewCompat.OnUnhandledKeyEventListenerCompat);
+    method public static void replaceAccessibilityAction(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat, CharSequence?, androidx.core.view.accessibility.AccessibilityViewCommand?);
+    method public static void requestApplyInsets(android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.View, @IdRes int);
+    method @Deprecated public static int resolveSizeAndState(int, int, int);
+    method public static boolean restoreDefaultFocus(android.view.View);
+    method public static void saveAttributeDataForStyleable(android.view.View, android.content.Context, int[], android.util.AttributeSet?, android.content.res.TypedArray, int, int);
+    method public static void setAccessibilityDelegate(android.view.View, androidx.core.view.AccessibilityDelegateCompat?);
+    method @UiThread public static void setAccessibilityHeading(android.view.View, boolean);
+    method public static void setAccessibilityLiveRegion(android.view.View, int);
+    method @UiThread public static void setAccessibilityPaneTitle(android.view.View, CharSequence?);
+    method @Deprecated public static void setActivated(android.view.View!, boolean);
+    method @Deprecated public static void setAlpha(android.view.View!, @FloatRange(from=0.0, to=1.0) float);
+    method public static void setAutofillHints(android.view.View, java.lang.String!...);
+    method public static void setAutofillId(android.view.View, androidx.core.view.autofill.AutofillIdCompat?);
+    method public static void setBackground(android.view.View, android.graphics.drawable.Drawable?);
+    method public static void setBackgroundTintList(android.view.View, android.content.res.ColorStateList?);
+    method public static void setBackgroundTintMode(android.view.View, android.graphics.PorterDuff.Mode?);
+    method @Deprecated public static void setChildrenDrawingOrderEnabled(android.view.ViewGroup!, boolean);
+    method public static void setClipBounds(android.view.View, android.graphics.Rect?);
+    method public static void setContentCaptureSession(android.view.View, androidx.core.view.contentcapture.ContentCaptureSessionCompat?);
+    method public static void setElevation(android.view.View, float);
+    method @Deprecated public static void setFitsSystemWindows(android.view.View!, boolean);
+    method public static void setFocusedByDefault(android.view.View, boolean);
+    method public static void setHasTransientState(android.view.View, boolean);
+    method @UiThread public static void setImportantForAccessibility(android.view.View, int);
+    method public static void setImportantForAutofill(android.view.View, int);
+    method public static void setImportantForContentCapture(android.view.View, int);
+    method public static void setKeyboardNavigationCluster(android.view.View, boolean);
+    method public static void setLabelFor(android.view.View, @IdRes int);
+    method public static void setLayerPaint(android.view.View, android.graphics.Paint?);
+    method @Deprecated public static void setLayerType(android.view.View!, int, android.graphics.Paint!);
+    method public static void setLayoutDirection(android.view.View, int);
+    method public static void setNestedScrollingEnabled(android.view.View, boolean);
+    method public static void setNextClusterForwardId(android.view.View, int);
+    method public static void setOnApplyWindowInsetsListener(android.view.View, androidx.core.view.OnApplyWindowInsetsListener?);
+    method public static void setOnReceiveContentListener(android.view.View, String![]?, androidx.core.view.OnReceiveContentListener?);
+    method @Deprecated public static void setOverScrollMode(android.view.View!, int);
+    method public static void setPaddingRelative(android.view.View, @Px int, @Px int, @Px int, @Px int);
+    method @Deprecated public static void setPivotX(android.view.View!, float);
+    method @Deprecated public static void setPivotY(android.view.View!, float);
+    method public static void setPointerIcon(android.view.View, androidx.core.view.PointerIconCompat?);
+    method @Deprecated public static void setRotation(android.view.View!, float);
+    method @Deprecated public static void setRotationX(android.view.View!, float);
+    method @Deprecated public static void setRotationY(android.view.View!, float);
+    method @Deprecated public static void setSaveFromParentEnabled(android.view.View!, boolean);
+    method @Deprecated public static void setScaleX(android.view.View!, float);
+    method @Deprecated public static void setScaleY(android.view.View!, float);
+    method @UiThread public static void setScreenReaderFocusable(android.view.View, boolean);
+    method public static void setScrollIndicators(android.view.View, int);
+    method public static void setScrollIndicators(android.view.View, int, int);
+    method @UiThread public static void setStateDescription(android.view.View, CharSequence?);
+    method public static void setSystemGestureExclusionRects(android.view.View, java.util.List<android.graphics.Rect!>);
+    method public static void setTooltipText(android.view.View, CharSequence?);
+    method public static void setTransitionName(android.view.View, String?);
+    method @Deprecated public static void setTranslationX(android.view.View!, float);
+    method @Deprecated public static void setTranslationY(android.view.View!, float);
+    method public static void setTranslationZ(android.view.View, float);
+    method public static void setWindowInsetsAnimationCallback(android.view.View, androidx.core.view.WindowInsetsAnimationCompat.Callback?);
+    method @Deprecated public static void setX(android.view.View!, float);
+    method @Deprecated public static void setY(android.view.View!, float);
+    method public static void setZ(android.view.View, float);
+    method public static boolean startDragAndDrop(android.view.View, android.content.ClipData?, android.view.View.DragShadowBuilder, Object?, int);
+    method public static boolean startNestedScroll(android.view.View, int);
+    method public static boolean startNestedScroll(android.view.View, int, int);
+    method public static void stopNestedScroll(android.view.View);
+    method public static void stopNestedScroll(android.view.View, int);
+    method public static void updateDragShadow(android.view.View, android.view.View.DragShadowBuilder);
+    field public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 2; // 0x2
+    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
+    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 4; // 0x4
+    field public static final int IMPORTANT_FOR_ACCESSIBILITY_YES = 1; // 0x1
+    field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0; // 0x0
+    field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 2; // 0x2
+    field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 8; // 0x8
+    field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 1; // 0x1
+    field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 4; // 0x4
+    field @Deprecated public static final int LAYER_TYPE_HARDWARE = 2; // 0x2
+    field @Deprecated public static final int LAYER_TYPE_NONE = 0; // 0x0
+    field @Deprecated public static final int LAYER_TYPE_SOFTWARE = 1; // 0x1
+    field public static final int LAYOUT_DIRECTION_INHERIT = 2; // 0x2
+    field public static final int LAYOUT_DIRECTION_LOCALE = 3; // 0x3
+    field public static final int LAYOUT_DIRECTION_LTR = 0; // 0x0
+    field public static final int LAYOUT_DIRECTION_RTL = 1; // 0x1
+    field @Deprecated public static final int MEASURED_HEIGHT_STATE_SHIFT = 16; // 0x10
+    field @Deprecated public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
+    field @Deprecated public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
+    field @Deprecated public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
+    field @Deprecated public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
+    field @Deprecated public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
+    field @Deprecated public static final int OVER_SCROLL_NEVER = 2; // 0x2
+    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
+    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
+    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
+    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
+    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
+    field public static final int SCROLL_INDICATOR_RIGHT = 8; // 0x8
+    field public static final int SCROLL_INDICATOR_START = 16; // 0x10
+    field public static final int SCROLL_INDICATOR_TOP = 1; // 0x1
+    field public static final int TYPE_NON_TOUCH = 1; // 0x1
+    field public static final int TYPE_TOUCH = 0; // 0x0
+  }
+
+  public static interface ViewCompat.OnUnhandledKeyEventListenerCompat {
+    method public boolean onUnhandledKeyEvent(android.view.View, android.view.KeyEvent);
+  }
+
+  public final class ViewConfigurationCompat {
+    method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
+    method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
+    method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
+    method public static boolean shouldShowMenuShortcutsWhenKeyboardPresent(android.view.ViewConfiguration, android.content.Context);
+  }
+
+  public final class ViewGroupCompat {
+    method public static int getLayoutMode(android.view.ViewGroup);
+    method public static int getNestedScrollAxes(android.view.ViewGroup);
+    method public static boolean isTransitionGroup(android.view.ViewGroup);
+    method @Deprecated public static boolean onRequestSendAccessibilityEvent(android.view.ViewGroup!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+    method public static void setLayoutMode(android.view.ViewGroup, int);
+    method @Deprecated public static void setMotionEventSplittingEnabled(android.view.ViewGroup!, boolean);
+    method public static void setTransitionGroup(android.view.ViewGroup, boolean);
+    field public static final int LAYOUT_MODE_CLIP_BOUNDS = 0; // 0x0
+    field public static final int LAYOUT_MODE_OPTICAL_BOUNDS = 1; // 0x1
+  }
+
+  public final class ViewParentCompat {
+    method public static void notifySubtreeAccessibilityStateChanged(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onNestedFling(android.view.ViewParent, android.view.View, float, float, boolean);
+    method public static boolean onNestedPreFling(android.view.ViewParent, android.view.View, float, float);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[]);
+    method public static void onNestedPreScroll(android.view.ViewParent, android.view.View, int, int, int[], int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int);
+    method public static void onNestedScroll(android.view.ViewParent, android.view.View, int, int, int, int, int, int[]);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static void onNestedScrollAccepted(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int);
+    method public static boolean onStartNestedScroll(android.view.ViewParent, android.view.View, android.view.View, int, int);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View);
+    method public static void onStopNestedScroll(android.view.ViewParent, android.view.View, int);
+    method @Deprecated public static boolean requestSendAccessibilityEvent(android.view.ViewParent!, android.view.View!, android.view.accessibility.AccessibilityEvent!);
+  }
+
+  public final class ViewPropertyAnimatorCompat {
+    method public androidx.core.view.ViewPropertyAnimatorCompat alpha(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat alphaBy(float);
+    method public void cancel();
+    method public long getDuration();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public long getStartDelay();
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotation(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat rotationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat scaleYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setDuration(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setInterpolator(android.view.animation.Interpolator?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setListener(androidx.core.view.ViewPropertyAnimatorListener?);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setStartDelay(long);
+    method public androidx.core.view.ViewPropertyAnimatorCompat setUpdateListener(androidx.core.view.ViewPropertyAnimatorUpdateListener?);
+    method public void start();
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationX(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationXBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationY(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationYBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZ(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat translationZBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withEndAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat withLayer();
+    method public androidx.core.view.ViewPropertyAnimatorCompat withStartAction(Runnable);
+    method public androidx.core.view.ViewPropertyAnimatorCompat x(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat xBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat y(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat yBy(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat z(float);
+    method public androidx.core.view.ViewPropertyAnimatorCompat zBy(float);
+  }
+
+  public interface ViewPropertyAnimatorListener {
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public class ViewPropertyAnimatorListenerAdapter implements androidx.core.view.ViewPropertyAnimatorListener {
+    ctor public ViewPropertyAnimatorListenerAdapter();
+    method public void onAnimationCancel(android.view.View);
+    method public void onAnimationEnd(android.view.View);
+    method public void onAnimationStart(android.view.View);
+  }
+
+  public interface ViewPropertyAnimatorUpdateListener {
+    method public void onAnimationUpdate(android.view.View);
+  }
+
+  public class ViewStructureCompat {
+    method public void setClassName(String);
+    method public void setContentDescription(CharSequence);
+    method public void setDimens(int, int, int, int, int, int);
+    method public void setText(CharSequence);
+    method @RequiresApi(23) public android.view.ViewStructure toViewStructure();
+    method @RequiresApi(23) public static androidx.core.view.ViewStructureCompat toViewStructureCompat(android.view.ViewStructure);
+  }
+
+  public final class WindowCompat {
+    method public static androidx.core.view.WindowInsetsControllerCompat getInsetsController(android.view.Window, android.view.View);
+    method public static <T extends android.view.View> T requireViewById(android.view.Window, @IdRes int);
+    method public static void setDecorFitsSystemWindows(android.view.Window, boolean);
+    field public static final int FEATURE_ACTION_BAR = 8; // 0x8
+    field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
+    field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+  }
+
+  public final class WindowInsetsAnimationCompat {
+    ctor public WindowInsetsAnimationCompat(int, android.view.animation.Interpolator?, long);
+    method @FloatRange(from=0.0f, to=1.0f) public float getAlpha();
+    method public long getDurationMillis();
+    method @FloatRange(from=0.0f, to=1.0f) public float getFraction();
+    method public float getInterpolatedFraction();
+    method public android.view.animation.Interpolator? getInterpolator();
+    method public int getTypeMask();
+    method public void setAlpha(@FloatRange(from=0.0f, to=1.0f) float);
+    method public void setFraction(@FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public static final class WindowInsetsAnimationCompat.BoundsCompat {
+    ctor public WindowInsetsAnimationCompat.BoundsCompat(androidx.core.graphics.Insets, androidx.core.graphics.Insets);
+    method public androidx.core.graphics.Insets getLowerBound();
+    method public androidx.core.graphics.Insets getUpperBound();
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat inset(androidx.core.graphics.Insets);
+    method @RequiresApi(30) public android.view.WindowInsetsAnimation.Bounds toBounds();
+    method @RequiresApi(30) public static androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat toBoundsCompat(android.view.WindowInsetsAnimation.Bounds);
+  }
+
+  public abstract static class WindowInsetsAnimationCompat.Callback {
+    ctor public WindowInsetsAnimationCompat.Callback(int);
+    method public final int getDispatchMode();
+    method public void onEnd(androidx.core.view.WindowInsetsAnimationCompat);
+    method public void onPrepare(androidx.core.view.WindowInsetsAnimationCompat);
+    method public abstract androidx.core.view.WindowInsetsCompat onProgress(androidx.core.view.WindowInsetsCompat, java.util.List<androidx.core.view.WindowInsetsAnimationCompat!>);
+    method public androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat onStart(androidx.core.view.WindowInsetsAnimationCompat, androidx.core.view.WindowInsetsAnimationCompat.BoundsCompat);
+    field public static final int DISPATCH_MODE_CONTINUE_ON_SUBTREE = 1; // 0x1
+    field public static final int DISPATCH_MODE_STOP = 0; // 0x0
+  }
+
+  public interface WindowInsetsAnimationControlListenerCompat {
+    method public void onCancelled(androidx.core.view.WindowInsetsAnimationControllerCompat?);
+    method public void onFinished(androidx.core.view.WindowInsetsAnimationControllerCompat);
+    method public void onReady(androidx.core.view.WindowInsetsAnimationControllerCompat, int);
+  }
+
+  public final class WindowInsetsAnimationControllerCompat {
+    method public void finish(boolean);
+    method public float getCurrentAlpha();
+    method @FloatRange(from=0.0f, to=1.0f) public float getCurrentFraction();
+    method public androidx.core.graphics.Insets getCurrentInsets();
+    method public androidx.core.graphics.Insets getHiddenStateInsets();
+    method public androidx.core.graphics.Insets getShownStateInsets();
+    method public int getTypes();
+    method public boolean isCancelled();
+    method public boolean isFinished();
+    method public boolean isReady();
+    method public void setInsetsAndAlpha(androidx.core.graphics.Insets?, @FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
+  }
+
+  public class WindowInsetsCompat {
+    ctor public WindowInsetsCompat(androidx.core.view.WindowInsetsCompat?);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeDisplayCutout();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeStableInsets();
+    method @Deprecated public androidx.core.view.WindowInsetsCompat consumeSystemWindowInsets();
+    method public androidx.core.view.DisplayCutoutCompat? getDisplayCutout();
+    method public androidx.core.graphics.Insets getInsets(int);
+    method public androidx.core.graphics.Insets getInsetsIgnoringVisibility(int);
+    method @Deprecated public androidx.core.graphics.Insets getMandatorySystemGestureInsets();
+    method @Deprecated public int getStableInsetBottom();
+    method @Deprecated public int getStableInsetLeft();
+    method @Deprecated public int getStableInsetRight();
+    method @Deprecated public int getStableInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getStableInsets();
+    method @Deprecated public androidx.core.graphics.Insets getSystemGestureInsets();
+    method @Deprecated public int getSystemWindowInsetBottom();
+    method @Deprecated public int getSystemWindowInsetLeft();
+    method @Deprecated public int getSystemWindowInsetRight();
+    method @Deprecated public int getSystemWindowInsetTop();
+    method @Deprecated public androidx.core.graphics.Insets getSystemWindowInsets();
+    method @Deprecated public androidx.core.graphics.Insets getTappableElementInsets();
+    method public boolean hasInsets();
+    method @Deprecated public boolean hasStableInsets();
+    method @Deprecated public boolean hasSystemWindowInsets();
+    method public androidx.core.view.WindowInsetsCompat inset(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat inset(@IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int);
+    method public boolean isConsumed();
+    method public boolean isRound();
+    method public boolean isVisible(int);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(android.graphics.Rect);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat replaceSystemWindowInsets(int, int, int, int);
+    method @RequiresApi(20) public android.view.WindowInsets? toWindowInsets();
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets);
+    method @RequiresApi(20) public static androidx.core.view.WindowInsetsCompat toWindowInsetsCompat(android.view.WindowInsets, android.view.View?);
+    field public static final androidx.core.view.WindowInsetsCompat CONSUMED;
+  }
+
+  public static final class WindowInsetsCompat.Builder {
+    ctor public WindowInsetsCompat.Builder();
+    ctor public WindowInsetsCompat.Builder(androidx.core.view.WindowInsetsCompat);
+    method public androidx.core.view.WindowInsetsCompat build();
+    method public androidx.core.view.WindowInsetsCompat.Builder setDisplayCutout(androidx.core.view.DisplayCutoutCompat?);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsets(int, androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setInsetsIgnoringVisibility(int, androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setMandatorySystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setStableInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemGestureInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setSystemWindowInsets(androidx.core.graphics.Insets);
+    method @Deprecated public androidx.core.view.WindowInsetsCompat.Builder setTappableElementInsets(androidx.core.graphics.Insets);
+    method public androidx.core.view.WindowInsetsCompat.Builder setVisible(int, boolean);
+  }
+
+  public static final class WindowInsetsCompat.Type {
+    method public static int captionBar();
+    method public static int displayCutout();
+    method public static int ime();
+    method public static int mandatorySystemGestures();
+    method public static int navigationBars();
+    method public static int statusBars();
+    method public static int systemBars();
+    method public static int systemGestures();
+    method public static int tappableElement();
+  }
+
+  public final class WindowInsetsControllerCompat {
+    ctor public WindowInsetsControllerCompat(android.view.Window, android.view.View);
+    method public void addOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void controlWindowInsetsAnimation(int, long, android.view.animation.Interpolator?, android.os.CancellationSignal?, androidx.core.view.WindowInsetsAnimationControlListenerCompat);
+    method public int getSystemBarsBehavior();
+    method public void hide(int);
+    method public boolean isAppearanceLightNavigationBars();
+    method public boolean isAppearanceLightStatusBars();
+    method public void removeOnControllableInsetsChangedListener(androidx.core.view.WindowInsetsControllerCompat.OnControllableInsetsChangedListener);
+    method public void setAppearanceLightNavigationBars(boolean);
+    method public void setAppearanceLightStatusBars(boolean);
+    method public void setSystemBarsBehavior(int);
+    method public void show(int);
+    method @Deprecated @RequiresApi(30) public static androidx.core.view.WindowInsetsControllerCompat toWindowInsetsControllerCompat(android.view.WindowInsetsController);
+    field public static final int BEHAVIOR_DEFAULT = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_SWIPE = 1; // 0x1
+    field @Deprecated public static final int BEHAVIOR_SHOW_BARS_BY_TOUCH = 0; // 0x0
+    field public static final int BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE = 2; // 0x2
+  }
+
+  public static interface WindowInsetsControllerCompat.OnControllableInsetsChangedListener {
+    method public void onControllableInsetsChanged(androidx.core.view.WindowInsetsControllerCompat, int);
+  }
+
+}
+
+package androidx.core.view.accessibility {
+
+  public final class AccessibilityClickableSpanCompat extends android.text.style.ClickableSpan {
+    method public void onClick(android.view.View);
+  }
+
+  public final class AccessibilityEventCompat {
+    method @Deprecated public static void appendRecord(android.view.accessibility.AccessibilityEvent!, androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! asRecord(android.view.accessibility.AccessibilityEvent!);
+    method public static int getAction(android.view.accessibility.AccessibilityEvent);
+    method public static int getContentChangeTypes(android.view.accessibility.AccessibilityEvent);
+    method public static int getMovementGranularity(android.view.accessibility.AccessibilityEvent);
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! getRecord(android.view.accessibility.AccessibilityEvent!, int);
+    method @Deprecated public static int getRecordCount(android.view.accessibility.AccessibilityEvent!);
+    method public static void setAction(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setContentChangeTypes(android.view.accessibility.AccessibilityEvent, int);
+    method public static void setMovementGranularity(android.view.accessibility.AccessibilityEvent, int);
+    field public static final int CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION = 4; // 0x4
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_CANCELLED = 512; // 0x200
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_DROPPED = 256; // 0x100
+    field public static final int CONTENT_CHANGE_TYPE_DRAG_STARTED = 128; // 0x80
+    field public static final int CONTENT_CHANGE_TYPE_PANE_APPEARED = 16; // 0x10
+    field public static final int CONTENT_CHANGE_TYPE_PANE_DISAPPEARED = 32; // 0x20
+    field public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 8; // 0x8
+    field public static final int CONTENT_CHANGE_TYPE_STATE_DESCRIPTION = 64; // 0x40
+    field public static final int CONTENT_CHANGE_TYPE_SUBTREE = 1; // 0x1
+    field public static final int CONTENT_CHANGE_TYPE_TEXT = 2; // 0x2
+    field public static final int CONTENT_CHANGE_TYPE_UNDEFINED = 0; // 0x0
+    field public static final int TYPES_ALL_MASK = -1; // 0xffffffff
+    field public static final int TYPE_ANNOUNCEMENT = 16384; // 0x4000
+    field public static final int TYPE_ASSIST_READING_CONTEXT = 16777216; // 0x1000000
+    field public static final int TYPE_GESTURE_DETECTION_END = 524288; // 0x80000
+    field public static final int TYPE_GESTURE_DETECTION_START = 262144; // 0x40000
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_END = 1024; // 0x400
+    field @Deprecated public static final int TYPE_TOUCH_EXPLORATION_GESTURE_START = 512; // 0x200
+    field public static final int TYPE_TOUCH_INTERACTION_END = 2097152; // 0x200000
+    field public static final int TYPE_TOUCH_INTERACTION_START = 1048576; // 0x100000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUSED = 32768; // 0x8000
+    field public static final int TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED = 65536; // 0x10000
+    field public static final int TYPE_VIEW_CONTEXT_CLICKED = 8388608; // 0x800000
+    field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
+    field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
+    field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
+    field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
+    field @Deprecated public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
+  }
+
+  public final class AccessibilityManagerCompat {
+    method @Deprecated public static boolean addAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean addTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getEnabledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!, int);
+    method @Deprecated public static java.util.List<android.accessibilityservice.AccessibilityServiceInfo!>! getInstalledAccessibilityServiceList(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean isTouchExplorationEnabled(android.view.accessibility.AccessibilityManager!);
+    method @Deprecated public static boolean removeAccessibilityStateChangeListener(android.view.accessibility.AccessibilityManager!, androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener!);
+    method public static boolean removeTouchExplorationStateChangeListener(android.view.accessibility.AccessibilityManager, androidx.core.view.accessibility.AccessibilityManagerCompat.TouchExplorationStateChangeListener);
+  }
+
+  @Deprecated public static interface AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    method @Deprecated public void onAccessibilityStateChanged(boolean);
+  }
+
+  @Deprecated public abstract static class AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat implements androidx.core.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListener {
+    ctor @Deprecated public AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat();
+  }
+
+  public static interface AccessibilityManagerCompat.TouchExplorationStateChangeListener {
+    method public void onTouchExplorationStateChanged(boolean);
+  }
+
+  public class AccessibilityNodeInfoCompat {
+    ctor @Deprecated public AccessibilityNodeInfoCompat(Object!);
+    method public void addAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public void addAction(int);
+    method public void addChild(android.view.View!);
+    method public void addChild(android.view.View!, int);
+    method public boolean canOpenPopup();
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByText(String!);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>! findAccessibilityNodeInfosByViewId(String!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! findFocus(int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! focusSearch(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!>! getActionList();
+    method @Deprecated public int getActions();
+    method public java.util.List<java.lang.String!> getAvailableExtraData();
+    method @Deprecated public void getBoundsInParent(android.graphics.Rect!);
+    method public void getBoundsInScreen(android.graphics.Rect!);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getChild(int);
+    method public int getChildCount();
+    method public CharSequence! getClassName();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! getCollectionInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! getCollectionItemInfo();
+    method public CharSequence! getContentDescription();
+    method public int getDrawingOrder();
+    method public CharSequence! getError();
+    method public android.view.accessibility.AccessibilityNodeInfo.ExtraRenderingInfo? getExtraRenderingInfo();
+    method public android.os.Bundle! getExtras();
+    method public CharSequence? getHintText();
+    method @Deprecated public Object! getInfo();
+    method public int getInputType();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabelFor();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getLabeledBy();
+    method public int getLiveRegion();
+    method public int getMaxTextLength();
+    method public long getMinDurationBetweenContentChangesMillis();
+    method public int getMovementGranularities();
+    method public CharSequence! getPackageName();
+    method public CharSequence? getPaneTitle();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getParent();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! getRangeInfo();
+    method public CharSequence? getRoleDescription();
+    method public CharSequence? getStateDescription();
+    method public CharSequence! getText();
+    method public int getTextSelectionEnd();
+    method public int getTextSelectionStart();
+    method public CharSequence? getTooltipText();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat? getTouchDelegateInfo();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalAfter();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getTraversalBefore();
+    method public String? getUniqueId();
+    method public String! getViewIdResourceName();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat! getWindow();
+    method public int getWindowId();
+    method public boolean hasRequestInitialAccessibilityFocus();
+    method public boolean isAccessibilityFocused();
+    method public boolean isCheckable();
+    method public boolean isChecked();
+    method public boolean isClickable();
+    method public boolean isContentInvalid();
+    method public boolean isContextClickable();
+    method public boolean isDismissable();
+    method public boolean isEditable();
+    method public boolean isEnabled();
+    method public boolean isFocusable();
+    method public boolean isFocused();
+    method public boolean isHeading();
+    method public boolean isImportantForAccessibility();
+    method public boolean isLongClickable();
+    method public boolean isMultiLine();
+    method public boolean isPassword();
+    method public boolean isScreenReaderFocusable();
+    method public boolean isScrollable();
+    method public boolean isSelected();
+    method public boolean isShowingHintText();
+    method public boolean isTextEntryKey();
+    method public boolean isTextSelectable();
+    method public boolean isVisibleToUser();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(android.view.View!, int);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! obtain(androidx.core.view.accessibility.AccessibilityNodeInfoCompat!);
+    method public boolean performAction(int);
+    method public boolean performAction(int, android.os.Bundle!);
+    method @Deprecated public void recycle();
+    method public boolean refresh();
+    method public boolean removeAction(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat!);
+    method public boolean removeChild(android.view.View!);
+    method public boolean removeChild(android.view.View!, int);
+    method public void setAccessibilityFocused(boolean);
+    method public void setAvailableExtraData(java.util.List<java.lang.String!>);
+    method @Deprecated public void setBoundsInParent(android.graphics.Rect!);
+    method public void setBoundsInScreen(android.graphics.Rect!);
+    method public void setCanOpenPopup(boolean);
+    method public void setCheckable(boolean);
+    method public void setChecked(boolean);
+    method public void setClassName(CharSequence!);
+    method public void setClickable(boolean);
+    method public void setCollectionInfo(Object!);
+    method public void setCollectionItemInfo(Object!);
+    method public void setContentDescription(CharSequence!);
+    method public void setContentInvalid(boolean);
+    method public void setContextClickable(boolean);
+    method public void setDismissable(boolean);
+    method public void setDrawingOrder(int);
+    method public void setEditable(boolean);
+    method public void setEnabled(boolean);
+    method public void setError(CharSequence!);
+    method public void setFocusable(boolean);
+    method public void setFocused(boolean);
+    method public void setHeading(boolean);
+    method public void setHintText(CharSequence?);
+    method public void setImportantForAccessibility(boolean);
+    method public void setInputType(int);
+    method public void setLabelFor(android.view.View!);
+    method public void setLabelFor(android.view.View!, int);
+    method public void setLabeledBy(android.view.View!);
+    method public void setLabeledBy(android.view.View!, int);
+    method public void setLiveRegion(int);
+    method public void setLongClickable(boolean);
+    method public void setMaxTextLength(int);
+    method public void setMinDurationBetweenContentChangesMillis(long);
+    method public void setMovementGranularities(int);
+    method public void setMultiLine(boolean);
+    method public void setPackageName(CharSequence!);
+    method public void setPaneTitle(CharSequence?);
+    method public void setParent(android.view.View!);
+    method public void setParent(android.view.View!, int);
+    method public void setPassword(boolean);
+    method public void setRangeInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat!);
+    method public void setRequestInitialAccessibilityFocus(boolean);
+    method public void setRoleDescription(CharSequence?);
+    method public void setScreenReaderFocusable(boolean);
+    method public void setScrollable(boolean);
+    method public void setSelected(boolean);
+    method public void setShowingHintText(boolean);
+    method public void setSource(android.view.View!);
+    method public void setSource(android.view.View!, int);
+    method public void setStateDescription(CharSequence?);
+    method public void setText(CharSequence!);
+    method public void setTextEntryKey(boolean);
+    method public void setTextSelectable(boolean);
+    method public void setTextSelection(int, int);
+    method public void setTooltipText(CharSequence?);
+    method public void setTouchDelegateInfo(androidx.core.view.accessibility.AccessibilityNodeInfoCompat.TouchDelegateInfoCompat);
+    method public void setTraversalAfter(android.view.View!);
+    method public void setTraversalAfter(android.view.View!, int);
+    method public void setTraversalBefore(android.view.View!);
+    method public void setTraversalBefore(android.view.View!, int);
+    method public void setUniqueId(String?);
+    method public void setViewIdResourceName(String!);
+    method public void setVisibleToUser(boolean);
+    method public android.view.accessibility.AccessibilityNodeInfo! unwrap();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
+    field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
+    field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
+    field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
+    field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_X = "ACTION_ARGUMENT_MOVE_WINDOW_X";
+    field public static final String ACTION_ARGUMENT_MOVE_WINDOW_Y = "ACTION_ARGUMENT_MOVE_WINDOW_Y";
+    field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
+    field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
+    field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
+    field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+    field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
+    field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
+    field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
+    field public static final int ACTION_CLICK = 16; // 0x10
+    field public static final int ACTION_COLLAPSE = 524288; // 0x80000
+    field public static final int ACTION_COPY = 16384; // 0x4000
+    field public static final int ACTION_CUT = 65536; // 0x10000
+    field public static final int ACTION_DISMISS = 1048576; // 0x100000
+    field public static final int ACTION_EXPAND = 262144; // 0x40000
+    field public static final int ACTION_FOCUS = 1; // 0x1
+    field public static final int ACTION_LONG_CLICK = 32; // 0x20
+    field public static final int ACTION_NEXT_AT_MOVEMENT_GRANULARITY = 256; // 0x100
+    field public static final int ACTION_NEXT_HTML_ELEMENT = 1024; // 0x400
+    field public static final int ACTION_PASTE = 32768; // 0x8000
+    field public static final int ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY = 512; // 0x200
+    field public static final int ACTION_PREVIOUS_HTML_ELEMENT = 2048; // 0x800
+    field public static final int ACTION_SCROLL_BACKWARD = 8192; // 0x2000
+    field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
+    field public static final int ACTION_SELECT = 4; // 0x4
+    field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_LENGTH";
+    field public static final int EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_MAX_LENGTH = 20000; // 0x4e20
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX";
+    field public static final String EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY = "android.core.view.accessibility.extra.DATA_TEXT_CHARACTER_LOCATION_KEY";
+    field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
+    field public static final int FOCUS_INPUT = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_CHARACTER = 1; // 0x1
+    field public static final int MOVEMENT_GRANULARITY_LINE = 4; // 0x4
+    field public static final int MOVEMENT_GRANULARITY_PAGE = 16; // 0x10
+    field public static final int MOVEMENT_GRANULARITY_PARAGRAPH = 8; // 0x8
+    field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
+  }
+
+  public static class AccessibilityNodeInfoCompat.AccessibilityActionCompat {
+    ctor public AccessibilityNodeInfoCompat.AccessibilityActionCompat(int, CharSequence!);
+    method public int getId();
+    method public CharSequence! getLabel();
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_ACCESSIBILITY_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLEAR_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COLLAPSE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CONTEXT_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_COPY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_CUT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_DISMISS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_CANCEL;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_DROP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_DRAG_START;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_EXPAND;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_FOCUS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_HIDE_TOOLTIP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_IME_ENTER;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_LONG_CLICK;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_MOVE_WINDOW;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_NEXT_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PAGE_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PASTE;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_PRESS_AND_HOLD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_PREVIOUS_HTML_ELEMENT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_UP;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SELECT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_PROGRESS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_SELECTION;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SET_TEXT;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_ON_SCREEN;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SHOW_TEXT_SUGGESTIONS;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SHOW_TOOLTIP;
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionInfoCompat {
+    method public int getColumnCount();
+    method public int getRowCount();
+    method public int getSelectionMode();
+    method public boolean isHierarchical();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat! obtain(int, int, boolean, int);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
+  }
+
+  public static class AccessibilityNodeInfoCompat.CollectionItemInfoCompat {
+    method public int getColumnIndex();
+    method public int getColumnSpan();
+    method public int getRowIndex();
+    method public int getRowSpan();
+    method @Deprecated public boolean isHeading();
+    method public boolean isSelected();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean);
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat! obtain(int, int, int, int, boolean, boolean);
+  }
+
+  public static class AccessibilityNodeInfoCompat.RangeInfoCompat {
+    method public float getCurrent();
+    method public float getMax();
+    method public float getMin();
+    method public int getType();
+    method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.RangeInfoCompat! obtain(int, float, float, float);
+    field public static final int RANGE_TYPE_FLOAT = 1; // 0x1
+    field public static final int RANGE_TYPE_INT = 0; // 0x0
+    field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
+  }
+
+  public static final class AccessibilityNodeInfoCompat.TouchDelegateInfoCompat {
+    ctor public AccessibilityNodeInfoCompat.TouchDelegateInfoCompat(java.util.Map<android.graphics.Region!,android.view.View!>);
+    method public android.graphics.Region? getRegionAt(@IntRange(from=0) int);
+    method @IntRange(from=0) public int getRegionCount();
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getTargetForRegion(android.graphics.Region);
+  }
+
+  public class AccessibilityNodeProviderCompat {
+    ctor public AccessibilityNodeProviderCompat();
+    ctor public AccessibilityNodeProviderCompat(Object?);
+    method public void addExtraDataToAccessibilityNodeInfo(int, androidx.core.view.accessibility.AccessibilityNodeInfoCompat, String, android.os.Bundle?);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? createAccessibilityNodeInfo(int);
+    method public java.util.List<androidx.core.view.accessibility.AccessibilityNodeInfoCompat!>? findAccessibilityNodeInfosByText(String, int);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? findFocus(int);
+    method public Object? getProvider();
+    method public boolean performAction(int, int, android.os.Bundle?);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
+  }
+
+  public class AccessibilityRecordCompat {
+    ctor @Deprecated public AccessibilityRecordCompat(Object!);
+    method @Deprecated public boolean equals(Object?);
+    method @Deprecated public int getAddedCount();
+    method @Deprecated public CharSequence! getBeforeText();
+    method @Deprecated public CharSequence! getClassName();
+    method @Deprecated public CharSequence! getContentDescription();
+    method @Deprecated public int getCurrentItemIndex();
+    method @Deprecated public int getFromIndex();
+    method @Deprecated public Object! getImpl();
+    method @Deprecated public int getItemCount();
+    method @Deprecated public int getMaxScrollX();
+    method public static int getMaxScrollX(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public int getMaxScrollY();
+    method public static int getMaxScrollY(android.view.accessibility.AccessibilityRecord);
+    method @Deprecated public android.os.Parcelable! getParcelableData();
+    method @Deprecated public int getRemovedCount();
+    method @Deprecated public int getScrollX();
+    method @Deprecated public int getScrollY();
+    method @Deprecated public androidx.core.view.accessibility.AccessibilityNodeInfoCompat! getSource();
+    method @Deprecated public java.util.List<java.lang.CharSequence!>! getText();
+    method @Deprecated public int getToIndex();
+    method @Deprecated public int getWindowId();
+    method @Deprecated public int hashCode();
+    method @Deprecated public boolean isChecked();
+    method @Deprecated public boolean isEnabled();
+    method @Deprecated public boolean isFullScreen();
+    method @Deprecated public boolean isPassword();
+    method @Deprecated public boolean isScrollable();
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain();
+    method @Deprecated public static androidx.core.view.accessibility.AccessibilityRecordCompat! obtain(androidx.core.view.accessibility.AccessibilityRecordCompat!);
+    method @Deprecated public void recycle();
+    method @Deprecated public void setAddedCount(int);
+    method @Deprecated public void setBeforeText(CharSequence!);
+    method @Deprecated public void setChecked(boolean);
+    method @Deprecated public void setClassName(CharSequence!);
+    method @Deprecated public void setContentDescription(CharSequence!);
+    method @Deprecated public void setCurrentItemIndex(int);
+    method @Deprecated public void setEnabled(boolean);
+    method @Deprecated public void setFromIndex(int);
+    method @Deprecated public void setFullScreen(boolean);
+    method @Deprecated public void setItemCount(int);
+    method public static void setMaxScrollX(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setMaxScrollX(int);
+    method public static void setMaxScrollY(android.view.accessibility.AccessibilityRecord, int);
+    method @Deprecated public void setMaxScrollY(int);
+    method @Deprecated public void setParcelableData(android.os.Parcelable!);
+    method @Deprecated public void setPassword(boolean);
+    method @Deprecated public void setRemovedCount(int);
+    method @Deprecated public void setScrollX(int);
+    method @Deprecated public void setScrollY(int);
+    method @Deprecated public void setScrollable(boolean);
+    method public static void setSource(android.view.accessibility.AccessibilityRecord, android.view.View?, int);
+    method @Deprecated public void setSource(android.view.View!);
+    method @Deprecated public void setSource(android.view.View!, int);
+    method @Deprecated public void setToIndex(int);
+  }
+
+  public interface AccessibilityViewCommand {
+    method public boolean perform(android.view.View, androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments?);
+  }
+
+  public abstract static class AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.CommandArguments();
+  }
+
+  public static final class AccessibilityViewCommand.MoveAtGranularityArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveAtGranularityArguments();
+    method public boolean getExtendSelection();
+    method public int getGranularity();
+  }
+
+  public static final class AccessibilityViewCommand.MoveHtmlArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveHtmlArguments();
+    method public String? getHTMLElement();
+  }
+
+  public static final class AccessibilityViewCommand.MoveWindowArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.MoveWindowArguments();
+    method public int getX();
+    method public int getY();
+  }
+
+  public static final class AccessibilityViewCommand.ScrollToPositionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.ScrollToPositionArguments();
+    method public int getColumn();
+    method public int getRow();
+  }
+
+  public static final class AccessibilityViewCommand.SetProgressArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetProgressArguments();
+    method public float getProgress();
+  }
+
+  public static final class AccessibilityViewCommand.SetSelectionArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetSelectionArguments();
+    method public int getEnd();
+    method public int getStart();
+  }
+
+  public static final class AccessibilityViewCommand.SetTextArguments extends androidx.core.view.accessibility.AccessibilityViewCommand.CommandArguments {
+    ctor public AccessibilityViewCommand.SetTextArguments();
+    method public CharSequence? getText();
+  }
+
+  public class AccessibilityWindowInfoCompat {
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
+    method public int getChildCount();
+    method public int getDisplayId();
+    method public int getId();
+    method public int getLayer();
+    method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getParent();
+    method public void getRegionInScreen(android.graphics.Region);
+    method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getRoot();
+    method public CharSequence? getTitle();
+    method public int getType();
+    method public boolean isAccessibilityFocused();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public boolean isInPictureInPictureMode();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain();
+    method public static androidx.core.view.accessibility.AccessibilityWindowInfoCompat? obtain(androidx.core.view.accessibility.AccessibilityWindowInfoCompat?);
+    method @Deprecated public void recycle();
+    method public android.view.accessibility.AccessibilityWindowInfo? unwrap();
+    field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
+}
+
+package androidx.core.view.animation {
+
+  public final class PathInterpolatorCompat {
+    method public static android.view.animation.Interpolator create(android.graphics.Path);
+    method public static android.view.animation.Interpolator create(float, float);
+    method public static android.view.animation.Interpolator create(float, float, float, float);
+  }
+
+}
+
+package androidx.core.view.autofill {
+
+  public class AutofillIdCompat {
+    method @RequiresApi(26) public android.view.autofill.AutofillId toAutofillId();
+    method @RequiresApi(26) public static androidx.core.view.autofill.AutofillIdCompat toAutofillIdCompat(android.view.autofill.AutofillId);
+  }
+
+}
+
+package androidx.core.view.contentcapture {
+
+  public class ContentCaptureSessionCompat {
+    method public android.view.autofill.AutofillId? newAutofillId(long);
+    method public androidx.core.view.ViewStructureCompat? newVirtualViewStructure(android.view.autofill.AutofillId, long);
+    method public void notifyViewTextChanged(android.view.autofill.AutofillId, CharSequence?);
+    method public void notifyViewsAppeared(java.util.List<android.view.ViewStructure!>);
+    method public void notifyViewsDisappeared(long[]);
+    method @RequiresApi(29) public android.view.contentcapture.ContentCaptureSession toContentCaptureSession();
+    method @RequiresApi(29) public static androidx.core.view.contentcapture.ContentCaptureSessionCompat toContentCaptureSessionCompat(android.view.contentcapture.ContentCaptureSession, android.view.View);
+  }
+
+}
+
+package androidx.core.view.inputmethod {
+
+  public final class EditorInfoCompat {
+    ctor @Deprecated public EditorInfoCompat();
+    method public static String![] getContentMimeTypes(android.view.inputmethod.EditorInfo);
+    method public static CharSequence? getInitialSelectedText(android.view.inputmethod.EditorInfo, int);
+    method public static CharSequence? getInitialTextAfterCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static CharSequence? getInitialTextBeforeCursor(android.view.inputmethod.EditorInfo, int, int);
+    method public static void setContentMimeTypes(android.view.inputmethod.EditorInfo, String![]?);
+    method public static void setInitialSurroundingSubText(android.view.inputmethod.EditorInfo, CharSequence, int);
+    method public static void setInitialSurroundingText(android.view.inputmethod.EditorInfo, CharSequence);
+    field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000
+    field public static final int IME_FLAG_NO_PERSONALIZED_LEARNING = 16777216; // 0x1000000
+  }
+
+  public final class InputConnectionCompat {
+    ctor @Deprecated public InputConnectionCompat();
+    method public static boolean commitContent(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+    method @Deprecated public static android.view.inputmethod.InputConnection createWrapper(android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo, androidx.core.view.inputmethod.InputConnectionCompat.OnCommitContentListener);
+    method public static android.view.inputmethod.InputConnection createWrapper(android.view.View, android.view.inputmethod.InputConnection, android.view.inputmethod.EditorInfo);
+    field public static final int INPUT_CONTENT_GRANT_READ_URI_PERMISSION = 1; // 0x1
+  }
+
+  public static interface InputConnectionCompat.OnCommitContentListener {
+    method public boolean onCommitContent(androidx.core.view.inputmethod.InputContentInfoCompat, int, android.os.Bundle?);
+  }
+
+  public final class InputContentInfoCompat {
+    ctor public InputContentInfoCompat(android.net.Uri, android.content.ClipDescription, android.net.Uri?);
+    method public android.net.Uri getContentUri();
+    method public android.content.ClipDescription getDescription();
+    method public android.net.Uri? getLinkUri();
+    method public void releasePermission();
+    method public void requestPermission();
+    method public Object? unwrap();
+    method public static androidx.core.view.inputmethod.InputContentInfoCompat? wrap(Object?);
+  }
+
+}
+
+package androidx.core.widget {
+
+  public abstract class AutoScrollHelper implements android.view.View.OnTouchListener {
+    ctor public AutoScrollHelper(android.view.View);
+    method public abstract boolean canTargetScrollHorizontally(int);
+    method public abstract boolean canTargetScrollVertically(int);
+    method public boolean isEnabled();
+    method public boolean isExclusive();
+    method public boolean onTouch(android.view.View!, android.view.MotionEvent!);
+    method public abstract void scrollTargetBy(int, int);
+    method public androidx.core.widget.AutoScrollHelper setActivationDelay(int);
+    method public androidx.core.widget.AutoScrollHelper setEdgeType(int);
+    method public androidx.core.widget.AutoScrollHelper! setEnabled(boolean);
+    method public androidx.core.widget.AutoScrollHelper! setExclusive(boolean);
+    method public androidx.core.widget.AutoScrollHelper setMaximumEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMaximumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setMinimumVelocity(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRampDownDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRampUpDuration(int);
+    method public androidx.core.widget.AutoScrollHelper setRelativeEdges(float, float);
+    method public androidx.core.widget.AutoScrollHelper setRelativeVelocity(float, float);
+    field public static final int EDGE_TYPE_INSIDE = 0; // 0x0
+    field public static final int EDGE_TYPE_INSIDE_EXTEND = 1; // 0x1
+    field public static final int EDGE_TYPE_OUTSIDE = 2; // 0x2
+    field public static final float NO_MAX = 3.4028235E38f;
+    field public static final float NO_MIN = 0.0f;
+    field public static final float RELATIVE_UNSPECIFIED = 0.0f;
+  }
+
+  public final class CheckedTextViewCompat {
+    method public static android.graphics.drawable.Drawable? getCheckMarkDrawable(android.widget.CheckedTextView);
+    method public static android.content.res.ColorStateList? getCheckMarkTintList(android.widget.CheckedTextView);
+    method public static android.graphics.PorterDuff.Mode? getCheckMarkTintMode(android.widget.CheckedTextView);
+    method public static void setCheckMarkTintList(android.widget.CheckedTextView, android.content.res.ColorStateList?);
+    method public static void setCheckMarkTintMode(android.widget.CheckedTextView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class CompoundButtonCompat {
+    method public static android.graphics.drawable.Drawable? getButtonDrawable(android.widget.CompoundButton);
+    method public static android.content.res.ColorStateList? getButtonTintList(android.widget.CompoundButton);
+    method public static android.graphics.PorterDuff.Mode? getButtonTintMode(android.widget.CompoundButton);
+    method public static void setButtonTintList(android.widget.CompoundButton, android.content.res.ColorStateList?);
+    method public static void setButtonTintMode(android.widget.CompoundButton, android.graphics.PorterDuff.Mode?);
+  }
+
+  public class ContentLoadingProgressBar extends android.widget.ProgressBar {
+    ctor public ContentLoadingProgressBar(android.content.Context);
+    ctor public ContentLoadingProgressBar(android.content.Context, android.util.AttributeSet?);
+    method public void hide();
+    method public void onAttachedToWindow();
+    method public void onDetachedFromWindow();
+    method public void show();
+  }
+
+  public final class EdgeEffectCompat {
+    ctor @Deprecated public EdgeEffectCompat(android.content.Context!);
+    method public static android.widget.EdgeEffect create(android.content.Context, android.util.AttributeSet?);
+    method @Deprecated public boolean draw(android.graphics.Canvas!);
+    method @Deprecated public void finish();
+    method public static float getDistance(android.widget.EdgeEffect);
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean onAbsorb(int);
+    method public static void onPull(android.widget.EdgeEffect, float, float);
+    method @Deprecated public boolean onPull(float);
+    method @Deprecated public boolean onPull(float, float);
+    method public static float onPullDistance(android.widget.EdgeEffect, float, float);
+    method @Deprecated public boolean onRelease();
+    method @Deprecated public void setSize(int, int);
+  }
+
+  public class ImageViewCompat {
+    method public static android.content.res.ColorStateList? getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode? getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList?);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode?);
+  }
+
+  public final class ListPopupWindowCompat {
+    method public static android.view.View.OnTouchListener? createDragToOpenListener(android.widget.ListPopupWindow, android.view.View);
+    method @Deprecated public static android.view.View.OnTouchListener! createDragToOpenListener(Object!, android.view.View!);
+  }
+
+  public class ListViewAutoScrollHelper extends androidx.core.widget.AutoScrollHelper {
+    ctor public ListViewAutoScrollHelper(android.widget.ListView);
+    method public boolean canTargetScrollHorizontally(int);
+    method public boolean canTargetScrollVertically(int);
+    method public void scrollTargetBy(int, int);
+  }
+
+  public final class ListViewCompat {
+    method public static boolean canScrollList(android.widget.ListView, int);
+    method public static void scrollListBy(android.widget.ListView, int);
+  }
+
+  public class NestedScrollView extends android.widget.FrameLayout implements androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent3 androidx.core.view.ScrollingView {
+    ctor public NestedScrollView(android.content.Context);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?);
+    ctor public NestedScrollView(android.content.Context, android.util.AttributeSet?, int);
+    method public boolean arrowScroll(int);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeHorizontalScrollRange();
+    method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect!);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollExtent();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollOffset();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public int computeVerticalScrollRange();
+    method public boolean dispatchNestedPreScroll(int, int, int[]?, int[]?, int);
+    method public boolean dispatchNestedScroll(int, int, int, int, int[]?, int);
+    method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+    method public boolean executeKeyEvent(android.view.KeyEvent);
+    method public void fling(int);
+    method public boolean fullScroll(int);
+    method public int getMaxScrollAmount();
+    method public boolean hasNestedScrollingParent(int);
+    method public boolean isFillViewport();
+    method public boolean isSmoothScrollingEnabled();
+    method public void onAttachedToWindow();
+    method public void onNestedPreScroll(android.view.View, int, int, int[], int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int);
+    method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+    method public void onNestedScrollAccepted(android.view.View, android.view.View, int, int);
+    method public boolean onStartNestedScroll(android.view.View, android.view.View, int, int);
+    method public void onStopNestedScroll(android.view.View, int);
+    method public boolean pageScroll(int);
+    method public void setFillViewport(boolean);
+    method public void setOnScrollChangeListener(androidx.core.widget.NestedScrollView.OnScrollChangeListener?);
+    method public void setSmoothScrollingEnabled(boolean);
+    method public final void smoothScrollBy(int, int);
+    method public final void smoothScrollBy(int, int, int);
+    method public final void smoothScrollTo(int, int);
+    method public final void smoothScrollTo(int, int, int);
+    method public boolean startNestedScroll(int, int);
+    method public void stopNestedScroll(int);
+  }
+
+  public static interface NestedScrollView.OnScrollChangeListener {
+    method public void onScrollChange(androidx.core.widget.NestedScrollView, int, int, int, int);
+  }
+
+  public final class PopupMenuCompat {
+    method public static android.view.View.OnTouchListener? getDragToOpenListener(Object);
+  }
+
+  public final class PopupWindowCompat {
+    method public static boolean getOverlapAnchor(android.widget.PopupWindow);
+    method public static int getWindowLayoutType(android.widget.PopupWindow);
+    method public static void setOverlapAnchor(android.widget.PopupWindow, boolean);
+    method public static void setWindowLayoutType(android.widget.PopupWindow, int);
+    method public static void showAsDropDown(android.widget.PopupWindow, android.view.View, int, int, int);
+  }
+
+  @Deprecated public final class ScrollerCompat {
+    method @Deprecated public void abortAnimation();
+    method @Deprecated public boolean computeScrollOffset();
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!);
+    method @Deprecated public static androidx.core.widget.ScrollerCompat! create(android.content.Context!, android.view.animation.Interpolator!);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int);
+    method @Deprecated public void fling(int, int, int, int, int, int, int, int, int, int);
+    method @Deprecated public float getCurrVelocity();
+    method @Deprecated public int getCurrX();
+    method @Deprecated public int getCurrY();
+    method @Deprecated public int getFinalX();
+    method @Deprecated public int getFinalY();
+    method @Deprecated public boolean isFinished();
+    method @Deprecated public boolean isOverScrolled();
+    method @Deprecated public void notifyHorizontalEdgeReached(int, int, int);
+    method @Deprecated public void notifyVerticalEdgeReached(int, int, int);
+    method @Deprecated public boolean springBack(int, int, int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int);
+    method @Deprecated public void startScroll(int, int, int, int, int);
+  }
+
+  public final class TextViewCompat {
+    method public static int getAutoSizeMaxTextSize(android.widget.TextView);
+    method public static int getAutoSizeMinTextSize(android.widget.TextView);
+    method public static int getAutoSizeStepGranularity(android.widget.TextView);
+    method public static int[] getAutoSizeTextAvailableSizes(android.widget.TextView);
+    method public static int getAutoSizeTextType(android.widget.TextView);
+    method public static android.content.res.ColorStateList? getCompoundDrawableTintList(android.widget.TextView);
+    method public static android.graphics.PorterDuff.Mode? getCompoundDrawableTintMode(android.widget.TextView);
+    method public static android.graphics.drawable.Drawable![] getCompoundDrawablesRelative(android.widget.TextView);
+    method public static int getFirstBaselineToTopHeight(android.widget.TextView);
+    method public static int getLastBaselineToBottomHeight(android.widget.TextView);
+    method public static int getMaxLines(android.widget.TextView);
+    method public static int getMinLines(android.widget.TextView);
+    method public static androidx.core.text.PrecomputedTextCompat.Params getTextMetricsParams(android.widget.TextView);
+    method public static void setAutoSizeTextTypeUniformWithConfiguration(android.widget.TextView, int, int, int, int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeUniformWithPresetSizes(android.widget.TextView, int[], int) throws java.lang.IllegalArgumentException;
+    method public static void setAutoSizeTextTypeWithDefaults(android.widget.TextView, int);
+    method public static void setCompoundDrawableTintList(android.widget.TextView, android.content.res.ColorStateList?);
+    method public static void setCompoundDrawableTintMode(android.widget.TextView, android.graphics.PorterDuff.Mode?);
+    method public static void setCompoundDrawablesRelative(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?, android.graphics.drawable.Drawable?);
+    method public static void setCompoundDrawablesRelativeWithIntrinsicBounds(android.widget.TextView, @DrawableRes int, @DrawableRes int, @DrawableRes int, @DrawableRes int);
+    method public static void setCustomSelectionActionModeCallback(android.widget.TextView, android.view.ActionMode.Callback);
+    method public static void setFirstBaselineToTopHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLastBaselineToBottomHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setLineHeight(android.widget.TextView, @IntRange(from=0) @Px int);
+    method public static void setPrecomputedText(android.widget.TextView, androidx.core.text.PrecomputedTextCompat);
+    method public static void setTextAppearance(android.widget.TextView, @StyleRes int);
+    method public static void setTextMetricsParams(android.widget.TextView, androidx.core.text.PrecomputedTextCompat.Params);
+    field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0
+    field public static final int AUTO_SIZE_TEXT_TYPE_UNIFORM = 1; // 0x1
+  }
+
+  public interface TintableCompoundButton {
+    method public android.content.res.ColorStateList? getSupportButtonTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportButtonTintMode();
+    method public void setSupportButtonTintList(android.content.res.ColorStateList?);
+    method public void setSupportButtonTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+  public interface TintableCompoundDrawablesView {
+    method public android.content.res.ColorStateList? getSupportCompoundDrawablesTintList();
+    method public android.graphics.PorterDuff.Mode? getSupportCompoundDrawablesTintMode();
+    method public void setSupportCompoundDrawablesTintList(android.content.res.ColorStateList?);
+    method public void setSupportCompoundDrawablesTintMode(android.graphics.PorterDuff.Mode?);
+  }
+
+}
+
diff --git a/core/core/api/restricted_1.11.0-beta01.txt b/core/core/api/restricted_1.11.0-beta01.txt
index f02ce1a..cc104ba 100644
--- a/core/core/api/restricted_1.11.0-beta01.txt
+++ b/core/core/api/restricted_1.11.0-beta01.txt
@@ -2195,19 +2195,12 @@
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.Q) public static boolean isAtLeastQ();
     method @Deprecated @ChecksSdkIntAtLeast(api=android.os.Build.VERSION_CODES.R) public static boolean isAtLeastR();
     method @Deprecated @ChecksSdkIntAtLeast(api=31, codename="S") public static boolean isAtLeastS();
-    method @Deprecated @ChecksSdkIntAtLeast(api=32, codename="Sv2") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastSv2();
-    method @Deprecated @ChecksSdkIntAtLeast(api=33, codename="Tiramisu") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastT();
-    method @ChecksSdkIntAtLeast(api=34, codename="UpsideDownCake") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastU();
-    method @ChecksSdkIntAtLeast(codename="VanillaIceCream") @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static boolean isAtLeastV();
     field @ChecksSdkIntAtLeast(extension=android.os.ext.SdkExtensions.AD_SERVICES) public static final int AD_SERVICES_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.R) public static final int R_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.S) public static final int S_EXTENSION_INT;
     field @ChecksSdkIntAtLeast(extension=android.os.Build.VERSION_CODES.TIRAMISU) public static final int T_EXTENSION_INT;
   }
 
-  @RequiresOptIn @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface BuildCompat.PrereleaseSdkCheck {
-  }
-
   public final class BundleCompat {
     method public static android.os.IBinder? getBinder(android.os.Bundle, String?);
     method public static <T> T? getParcelable(android.os.Bundle, String?, Class<T!>);
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index f02ce1a..c02961d 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -203,6 +203,15 @@
   @IntDef(flag=true, value={androidx.core.app.FrameMetricsAggregator.TOTAL_DURATION, androidx.core.app.FrameMetricsAggregator.INPUT_DURATION, androidx.core.app.FrameMetricsAggregator.LAYOUT_MEASURE_DURATION, androidx.core.app.FrameMetricsAggregator.DRAW_DURATION, androidx.core.app.FrameMetricsAggregator.SYNC_DURATION, androidx.core.app.FrameMetricsAggregator.COMMAND_DURATION, androidx.core.app.FrameMetricsAggregator.SWAP_DURATION, androidx.core.app.FrameMetricsAggregator.DELAY_DURATION, androidx.core.app.FrameMetricsAggregator.ANIMATION_DURATION, androidx.core.app.FrameMetricsAggregator.EVERY_DURATION}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface FrameMetricsAggregator.MetricType {
   }
 
+  public final class GrammaticalInflectionManagerCompat {
+    method @AnyThread public static int getApplicationGrammaticalGender(android.content.Context);
+    method @AnyThread public static void setRequestedApplicationGrammaticalGender(android.content.Context, int);
+    field public static final int GRAMMATICAL_GENDER_FEMININE = 2; // 0x2
+    field public static final int GRAMMATICAL_GENDER_MASCULINE = 3; // 0x3
+    field public static final int GRAMMATICAL_GENDER_NEUTRAL = 1; // 0x1
+    field public static final int GRAMMATICAL_GENDER_NOT_SPECIFIED = 0; // 0x0
+  }
+
   @Deprecated public abstract class JobIntentService extends android.app.Service {
     ctor @Deprecated public JobIntentService();
     method @Deprecated public static void enqueueWork(android.content.Context, android.content.ComponentName, int, android.content.Intent);
@@ -892,6 +901,7 @@
 
   public final class NotificationManagerCompat {
     method public boolean areNotificationsEnabled();
+    method public boolean canUseFullScreenIntent();
     method public void cancel(int);
     method public void cancel(String?, int);
     method public void cancelAll();
@@ -1073,6 +1083,7 @@
   }
 
   public final class ServiceCompat {
+    method public static void startForeground(android.app.Service, int, android.app.Notification, int);
     method public static void stopForeground(android.app.Service, @androidx.core.app.ServiceCompat.StopForegroundFlags int);
     field public static final int START_STICKY = 1; // 0x1
     field public static final int STOP_FOREGROUND_DETACH = 2; // 0x2
@@ -1229,7 +1240,6 @@
     ctor protected FileProvider(@XmlRes int);
     method public int delete(android.net.Uri, String?, String![]?);
     method public String? getType(android.net.Uri);
-    method public String? getTypeAnonymous(android.net.Uri);
     method public static android.net.Uri! getUriForFile(android.content.Context, String, java.io.File);
     method public static android.net.Uri getUriForFile(android.content.Context, String, java.io.File, String);
     method public android.net.Uri! insert(android.net.Uri, android.content.ContentValues);
@@ -2434,6 +2444,26 @@
 
 }
 
+package androidx.core.service.quicksettings {
+
+  public class PendingIntentActivityWrapper {
+    ctor public PendingIntentActivityWrapper(android.content.Context, int, android.content.Intent, int, android.os.Bundle?, boolean);
+    ctor public PendingIntentActivityWrapper(android.content.Context, int, android.content.Intent, int, boolean);
+    method public android.content.Context getContext();
+    method public int getFlags();
+    method public android.content.Intent getIntent();
+    method public android.os.Bundle getOptions();
+    method public android.app.PendingIntent? getPendingIntent();
+    method public int getRequestCode();
+    method public boolean isMutable();
+  }
+
+  public class TileServiceCompat {
+    method public static void startActivityAndCollapse(android.service.quicksettings.TileService, androidx.core.service.quicksettings.PendingIntentActivityWrapper);
+  }
+
+}
+
 package androidx.core.telephony {
 
   @RequiresApi(22) public class SubscriptionManagerCompat {
@@ -2587,6 +2617,66 @@
   @IntDef(flag=true, value={android.text.util.Linkify.WEB_URLS, android.text.util.Linkify.EMAIL_ADDRESSES, android.text.util.Linkify.PHONE_NUMBERS, android.text.util.Linkify.MAP_ADDRESSES, android.text.util.Linkify.ALL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface LinkifyCompat.LinkifyMask {
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.LOLLIPOP) public final class LocalePreferences {
+    method public static String getCalendarType();
+    method public static String getCalendarType(boolean);
+    method public static String getCalendarType(java.util.Locale);
+    method public static String getCalendarType(java.util.Locale, boolean);
+    method public static String getFirstDayOfWeek();
+    method public static String getFirstDayOfWeek(boolean);
+    method public static String getFirstDayOfWeek(java.util.Locale);
+    method public static String getFirstDayOfWeek(java.util.Locale, boolean);
+    method public static String getHourCycle();
+    method public static String getHourCycle(boolean);
+    method public static String getHourCycle(java.util.Locale);
+    method public static String getHourCycle(java.util.Locale, boolean);
+    method public static String getTemperatureUnit();
+    method public static String getTemperatureUnit(boolean);
+    method public static String getTemperatureUnit(java.util.Locale);
+    method public static String getTemperatureUnit(java.util.Locale, boolean);
+  }
+
+  public static class LocalePreferences.CalendarType {
+    field public static final String CHINESE = "chinese";
+    field public static final String DANGI = "dangi";
+    field public static final String DEFAULT = "";
+    field public static final String GREGORIAN = "gregorian";
+    field public static final String HEBREW = "hebrew";
+    field public static final String INDIAN = "indian";
+    field public static final String ISLAMIC = "islamic";
+    field public static final String ISLAMIC_CIVIL = "islamic-civil";
+    field public static final String ISLAMIC_RGSA = "islamic-rgsa";
+    field public static final String ISLAMIC_TBLA = "islamic-tbla";
+    field public static final String ISLAMIC_UMALQURA = "islamic-umalqura";
+    field public static final String PERSIAN = "persian";
+  }
+
+  public static class LocalePreferences.FirstDayOfWeek {
+    field public static final String DEFAULT = "";
+    field public static final String FRIDAY = "fri";
+    field public static final String MONDAY = "mon";
+    field public static final String SATURDAY = "sat";
+    field public static final String SUNDAY = "sun";
+    field public static final String THURSDAY = "thu";
+    field public static final String TUESDAY = "tue";
+    field public static final String WEDNESDAY = "wed";
+  }
+
+  public static class LocalePreferences.HourCycle {
+    field public static final String DEFAULT = "";
+    field public static final String H11 = "h11";
+    field public static final String H12 = "h12";
+    field public static final String H23 = "h23";
+    field public static final String H24 = "h24";
+  }
+
+  public static class LocalePreferences.TemperatureUnit {
+    field public static final String CELSIUS = "celsius";
+    field public static final String DEFAULT = "";
+    field public static final String FAHRENHEIT = "fahrenhe";
+    field public static final String KELVIN = "kelvin";
+  }
+
 }
 
 package androidx.core.util {
@@ -2610,6 +2700,10 @@
     method public static void buildShortClassTag(Object!, StringBuilder!);
   }
 
+  @java.lang.FunctionalInterface public interface Function<T, R> {
+    method public R! apply(T!);
+  }
+
   @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class LogWriter extends java.io.Writer {
     ctor @Deprecated public LogWriter(String!);
     method @Deprecated public void close();
@@ -2710,6 +2804,14 @@
     field @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final int HUNDRED_DAY_FIELD_LEN = 19; // 0x13
   }
 
+  public class TypedValueCompat {
+    method public static float deriveDimension(int, float, android.util.DisplayMetrics);
+    method public static float dpToPx(float, android.util.DisplayMetrics);
+    method public static float pxToDp(float, android.util.DisplayMetrics);
+    method public static float pxToSp(float, android.util.DisplayMetrics);
+    method public static float spToPx(float, android.util.DisplayMetrics);
+  }
+
 }
 
 package androidx.core.view {
@@ -3223,9 +3325,15 @@
     method public void setSupportBackgroundTintMode(android.graphics.PorterDuff.Mode?);
   }
 
-  @Deprecated public final class VelocityTrackerCompat {
+  public final class VelocityTrackerCompat {
+    method public static float getAxisVelocity(android.view.VelocityTracker, @androidx.core.view.VelocityTrackerCompat.VelocityTrackableMotionEventAxis int);
+    method public static float getAxisVelocity(android.view.VelocityTracker, @androidx.core.view.VelocityTrackerCompat.VelocityTrackableMotionEventAxis int, int);
     method @Deprecated public static float getXVelocity(android.view.VelocityTracker!, int);
     method @Deprecated public static float getYVelocity(android.view.VelocityTracker!, int);
+    method public static boolean isAxisSupported(android.view.VelocityTracker, @androidx.core.view.VelocityTrackerCompat.VelocityTrackableMotionEventAxis int);
+  }
+
+  @IntDef({android.view.MotionEvent.AXIS_X, android.view.MotionEvent.AXIS_Y, android.view.MotionEvent.AXIS_SCROLL}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface VelocityTrackerCompat.VelocityTrackableMotionEventAxis {
   }
 
   public class ViewCompat {
@@ -3472,6 +3580,8 @@
   public final class ViewConfigurationCompat {
     method public static float getScaledHorizontalScrollFactor(android.view.ViewConfiguration, android.content.Context);
     method public static int getScaledHoverSlop(android.view.ViewConfiguration);
+    method public static int getScaledMaximumFlingVelocity(android.content.Context, android.view.ViewConfiguration, int, int, int);
+    method public static int getScaledMinimumFlingVelocity(android.content.Context, android.view.ViewConfiguration, int, int, int);
     method @Deprecated public static int getScaledPagingTouchSlop(android.view.ViewConfiguration!);
     method public static float getScaledVerticalScrollFactor(android.view.ViewConfiguration, android.content.Context);
     method @Deprecated public static boolean hasPermanentMenuKey(android.view.ViewConfiguration!);
@@ -3776,6 +3886,7 @@
     field @Deprecated public static final int TYPE_VIEW_HOVER_ENTER = 128; // 0x80
     field @Deprecated public static final int TYPE_VIEW_HOVER_EXIT = 256; // 0x100
     field @Deprecated public static final int TYPE_VIEW_SCROLLED = 4096; // 0x1000
+    field public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 67108864; // 0x4000000
     field @Deprecated public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
     field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
     field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
@@ -3873,6 +3984,7 @@
     method public boolean isEnabled();
     method public boolean isFocusable();
     method public boolean isFocused();
+    method public boolean isGranularScrollingSupported();
     method public boolean isHeading();
     method public boolean isImportantForAccessibility();
     method public boolean isLongClickable();
@@ -3917,6 +4029,7 @@
     method public void setError(CharSequence!);
     method public void setFocusable(boolean);
     method public void setFocused(boolean);
+    method public void setGranularScrollingSupported(boolean);
     method public void setHeading(boolean);
     method public void setHintText(CharSequence?);
     method public void setImportantForAccessibility(boolean);
@@ -3963,6 +4076,7 @@
     method public static androidx.core.view.accessibility.AccessibilityNodeInfoCompat! wrap(android.view.accessibility.AccessibilityNodeInfo);
     field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
     field public static final String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT";
+    field public static final String ACTION_ARGUMENT_DIRECTION_INT = "androidx.core.view.accessibility.action.ARGUMENT_DIRECTION_INT";
     field public static final String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN";
     field public static final String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
     field public static final String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
@@ -3971,6 +4085,7 @@
     field public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT = "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
     field public static final String ACTION_ARGUMENT_PROGRESS_VALUE = "android.view.accessibility.action.ARGUMENT_PROGRESS_VALUE";
     field public static final String ACTION_ARGUMENT_ROW_INT = "android.view.accessibility.action.ARGUMENT_ROW_INT";
+    field public static final String ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT = "androidx.core.view.accessibility.action.ARGUMENT_SCROLL_AMOUNT_FLOAT";
     field public static final String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
     field public static final String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
     field public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
@@ -4048,6 +4163,7 @@
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_BACKWARD;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_DOWN;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_FORWARD;
+    field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat ACTION_SCROLL_IN_DIRECTION;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_LEFT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_RIGHT;
     field public static final androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat! ACTION_SCROLL_TO_POSITION;
@@ -4222,6 +4338,7 @@
   }
 
   public class AccessibilityWindowInfoCompat {
+    ctor public AccessibilityWindowInfoCompat();
     method public androidx.core.view.accessibility.AccessibilityNodeInfoCompat? getAnchor();
     method public void getBoundsInScreen(android.graphics.Rect);
     method public androidx.core.view.accessibility.AccessibilityWindowInfoCompat? getChild(int);
diff --git a/core/core/build.gradle b/core/core/build.gradle
index 832085f..149662a 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -22,6 +22,9 @@
     implementation("androidx.concurrent:concurrent-futures:1.0.0")
     implementation("androidx.interpolator:interpolator:1.0.0")
 
+    // Workaround for Kotlin dependency constraints
+    implementation(libs.kotlinStdlib)
+
     // We don't ship this as a public artifact, so it must remain a project-type dependency.
     annotationProcessor(projectOrArtifact(":versionedparcelable:versionedparcelable-compiler"))
 
diff --git a/core/core/lint-baseline.xml b/core/core/lint-baseline.xml
index 15bf316..44d14fe 100644
--- a/core/core/lint-baseline.xml
+++ b/core/core/lint-baseline.xml
@@ -722,6 +722,15 @@
     </issue>
 
     <issue
+        id="Range"
+        message="Value must be ≥ 1 and ≤ 200 but `getSvid` can be 206"
+        errorLine1="        return mWrapped.getSvid(satelliteIndex);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/core/location/GnssStatusWrapper.java"/>
+    </issue>
+
+    <issue
         id="WrongConstant"
         message="Must be one of: Callback.DISPATCH_MODE_STOP, Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE"
         errorLine1="                super(compat.getDispatchMode());"
@@ -2046,6 +2055,15 @@
 
     <issue
         id="ClassVerificationFailure"
+        message="This call references a method added in API level 23; however, the containing class androidx.core.app.NotificationManagerCompat is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    mContext.checkSelfPermission(Manifest.permission.USE_FULL_SCREEN_INTENT);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/core/app/NotificationManagerCompat.java"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
         message="This call references a method added in API level 28; however, the containing class androidx.core.text.PrecomputedTextCompat.Params is reachable from earlier API levels and will fail run-time class verification."
         errorLine1="                mWrapped = new PrecomputedText.Params.Builder(paint)"
         errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/core/core/src/androidTest/AndroidManifest.xml b/core/core/src/androidTest/AndroidManifest.xml
index 2688f36..30756c9 100644
--- a/core/core/src/androidTest/AndroidManifest.xml
+++ b/core/core/src/androidTest/AndroidManifest.xml
@@ -144,6 +144,11 @@
             android:name="androidx.core.view.inputmethod.ImeSecondarySplitTestActivity"
             android:exported="true" />
 
+        <activity
+            android:name="androidx.core.app.GrammaticalInfectionActivity"
+            android:configChanges="grammaticalGender"
+            android:exported="true" />
+
         <activity-alias
             android:name="androidx.core.app.NavUtilsAliasActivity"
             android:targetActivity="androidx.core.app.NavUtilsActivity">
diff --git a/core/core/src/androidTest/java/androidx/core/app/GrammaticalInfectionActivity.java b/core/core/src/androidTest/java/androidx/core/app/GrammaticalInfectionActivity.java
new file mode 100644
index 0000000..07e58d1
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/app/GrammaticalInfectionActivity.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core.app;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class GrammaticalInfectionActivity extends Activity {
+    private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+        setContentView(androidx.core.test.R.layout.activity_compat_activity);
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration config) {
+        super.onConfigurationChanged(config);
+        mCountDownLatch.countDown();
+    }
+
+    public void await() throws InterruptedException {
+        mCountDownLatch.await(5, TimeUnit.SECONDS);
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/app/GrammaticalInflectionManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/GrammaticalInflectionManagerCompatTest.java
new file mode 100644
index 0000000..187ca12
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/app/GrammaticalInflectionManagerCompatTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.app;
+
+import static androidx.core.app.GrammaticalInflectionManagerCompat.GRAMMATICAL_GENDER_MASCULINE;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.v4.BaseInstrumentationTestCase;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GrammaticalInflectionManagerCompatTest extends
+        BaseInstrumentationTestCase<GrammaticalInfectionActivity> {
+
+    public GrammaticalInflectionManagerCompatTest() {
+        super(GrammaticalInfectionActivity.class);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 34)
+    public void testSetGrammaticalGender() throws InterruptedException {
+        GrammaticalInflectionManagerCompat.setRequestedApplicationGrammaticalGender(
+                mActivityTestRule.getActivity(),
+                GRAMMATICAL_GENDER_MASCULINE
+        );
+
+        mActivityTestRule.getActivity().await();
+
+        assertEquals(GRAMMATICAL_GENDER_MASCULINE,
+                GrammaticalInflectionManagerCompat.getApplicationGrammaticalGender(
+                        mActivityTestRule.getActivity()));
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java b/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
index 6531103..a264df7 100644
--- a/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/app/NotificationManagerCompatTest.java
@@ -26,7 +26,10 @@
 import static androidx.core.app.NotificationManagerCompat.IMPORTANCE_MAX;
 import static androidx.core.app.NotificationManagerCompat.IMPORTANCE_MIN;
 
+import static org.mockito.Mockito.spy;
+
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -34,6 +37,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.Manifest;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
@@ -1159,6 +1163,27 @@
     }
 
     @Test
+    public void testCanUseFullScreenIntent() {
+        NotificationManager fakeManager = mock(NotificationManager.class);
+
+        Context spyContext = spy(mContext);
+
+        NotificationManagerCompat notificationManagerCompat =
+                new NotificationManagerCompat(fakeManager, spyContext);
+
+        final boolean canUse = notificationManagerCompat.canUseFullScreenIntent();
+
+        if (Build.VERSION.SDK_INT < 29) {
+            assertTrue(canUse);
+
+        } else if (Build.VERSION.SDK_INT < 34) {
+            verify(spyContext, times(1))
+                    .checkSelfPermission(Manifest.permission.USE_FULL_SCREEN_INTENT);
+        } else {
+            verify(fakeManager, times(1)).canUseFullScreenIntent();
+        }
+    }
+
     public void testGetActiveNotifications() {
         NotificationManager fakeManager = mock(NotificationManager.class);
         NotificationManagerCompat notificationManager =
diff --git a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
index c1e0eda..a0ce095 100644
--- a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
@@ -87,6 +87,7 @@
 import android.app.KeyguardManager;
 import android.app.NotificationManager;
 import android.app.SearchManager;
+import android.app.UiAutomation;
 import android.app.UiModeManager;
 import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
@@ -531,11 +532,15 @@
     @Test
     @SdkSuppress(minSdkVersion = 29, maxSdkVersion = 32)
     public void testRegisterReceiverPermissionNotGrantedApi26() {
-        InstrumentationRegistry
-                .getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
-        assertThrows(RuntimeException.class,
-                () -> ContextCompat.registerReceiver(mContext,
-                        mTestReceiver, mTestFilter, ContextCompat.RECEIVER_NOT_EXPORTED));
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        uiAutomation.adoptShellPermissionIdentity();
+        try {
+            assertThrows(RuntimeException.class,
+                    () -> ContextCompat.registerReceiver(mContext,
+                            mTestReceiver, mTestFilter, ContextCompat.RECEIVER_NOT_EXPORTED));
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
     }
 
     @Test
diff --git a/core/core/src/androidTest/java/androidx/core/service/quicksettings/TileServiceCompatTest.java b/core/core/src/androidTest/java/androidx/core/service/quicksettings/TileServiceCompatTest.java
new file mode 100644
index 0000000..a78f703
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/service/quicksettings/TileServiceCompatTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.core.service.quicksettings;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.quicksettings.TileService;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit test for {@link TileServiceCompat}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class TileServiceCompatTest {
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+
+    @After
+    public void tearDown() {
+        TileServiceCompat.clearTileServiceWrapper();
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    public void startActivityAndCollapse_usesPendingIntent() {
+        TileServiceCompat.TileServiceWrapper tileServiceWrapper =
+                mock(TileServiceCompat.TileServiceWrapper.class);
+        TileService tileService = mock(TileService.class);
+        int requestCode = 7465;
+        Intent intent = new Intent();
+        Bundle options = new Bundle();
+        PendingIntentActivityWrapper wrapper = new PendingIntentActivityWrapper(mContext,
+                requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT, options, /* isMutable = */
+                true);
+        TileServiceCompat.setTileServiceWrapper(tileServiceWrapper);
+
+        TileServiceCompat.startActivityAndCollapse(tileService, wrapper);
+
+        verify(tileServiceWrapper).startActivityAndCollapse(wrapper.getPendingIntent());
+    }
+
+    @SdkSuppress(minSdkVersion = 24, maxSdkVersion = 33)
+    @Test
+    public void startActivityAndCollapse_usesIntent() {
+        TileServiceCompat.TileServiceWrapper tileServiceWrapper =
+                mock(TileServiceCompat.TileServiceWrapper.class);
+        TileService tileService = mock(TileService.class);
+        int requestCode = 7465;
+        Intent intent = new Intent();
+        Bundle options = new Bundle();
+        PendingIntentActivityWrapper wrapper = new PendingIntentActivityWrapper(mContext,
+                requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT, options, /* isMutable = */
+                true);
+        TileServiceCompat.setTileServiceWrapper(tileServiceWrapper);
+
+        TileServiceCompat.startActivityAndCollapse(tileService, wrapper);
+
+        verify(tileServiceWrapper).startActivityAndCollapse(intent);
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/text/util/LocalePreferencesTest.java b/core/core/src/androidTest/java/androidx/core/text/util/LocalePreferencesTest.java
new file mode 100644
index 0000000..a47cc38
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/text/util/LocalePreferencesTest.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.text.util;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Build.VERSION_CODES;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Locale;
+
+@SmallTest
+@SdkSuppress(minSdkVersion = VERSION_CODES.N)
+@RunWith(AndroidJUnit4.class)
+public class LocalePreferencesTest {
+    private static Locale sLocale;
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        sLocale = Locale.getDefault(Locale.Category.FORMAT);
+    }
+
+    @After
+    public void tearDown() {
+        Locale.setDefault(sLocale);
+    }
+
+    // Hour cycle
+    @Test
+    public void getHourCycle_hasSubTags_resultIsH24() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getHourCycle();
+
+        assertEquals(LocalePreferences.HourCycle.H24, result);
+    }
+
+    @Test
+    public void getHourCycle_hasSubTagsWithoutHourCycleTag_resultIsH12() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getHourCycle();
+
+        assertEquals(LocalePreferences.HourCycle.H12, result);
+    }
+
+    @Test
+    public void getHourCycle_hasSubTagsAndDisableResolved_resultIsH24() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getHourCycle(false);
+
+        assertEquals(LocalePreferences.HourCycle.H24, result);
+    }
+
+    @Test
+    public void getHourCycle_hasSubTagsWithoutHourCycleTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getHourCycle(false);
+
+        assertEquals(LocalePreferences.HourCycle.DEFAULT, result);
+    }
+
+    @Test
+    public void getHourCycle_inputLocaleWithHourCycleTag_resultIsH12() throws Exception {
+        String result = LocalePreferences.getHourCycle(Locale.forLanguageTag("en-US-u-hc-h12"));
+
+        assertEquals(LocalePreferences.HourCycle.H12, result);
+    }
+
+    @Test
+    public void getHourCycle_inputLocaleWithoutHourCycleTag_resultIsH12() throws Exception {
+        String result = LocalePreferences.getHourCycle(Locale.forLanguageTag("en-US"));
+
+        assertEquals(LocalePreferences.HourCycle.H12, result);
+    }
+
+    @Test
+    public void getHourCycle_inputH23Locale_resultIsH23() throws Exception {
+        String result = LocalePreferences.getHourCycle(Locale.forLanguageTag("fr-FR"));
+
+        assertEquals(LocalePreferences.HourCycle.H23, result);
+    }
+
+    @Test
+    public void getHourCycle_inputH23LocaleWithHourCycleTag_resultIsH12() throws Exception {
+        String result = LocalePreferences.getHourCycle(Locale.forLanguageTag("fr-FR-u-hc-h12"));
+
+        assertEquals(LocalePreferences.HourCycle.H12, result);
+    }
+
+    @Test
+    public void getHourCycle_inputLocaleWithoutHourCycleTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        String result = LocalePreferences.getHourCycle(Locale.forLanguageTag("en-US"), false);
+
+        assertEquals(LocalePreferences.HourCycle.DEFAULT, result);
+    }
+
+    @Test
+    public void getHourCycle_compareHasResolvedValueIsTrueAndWithoutResolvedValue_sameResult()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("zh-TW-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        // Has Hour Cycle subtag
+        String resultWithoutResolvedValue = LocalePreferences.getHourCycle();
+        String resultResolvedIsTrue = LocalePreferences.getHourCycle(true);
+        assertEquals(resultWithoutResolvedValue, resultResolvedIsTrue);
+
+        // Does not have HourCycle subtag
+        Locale.setDefault(Locale.forLanguageTag("zh-TW-u-ca-chinese-mu-celsius-fw-wed"));
+
+        resultWithoutResolvedValue = LocalePreferences.getHourCycle();
+        resultResolvedIsTrue = LocalePreferences.getHourCycle(true);
+        assertEquals(resultWithoutResolvedValue, resultResolvedIsTrue);
+    }
+
+    // Calendar
+    @Test
+    public void getCalendarType_hasSubTags_resultIsChinese() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getCalendarType();
+
+        assertEquals(LocalePreferences.CalendarType.CHINESE, result);
+    }
+
+    @Test
+    public void getCalendarType_hasSubTagsWithoutCalendarTag_resultIsGregorian() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getCalendarType();
+
+        assertEquals(LocalePreferences.CalendarType.GREGORIAN, result);
+    }
+
+    @Test
+    public void getCalendarType_hasSubTagsAndDisableResolved_resultIsChinese() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getCalendarType(false);
+
+        assertEquals(LocalePreferences.CalendarType.CHINESE, result);
+    }
+
+    @Test
+    public void getCalendarType_hasSubTagsWithoutCalendarTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getCalendarType(false);
+
+        assertEquals(LocalePreferences.CalendarType.DEFAULT, result);
+    }
+
+    @Test
+    public void getCalendarType_inputLocaleWithCalendarTag_resultIsChinese() throws Exception {
+        String result =
+                LocalePreferences.getCalendarType(Locale.forLanguageTag("en-US-u-ca-chinese"));
+
+        assertEquals(LocalePreferences.CalendarType.CHINESE, result);
+    }
+
+    @Test
+    public void getCalendarType_inputLocaleWithoutCalendarTag_resultIsGregorian() throws Exception {
+        String result = LocalePreferences.getCalendarType(Locale.forLanguageTag("en-US"));
+
+        assertEquals(LocalePreferences.CalendarType.GREGORIAN, result);
+    }
+
+    @Test
+    public void getCalendarType_inputLocaleWithoutCalendarTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        String result = LocalePreferences.getCalendarType(Locale.forLanguageTag("en-US"), false);
+
+        assertEquals(LocalePreferences.CalendarType.DEFAULT, result);
+    }
+
+    // Temperature unit
+    @Test
+    public void getTemperatureUnit_hasSubTags_resultIsCelsius() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getTemperatureUnit();
+
+        assertEquals(LocalePreferences.TemperatureUnit.CELSIUS, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_hasSubTagsWithoutUnitTag_resultIsFahrenheit() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-hc-h24-fw-wed"));
+
+        String result = LocalePreferences.getTemperatureUnit();
+
+        assertEquals(LocalePreferences.TemperatureUnit.FAHRENHEIT, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_hasSubTagsAndDisableResolved_resultIsCelsius() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getTemperatureUnit(false);
+
+        assertEquals(LocalePreferences.TemperatureUnit.CELSIUS, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_hasSubTagsAndDisableResolved_resultIsFahrenheit()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("zh-TW-u-ca-chinese-hc-h24-mu-fahrenhe-fw-wed"));
+
+        String result = LocalePreferences.getTemperatureUnit(false);
+
+        assertEquals(LocalePreferences.TemperatureUnit.FAHRENHEIT, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_hasSubTagsWithoutUnitTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-fw-wed"));
+
+        String result = LocalePreferences.getTemperatureUnit(false);
+
+        assertEquals(LocalePreferences.TemperatureUnit.DEFAULT, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_inputLocaleWithUnitTag_resultIsCelsius() throws Exception {
+        String result = LocalePreferences
+                .getTemperatureUnit(Locale.forLanguageTag("en-US-u-mu-celsius"));
+
+        assertEquals(LocalePreferences.TemperatureUnit.CELSIUS, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_inputLocaleWithoutUnitTag_resultIsFahrenheit() throws Exception {
+        String result = LocalePreferences.getTemperatureUnit(Locale.forLanguageTag("en-US"));
+
+        assertEquals(LocalePreferences.TemperatureUnit.FAHRENHEIT, result);
+    }
+
+    @Test
+    public void getTemperatureUnit_inputLocaleWithoutUnitTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        String result = LocalePreferences
+                .getTemperatureUnit(Locale.forLanguageTag("en-US"), false);
+
+        assertEquals(LocalePreferences.TemperatureUnit.DEFAULT, result);
+    }
+
+    // First day of week
+    @Test
+    public void getFirstDayOfWeek_hasSubTags_resultIsCelsius() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getFirstDayOfWeek();
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.WEDNESDAY, result);
+    }
+
+    @Test
+    public void getFirstDayOfWeek_hasSubTagsWithoutFwTag_resultIsSun() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-hc-h24"));
+
+        String result = LocalePreferences.getFirstDayOfWeek();
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.SUNDAY, result);
+
+    }
+
+    @Test
+    public void getFirstDayOfWeek_hasSubTagsAndDisableResolved_resultIsWed() throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese-hc-h24-mu-celsius-fw-wed"));
+
+        String result = LocalePreferences.getFirstDayOfWeek(false);
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.WEDNESDAY, result);
+    }
+
+    @Test
+    public void getFirstDayOfWeek_hasSubTagsWithoutFwTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        Locale.setDefault(Locale.forLanguageTag("en-US-u-ca-chinese"));
+
+        String result = LocalePreferences.getFirstDayOfWeek(false);
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.DEFAULT, result);
+    }
+
+    @Test
+    public void getFirstDayOfWeek_inputLocaleWithFwTag_resultIsWed() throws Exception {
+        String result = LocalePreferences
+                .getFirstDayOfWeek(Locale.forLanguageTag("en-US-u-fw-wed"));
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.WEDNESDAY, result);
+    }
+
+    @Test
+    public void getFirstDayOfWeek_inputLocaleWithoutFwTag_resultIsSun() throws Exception {
+        String result = LocalePreferences.getFirstDayOfWeek(Locale.forLanguageTag("en-US"));
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.SUNDAY, result);
+    }
+
+    @Test
+    public void getFirstDayOfWeek_inputLocaleWithoutFwTagAndDisableResolved_resultIsEmpty()
+            throws Exception {
+        String result = LocalePreferences
+                .getFirstDayOfWeek(Locale.forLanguageTag("en-US"), false);
+
+        assertEquals(LocalePreferences.FirstDayOfWeek.DEFAULT, result);
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/util/TypedValueCompatTest.kt b/core/core/src/androidTest/java/androidx/core/util/TypedValueCompatTest.kt
new file mode 100644
index 0000000..8ad6646
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/util/TypedValueCompatTest.kt
@@ -0,0 +1,166 @@
+/*
+ * 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.core.util
+
+import android.util.DisplayMetrics
+import android.util.TypedValue
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class TypedValueCompatTest {
+    @Test
+    fun invalidUnitThrows() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        val fontScale = 2f
+        metrics.density = 1f
+        metrics.xdpi = 2f
+        metrics.scaledDensity = fontScale * metrics.density
+
+        assertThrows(IllegalArgumentException::class.java) {
+            TypedValueCompat.deriveDimension(TypedValue.COMPLEX_UNIT_MM + 1, 23f, metrics)
+        }
+    }
+
+    @Test
+    fun density0_deriveDoesNotCrash() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        metrics.density = 0f
+        metrics.xdpi = 0f
+        metrics.scaledDensity = 0f
+
+        listOf(
+            TypedValue.COMPLEX_UNIT_DIP,
+            TypedValue.COMPLEX_UNIT_SP,
+            TypedValue.COMPLEX_UNIT_PT,
+            TypedValue.COMPLEX_UNIT_IN,
+            TypedValue.COMPLEX_UNIT_MM
+        )
+            .forEach { dimenType ->
+                assertThat(TypedValueCompat.deriveDimension(dimenType, 23f, metrics))
+                    .isEqualTo(0)
+            }
+    }
+
+    @Test
+    fun scaledDensity0_deriveSpDoesNotCrash() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        metrics.density = 1f
+        metrics.xdpi = 2f
+        metrics.scaledDensity = 0f
+
+        assertThat(TypedValueCompat.deriveDimension(TypedValue.COMPLEX_UNIT_SP, 23f, metrics))
+            .isEqualTo(0)
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @Test
+    fun deriveDimensionMatchesRealVersion() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        metrics.density = 1f
+        metrics.xdpi = 2f
+        metrics.scaledDensity = 2f
+
+         listOf(
+            TypedValue.COMPLEX_UNIT_PX,
+            TypedValue.COMPLEX_UNIT_DIP,
+            TypedValue.COMPLEX_UNIT_SP,
+            TypedValue.COMPLEX_UNIT_PT,
+            TypedValue.COMPLEX_UNIT_IN,
+            TypedValue.COMPLEX_UNIT_MM
+        )
+            .forEach { dimenType ->
+                for (i: Int in -1000 until 1000) {
+                    assertThat(TypedValueCompat.deriveDimension(dimenType, i.toFloat(), metrics))
+                        .isWithin(0.05f)
+                        .of(TypedValue.deriveDimension(dimenType, i.toFloat(), metrics))
+                }
+            }
+    }
+
+    @Test
+    fun eachUnitType_roundTripIsEqual() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        metrics.density = 1f
+        metrics.xdpi = 2f
+        metrics.scaledDensity = 2f
+
+        listOf(
+            TypedValue.COMPLEX_UNIT_PX,
+            TypedValue.COMPLEX_UNIT_DIP,
+            TypedValue.COMPLEX_UNIT_SP,
+            TypedValue.COMPLEX_UNIT_PT,
+            TypedValue.COMPLEX_UNIT_IN,
+            TypedValue.COMPLEX_UNIT_MM
+        )
+            .forEach { dimenType ->
+                for (i: Int in -10000 until 10000) {
+                    assertRoundTripIsEqual(i.toFloat(), dimenType, metrics)
+                    assertRoundTripIsEqual(i - .1f, dimenType, metrics)
+                    assertRoundTripIsEqual(i + .5f, dimenType, metrics)
+                }
+            }
+    }
+
+    @Test
+    fun convenienceFunctionsCallCorrectAliases() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        metrics.density = 1f
+        metrics.xdpi = 2f
+        metrics.scaledDensity = 2f
+
+        assertThat(TypedValueCompat.pxToDp(20f, metrics))
+            .isWithin(0.05f)
+            .of(TypedValueCompat.deriveDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics))
+        assertThat(TypedValueCompat.pxToSp(20f, metrics))
+            .isWithin(0.05f)
+            .of(TypedValueCompat.deriveDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics))
+        assertThat(TypedValueCompat.dpToPx(20f, metrics))
+            .isWithin(0.05f)
+            .of(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20f, metrics))
+        assertThat(TypedValueCompat.spToPx(20f, metrics))
+            .isWithin(0.05f)
+            .of(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20f, metrics))
+    }
+
+    private fun assertRoundTripIsEqual(
+        dimenValueToTest: Float,
+        dimenType: Int,
+        metrics: DisplayMetrics,
+    ) {
+        val actualPx = TypedValue.applyDimension(dimenType, dimenValueToTest, metrics)
+        val actualDimenValue = TypedValueCompat.deriveDimension(dimenType, actualPx, metrics)
+        assertWithMessage(
+            "TypedValue.applyDimension for type %s on %s = %s should equal " +
+                "TypedValueCompat.deriveDimension of %s",
+            dimenType,
+            dimenValueToTest,
+            actualPx,
+            actualDimenValue
+        )
+            .that(dimenValueToTest)
+            .isWithin(0.05f)
+            .of(actualDimenValue)
+    }
+}
\ No newline at end of file
diff --git a/core/core/src/androidTest/java/androidx/core/view/VelocityTrackerCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/VelocityTrackerCompatTest.java
new file mode 100644
index 0000000..bb8d29a
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/view/VelocityTrackerCompatTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.view;
+
+import static android.view.MotionEvent.AXIS_BRAKE;
+import static android.view.MotionEvent.AXIS_X;
+import static android.view.MotionEvent.AXIS_Y;
+
+import static androidx.core.view.MotionEventCompat.AXIS_SCROLL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Build;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VelocityTrackerCompatTest {
+    /** Arbitrarily chosen velocities across different supported dimensions and some pointer IDs. */
+    private static final float X_VEL_POINTER_ID_1 = 5;
+    private static final float X_VEL_POINTER_ID_2 = 6;
+    private static final float Y_VEL_POINTER_ID_1 = 7;
+    private static final float Y_VEL_POINTER_ID_2 = 8;
+    private static final float SCROLL_VEL_POINTER_ID_1 = 9;
+    private static final float SCROLL_VEL_POINTER_ID_2 = 10;
+
+    /**
+     * A small enough step time stamp (ms), that the VelocityTracker wouldn't consider big enough to
+     * assume a pointer has stopped.
+     */
+    private static final long TIME_STEP_MS = 10;
+
+    /**
+     * An arbitrarily chosen value for the number of times a movement particular type of movement
+     * is added to a tracker. For velocities to be non-zero, we should generally have 2/3 movements,
+     * so 4 is a good value to use.
+     */
+    private static final int NUM_MOVEMENTS = 4;
+
+    private VelocityTracker mPlanarTracker;
+    private VelocityTracker mScrollTracker;
+
+    @Before
+    public void setup() {
+        mPlanarTracker = VelocityTracker.obtain();
+        mScrollTracker = VelocityTracker.obtain();
+
+        long time = 0;
+        float xPointer1 = 0;
+        float yPointer1 = 0;
+        float scrollPointer1 = 0;
+        float xPointer2 = 0;
+        float yPointer2 = 0;
+        float scrollPointer2 = 0;
+
+        // Add MotionEvents to create some velocity!
+        // Note that: the goal of these tests is not to check the specific values of the velocities,
+        // but instead, compare the outputs of the Compat tracker against the platform tracker.
+        for (int i = 0; i < NUM_MOVEMENTS; i++) {
+            time += TIME_STEP_MS;
+            xPointer1 += X_VEL_POINTER_ID_1 * TIME_STEP_MS;
+            yPointer1 += Y_VEL_POINTER_ID_1 * TIME_STEP_MS;
+            scrollPointer1 = SCROLL_VEL_POINTER_ID_1 * TIME_STEP_MS;
+
+            xPointer2 += X_VEL_POINTER_ID_2 * TIME_STEP_MS;
+            yPointer2 += Y_VEL_POINTER_ID_2 * TIME_STEP_MS;
+            scrollPointer2 = SCROLL_VEL_POINTER_ID_2 * TIME_STEP_MS;
+
+            addPlanarMotionEvent(1, time, xPointer1, yPointer1);
+            addPlanarMotionEvent(2, time, xPointer2, yPointer2);
+            addScrollMotionEvent(1, time, scrollPointer1);
+            addScrollMotionEvent(2, time, scrollPointer2);
+        }
+
+        mPlanarTracker.computeCurrentVelocity(1000);
+        mScrollTracker.computeCurrentVelocity(1000);
+    }
+
+    @Test
+    public void testIsAxisSupported_planarAxes() {
+        assertTrue(VelocityTrackerCompat.isAxisSupported(VelocityTracker.obtain(), AXIS_X));
+        assertTrue(VelocityTrackerCompat.isAxisSupported(VelocityTracker.obtain(), AXIS_Y));
+    }
+
+    @Test
+    public void testIsAxisSupported_nonPlanarAxes() {
+        if (Build.VERSION.SDK_INT >= 34) {
+            assertTrue(
+                    VelocityTrackerCompat.isAxisSupported(VelocityTracker.obtain(), AXIS_SCROLL));
+        } else {
+            assertFalse(
+                    VelocityTrackerCompat.isAxisSupported(VelocityTracker.obtain(), AXIS_SCROLL));
+        }
+
+        // Check against an axis that has not yet been supported at any Android version.
+        assertFalse(VelocityTrackerCompat.isAxisSupported(VelocityTracker.obtain(), AXIS_BRAKE));
+    }
+
+    @Test
+    public void testGetAxisVelocity_planarAxes_noPointerId_againstEquivalentPlatformApis() {
+        if (Build.VERSION.SDK_INT >= 34) {
+            float compatXVelocity = VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_X);
+            float compatYVelocity = VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_Y);
+
+            assertEquals(mPlanarTracker.getAxisVelocity(AXIS_X), compatXVelocity, 0);
+            assertEquals(mPlanarTracker.getAxisVelocity(AXIS_Y), compatYVelocity, 0);
+        }
+    }
+
+    @Test
+    public void testGetAxisVelocity_planarAxes_withPointerId_againstEquivalentPlatformApis() {
+        if (Build.VERSION.SDK_INT >= 34) {
+            float compatXVelocity =
+                    VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_X, 2);
+            float compatYVelocity =
+                    VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_Y, 2);
+
+            assertEquals(mPlanarTracker.getAxisVelocity(AXIS_X, 2), compatXVelocity, 0);
+            assertEquals(mPlanarTracker.getAxisVelocity(AXIS_Y, 2), compatYVelocity, 0);
+        }
+    }
+
+    @Test
+    public void testGetAxisVelocity_planarAxes_noPointerId_againstGenericXAndYVelocityApis() {
+        float compatXVelocity = VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_X);
+        float compatYVelocity = VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_Y);
+
+        assertEquals(mPlanarTracker.getXVelocity(), compatXVelocity, 0);
+        assertEquals(mPlanarTracker.getYVelocity(), compatYVelocity, 0);
+    }
+
+    @Test
+    public void testGetAxisVelocity_planarAxes_withPointerId_againstGenericXAndYVelocityApis() {
+        float compatXVelocity =
+                VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_X, 2);
+        float compatYVelocity =
+                VelocityTrackerCompat.getAxisVelocity(mPlanarTracker, AXIS_Y, 2);
+
+        assertEquals(mPlanarTracker.getXVelocity(2), compatXVelocity, 0);
+        assertEquals(mPlanarTracker.getYVelocity(2), compatYVelocity, 0);
+    }
+
+    @Test
+    public void testGetAxisVelocity_axisScroll_noPointerId() {
+        float compatScrollVelocity =
+                VelocityTrackerCompat.getAxisVelocity(mScrollTracker, AXIS_SCROLL);
+
+        if (Build.VERSION.SDK_INT >= 34) {
+            assertEquals(mScrollTracker.getAxisVelocity(AXIS_SCROLL), compatScrollVelocity, 0);
+        } else {
+            assertEquals(0, compatScrollVelocity, 0);
+        }
+    }
+
+    @Test
+    public void testGetAxisVelocity_axisScroll_withPointerId() {
+        float compatScrollVelocity =
+                VelocityTrackerCompat.getAxisVelocity(mScrollTracker, AXIS_SCROLL, 2);
+
+        if (Build.VERSION.SDK_INT >= 34) {
+            assertEquals(mScrollTracker.getAxisVelocity(AXIS_SCROLL, 2), compatScrollVelocity, 0);
+        } else {
+            assertEquals(0, compatScrollVelocity, 0);
+        }
+    }
+
+
+    private void addPlanarMotionEvent(int pointerId, long time, float x, float y) {
+        MotionEvent ev = MotionEvent.obtain(0L, time, MotionEvent.ACTION_MOVE, x, y, 0);
+        mPlanarTracker.addMovement(ev);
+        ev.recycle();
+    }
+    private void addScrollMotionEvent(int pointerId, long time, float scrollAmount) {
+        MotionEvent.PointerProperties props = new MotionEvent.PointerProperties();
+        props.id = pointerId;
+
+        MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+        coords.setAxisValue(MotionEvent.AXIS_SCROLL, scrollAmount);
+
+        MotionEvent ev = MotionEvent.obtain(0 /* downTime */,
+                time,
+                MotionEvent.ACTION_SCROLL,
+                1 /* pointerCount */,
+                new MotionEvent.PointerProperties[] {props},
+                new MotionEvent.PointerCoords[] {coords},
+                0 /* metaState */,
+                0 /* buttonState */,
+                0 /* xPrecision */,
+                0 /* yPrecision */,
+                1 /* deviceId */,
+                0 /* edgeFlags */,
+                InputDevice.SOURCE_ROTARY_ENCODER,
+                0 /* flags */);
+        mScrollTracker.addMovement(ev);
+        ev.recycle();
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/view/ViewConfigurationCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/ViewConfigurationCompatTest.java
new file mode 100644
index 0000000..3828f1f
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/view/ViewConfigurationCompatTest.java
@@ -0,0 +1,358 @@
+/*
+ * 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.core.view;
+
+import static android.view.MotionEvent.AXIS_X;
+import static android.view.MotionEvent.AXIS_Y;
+
+import static androidx.core.view.InputDeviceCompat.SOURCE_ROTARY_ENCODER;
+import static androidx.core.view.InputDeviceCompat.SOURCE_TOUCHSCREEN;
+import static androidx.core.view.MotionEventCompat.AXIS_SCROLL;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.input.InputManager;
+import android.view.InputDevice;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.Nullable;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ViewConfigurationCompatTest {
+    @Mock Resources mResourcesMock;
+    @Mock ViewConfiguration mViewConfigMock;
+    private Context mContext;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledFlingThresholds_withDeviceParams_apiPre34() {
+        InputDevice device = findInputDevice(SOURCE_TOUCHSCREEN);
+        if (device == null) {
+            return;
+        }
+        when(mViewConfigMock.getScaledMinimumFlingVelocity()).thenReturn(10);
+        when(mViewConfigMock.getScaledMaximumFlingVelocity()).thenReturn(20);
+
+        assertFlingThresholds(
+                mViewConfigMock,
+                device.getId(),
+                AXIS_X,
+                SOURCE_TOUCHSCREEN,
+                /* minVel= */ 10,
+                /* maxVel= */ 20);
+        assertFlingThresholds(
+                mViewConfigMock,
+                device.getId(),
+                AXIS_Y,
+                SOURCE_TOUCHSCREEN,
+                /* minVel= */ 10,
+                /* maxVel= */ 20);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledFlingThresholds_realTouchScreenDevice_apiPre34() {
+        InputDevice touchScreenDevice = findInputDevice(SOURCE_TOUCHSCREEN);
+        if (touchScreenDevice == null) {
+            return;
+        }
+        ViewConfiguration vc = ViewConfiguration.get(mContext);
+
+        assertFlingThresholds(
+                vc,
+                touchScreenDevice.getId(),
+                AXIS_X,
+                SOURCE_TOUCHSCREEN,
+                vc.getScaledMinimumFlingVelocity(),
+                vc.getScaledMaximumFlingVelocity());
+        assertFlingThresholds(
+                vc,
+                touchScreenDevice.getId(),
+                AXIS_Y,
+                SOURCE_TOUCHSCREEN,
+                vc.getScaledMinimumFlingVelocity(),
+                vc.getScaledMaximumFlingVelocity());
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledFlingThresholds_realRotaryEncoderDevice_hasNoAndroidResForFling_apiPre34() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+        when(mViewConfigMock.getScaledMinimumFlingVelocity()).thenReturn(10);
+        when(mViewConfigMock.getScaledMaximumFlingVelocity()).thenReturn(20);
+        mockAndroidResource("config_viewMinRotaryEncoderFlingVelocity", "dimen", /* resId= */ 0);
+        mContext = spy(mContext);
+        when(mContext.getResources()).thenReturn(mResourcesMock);
+
+        assertFlingThresholds(
+                mViewConfigMock,
+                rotaryEncoderDevice.getId(),
+                AXIS_SCROLL,
+                SOURCE_ROTARY_ENCODER,
+                /* minVel= */ 10,
+                /* maxVel= */ 20);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledMinFlingVelocity_realRotaryEncoderDevice_hasAndroidResForFling_apiPre34() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+        int deviceId = rotaryEncoderDevice.getId();
+        mockAndroidResource("config_viewMinRotaryEncoderFlingVelocity", "dimen", /* resId= */ 1);
+        when(mResourcesMock.getDimensionPixelSize(1)).thenReturn(100);
+        mContext = spy(mContext);
+        when(mContext.getResources()).thenReturn(mResourcesMock);
+
+        assertEquals(
+                100,
+                ViewConfigurationCompat.getScaledMinimumFlingVelocity(
+                        mContext, mViewConfigMock, deviceId, AXIS_SCROLL, SOURCE_ROTARY_ENCODER));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledMinFlingVelocity_realRotaryEncoderDevice_hasAndroidResForNoFling_apiPre34() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+        int deviceId = rotaryEncoderDevice.getId();
+        mockAndroidResource("config_viewMinRotaryEncoderFlingVelocity", "dimen", /* resId= */ 1);
+        when(mResourcesMock.getDimensionPixelSize(1)).thenReturn(-1);
+        mContext = spy(mContext);
+        when(mContext.getResources()).thenReturn(mResourcesMock);
+
+        assertEquals(
+                Integer.MAX_VALUE,
+                ViewConfigurationCompat.getScaledMinimumFlingVelocity(
+                        mContext, mViewConfigMock, deviceId, AXIS_SCROLL, SOURCE_ROTARY_ENCODER));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledMaxFlingVelocity_hasAndroidResForFling_realRotaryEncoderDevice_apiPre34() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+        int deviceId = rotaryEncoderDevice.getId();
+        mockAndroidResource("config_viewMaxRotaryEncoderFlingVelocity", "dimen", /* resId= */ 1);
+        when(mResourcesMock.getDimensionPixelSize(1)).thenReturn(100);
+        mContext = spy(mContext);
+        when(mContext.getResources()).thenReturn(mResourcesMock);
+
+        assertEquals(
+                100,
+                ViewConfigurationCompat.getScaledMaximumFlingVelocity(
+                        mContext, mViewConfigMock, deviceId, AXIS_SCROLL, SOURCE_ROTARY_ENCODER));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledMaxFlingVelocity_hasAndroidResForNoFling_realRotaryEncoderDevice_apiPre34() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+        int deviceId = rotaryEncoderDevice.getId();
+        mockAndroidResource("config_viewMaxRotaryEncoderFlingVelocity", "dimen", 1);
+        when(mResourcesMock.getDimensionPixelSize(1)).thenReturn(-1);
+        mContext = spy(mContext);
+        when(mContext.getResources()).thenReturn(mResourcesMock);
+
+        assertEquals(
+                Integer.MIN_VALUE,
+                ViewConfigurationCompat.getScaledMaximumFlingVelocity(
+                        mContext, mViewConfigMock, deviceId, AXIS_SCROLL, SOURCE_ROTARY_ENCODER));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 16, maxSdkVersion = 33)
+    public void scaledFlingThresholds_invalidInputDeviceParameters_apiPre34() {
+        assertFlingThresholds(
+                mViewConfigMock,
+                -10, // Bad InputDevice ID.
+                AXIS_X,
+                SOURCE_TOUCHSCREEN,
+                Integer.MAX_VALUE,
+                Integer.MIN_VALUE);
+
+        InputDevice touchScreenDevice = findInputDevice(SOURCE_TOUCHSCREEN);
+        if (touchScreenDevice == null) {
+            return;
+        }
+
+        assertFlingThresholds(
+                mViewConfigMock,
+                touchScreenDevice.getId(),
+                /* axis= */ -1, // Axis cannot be a negative value.
+                SOURCE_TOUCHSCREEN,
+                Integer.MAX_VALUE,
+                Integer.MIN_VALUE);
+        assertFlingThresholds(
+                mViewConfigMock,
+                touchScreenDevice.getId(),
+                AXIS_SCROLL, // Touch does not report on AXIS_SCROLL.
+                SOURCE_TOUCHSCREEN,
+                Integer.MAX_VALUE,
+                Integer.MIN_VALUE);
+        assertFlingThresholds(
+                mViewConfigMock,
+                touchScreenDevice.getId(),
+                AXIS_X,
+                /* source = */ -1, // Source cannot be a negative value.
+                Integer.MAX_VALUE,
+                Integer.MIN_VALUE);
+        assertFlingThresholds(
+                mViewConfigMock,
+                touchScreenDevice.getId(),
+                AXIS_X,
+                SOURCE_ROTARY_ENCODER, // Touch does not have rotary encoder source.
+                Integer.MAX_VALUE,
+                Integer.MIN_VALUE);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 34)
+    public void scaledVelocityThresholds_withDeviceParams_api34Plus() {
+        when(mViewConfigMock.getScaledMinimumFlingVelocity(1, 2, 3)).thenReturn(100);
+        when(mViewConfigMock.getScaledMaximumFlingVelocity(1, 2, 3)).thenReturn(200);
+
+        assertEquals(
+                100,
+                ViewConfigurationCompat.getScaledMinimumFlingVelocity(
+                        mContext, mViewConfigMock, 1, 2, 3));
+        assertEquals(
+                200,
+                ViewConfigurationCompat.getScaledMaximumFlingVelocity(
+                        mContext, mViewConfigMock, 1, 2, 3));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 34)
+    public void scaledFlingThresholds_realTouchScreenDevice_api34Plus() {
+        InputDevice touchScreenDevice = findInputDevice(SOURCE_TOUCHSCREEN);
+        if (touchScreenDevice == null) {
+            return;
+        }
+
+        assertFlingThresholdsEqualPlatformImpl(
+                ViewConfiguration.get(mContext),
+                touchScreenDevice.getId(),
+                SOURCE_TOUCHSCREEN,
+                AXIS_X);
+        assertFlingThresholdsEqualPlatformImpl(
+                ViewConfiguration.get(mContext),
+                touchScreenDevice.getId(),
+                SOURCE_TOUCHSCREEN,
+                AXIS_Y);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 34)
+    public void scaledFlingThresholds_realRotaryEncoderDevice_api34Plus() {
+        InputDevice rotaryEncoderDevice = findInputDevice(SOURCE_ROTARY_ENCODER);
+        if (rotaryEncoderDevice == null) {
+            return;
+        }
+
+        assertFlingThresholdsEqualPlatformImpl(
+                ViewConfiguration.get(mContext),
+                rotaryEncoderDevice.getId(),
+                SOURCE_ROTARY_ENCODER,
+                AXIS_SCROLL);
+    }
+
+    @SdkSuppress(minSdkVersion = 34)
+    private void assertFlingThresholdsEqualPlatformImpl(
+            ViewConfiguration vc, int inputDeviceId, int axis, int source) {
+        assertFlingThresholds(
+                vc,
+                inputDeviceId,
+                axis,
+                source,
+                vc.getScaledMinimumFlingVelocity(inputDeviceId, axis, source),
+                vc.getScaledMaximumFlingVelocity(inputDeviceId, axis, source));
+    }
+
+    private void assertFlingThresholds(
+            ViewConfiguration vc, int inputDeviceId, int axis, int source, int minVel, int maxVel) {
+        assertEquals(
+                minVel,
+                ViewConfigurationCompat.getScaledMinimumFlingVelocity(
+                        mContext, vc, inputDeviceId, axis, source));
+        assertEquals(
+                maxVel,
+                ViewConfigurationCompat.getScaledMaximumFlingVelocity(
+                        mContext, vc, inputDeviceId, axis, source));
+    }
+
+    @SdkSuppress(minSdkVersion = 16)
+    @Nullable
+    private InputDevice findInputDevice(int source) {
+        InputManager inputManager =
+                (InputManager) mContext.getSystemService(Context.INPUT_SERVICE);
+        int[] deviceIds = inputManager.getInputDeviceIds();
+        for (int deviceId : deviceIds) {
+            InputDevice inputDevice = inputManager.getInputDevice(deviceId);
+            if (inputDevice == null) {
+                continue;
+            }
+            List<InputDevice.MotionRange> motionRangeList = inputDevice.getMotionRanges();
+            for (InputDevice.MotionRange motionRange : motionRangeList) {
+                if (motionRange.getSource() == source) {
+                    return inputDevice;
+                }
+            }
+        }
+        return null;
+    }
+
+    private void mockAndroidResource(String name, String defType, int resId) {
+        when(mResourcesMock.getIdentifier(name, defType, /* defPackage= */ "android"))
+                .thenReturn(resId);
+    }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
index 805a399..3b7b2d8 100644
--- a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompatTest.java
@@ -119,6 +119,15 @@
 
     @SdkSuppress(minSdkVersion = 19)
     @Test
+    public void testisGranularScrollingSupported() {
+        AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
+        assertThat(nodeCompat.isGranularScrollingSupported(), is(false));
+        nodeCompat.setGranularScrollingSupported(true);
+        assertThat(nodeCompat.isGranularScrollingSupported(), is(true));
+    }
+
+    @SdkSuppress(minSdkVersion = 19)
+    @Test
     public void testGetSetHeading() {
         AccessibilityNodeInfoCompat nodeCompat = obtainedWrappedNodeCompat();
         nodeCompat.setHeading(true);
@@ -325,4 +334,16 @@
         accessibilityNodeInfoCompat.setTextSelectable(true);
         assertThat(accessibilityNodeInfoCompat.isTextSelectable(), equalTo(true));
     }
+
+    @SdkSuppress(minSdkVersion = 34)
+    @SmallTest
+    @Test
+    public void testActionScrollInDirection() {
+        AccessibilityActionCompat actionCompat =
+                AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION;
+        assertThat(actionCompat.getId(),
+                is(getExpectedActionId(android.R.id.accessibilityActionScrollInDirection)));
+        assertThat(actionCompat.toString(), is("AccessibilityActionCompat: "
+                + "ACTION_SCROLL_IN_DIRECTION"));
+    }
 }
diff --git a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompatTest.java
index a1afdfda..1788e22 100644
--- a/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompatTest.java
@@ -17,7 +17,9 @@
 package androidx.core.view.accessibility;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
 import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
 
 import android.annotation.TargetApi;
 import android.graphics.Region;
@@ -40,6 +42,17 @@
         return AccessibilityWindowInfoCompat.wrapNonNullInstance(accessibilityWindowInfo);
     }
 
+    @SdkSuppress(minSdkVersion = 30)
+    @SmallTest
+    @Test
+    public void testConstructor() {
+        AccessibilityWindowInfoCompat infoCompat = new AccessibilityWindowInfoCompat();
+        AccessibilityWindowInfo info = new AccessibilityWindowInfo();
+
+        assertThat(infoCompat.unwrap(), is(not(equalTo(null))));
+        assertThat(infoCompat.unwrap(), equalTo(info));
+    }
+
     @SdkSuppress(minSdkVersion = 33)
     @SmallTest
     @Test
diff --git a/core/core/src/main/java/androidx/core/app/GrammaticalInflectionManagerCompat.java b/core/core/src/main/java/androidx/core/app/GrammaticalInflectionManagerCompat.java
new file mode 100644
index 0000000..d1f442b
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/app/GrammaticalInflectionManagerCompat.java
@@ -0,0 +1,137 @@
+/*
+ * 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.core.app;
+
+import android.app.GrammaticalInflectionManager;
+import android.content.Context;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.DoNotInline;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helper for accessing features in {@link android.app.GrammaticalInflectionManager}.
+ */
+public final class GrammaticalInflectionManagerCompat {
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef(value = {
+            GRAMMATICAL_GENDER_NOT_SPECIFIED,
+            GRAMMATICAL_GENDER_NEUTRAL,
+            GRAMMATICAL_GENDER_FEMININE,
+            GRAMMATICAL_GENDER_MASCULINE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GrammaticalGender {}
+
+    /**
+     * Constant for grammatical gender: to indicate the user has not specified the terms
+     * of address for the application.
+     *
+     * @see android.content.res.Configuration#GRAMMATICAL_GENDER_NOT_SPECIFIED
+     */
+    public static final int GRAMMATICAL_GENDER_NOT_SPECIFIED = 0;
+
+    /**
+     * Constant for grammatical gender: to indicate the terms of address the user
+     * preferred in an application is neuter.
+     *
+     * @see android.content.res.Configuration#GRAMMATICAL_GENDER_NEUTRAL
+     */
+    public static final int GRAMMATICAL_GENDER_NEUTRAL = 1;
+
+    /**
+     * Constant for grammatical gender: to indicate the terms of address the user
+     * preferred in an application is feminine.
+     *
+     * @see android.content.res.Configuration#GRAMMATICAL_GENDER_FEMININE
+     */
+    public static final int GRAMMATICAL_GENDER_FEMININE = 2;
+
+    /**
+     * Constant for grammatical gender: to indicate the terms of address the user
+     * preferred in an application is masculine.
+     *
+     * @see android.content.res.Configuration#GRAMMATICAL_GENDER_MASCULINE
+     */
+    public static final int GRAMMATICAL_GENDER_MASCULINE = 3;
+
+    private GrammaticalInflectionManagerCompat() {}
+
+   /**
+    * Returns the current grammatical gender. No-op on versions prior to
+    * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}.
+    *
+    * @param context Context to retrieve service from.
+    * @return the grammatical gender if device API level is greater than 33, otherwise, return 0.
+    */
+    @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
+    @AnyThread
+    public static int getApplicationGrammaticalGender(@NonNull Context context) {
+        if (BuildCompat.isAtLeastU()) {
+            return Api34Impl.getApplicationGrammaticalGender(context);
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Sets the current grammatical gender. No-op on versions prior to
+     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}.
+     *
+     * @param context Context to retrieve service from.
+     * @param grammaticalGender the terms of address the user preferred in an application.
+     */
+    @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
+    @AnyThread
+    public static void setRequestedApplicationGrammaticalGender(
+            @NonNull Context context, @GrammaticalGender int grammaticalGender) {
+        if (BuildCompat.isAtLeastU()) {
+            Api34Impl.setRequestedApplicationGrammaticalGender(context, grammaticalGender);
+        }
+    }
+
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() {}
+
+        @DoNotInline
+        static int getApplicationGrammaticalGender(Context context) {
+            return getGrammaticalInflectionManager(context).getApplicationGrammaticalGender();
+        }
+
+        @DoNotInline
+        static void setRequestedApplicationGrammaticalGender(
+                Context context, int grammaticalGender) {
+            getGrammaticalInflectionManager(context)
+                    .setRequestedApplicationGrammaticalGender(grammaticalGender);
+        }
+
+        private static GrammaticalInflectionManager getGrammaticalInflectionManager(
+                Context context) {
+            return context.getSystemService(GrammaticalInflectionManager.class);
+        }
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
index ae70ed1..48bf924 100644
--- a/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
+++ b/core/core/src/main/java/androidx/core/app/NotificationManagerCompat.java
@@ -24,12 +24,14 @@
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
 import android.os.Build;
@@ -808,6 +810,41 @@
     }
 
     /**
+     * Returns whether the calling app can send fullscreen intents.
+     *
+     * <p>Fullscreen intents were introduced in Android
+     * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, where apps could always attach a full
+     * screen intent to their notification via
+     * {@link Notification.Builder#setFullScreenIntent(PendingIntent, boolean)}}.
+     *
+     * <p>Android {@link android.os.Build.VERSION_CODES#Q} introduced the
+     * {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}
+     * permission, where SystemUI will only show the full screen intent attached to a notification
+     * if the permission is declared in the manifest.
+     *
+     * <p>Starting from Android {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, apps
+     * may not have permission to use {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}. If
+     * the FSI permission is denied, SystemUI will show the notification as an expanded heads up
+     * notification on lockscreen.
+     *
+     * <p>To request access, add the {@link android.Manifest.permission#USE_FULL_SCREEN_INTENT}
+     * permission to your manifest, and use
+     * {@link android.provider.Settings#ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT} to send the user
+     * to the settings page where they can grant your app the FSI permission.
+     */
+    public boolean canUseFullScreenIntent() {
+        if (Build.VERSION.SDK_INT < 29) {
+            return true;
+        }
+        if (Build.VERSION.SDK_INT < 34) {
+            final int permissionState =
+                    mContext.checkSelfPermission(Manifest.permission.USE_FULL_SCREEN_INTENT);
+            return permissionState == PackageManager.PERMISSION_GRANTED;
+        }
+        return Api34Impl.canUseFullScreenIntent(mNotificationManager);
+    }
+
+    /**
      * Returns true if this notification should use the side channel for delivery.
      */
     private static boolean useSideChannelForNotification(Notification notification) {
@@ -1362,4 +1399,18 @@
         }
     }
 
+    /**
+     * A class for wrapping calls to {@link Notification.Builder} methods which
+     * were added in API 34; these calls must be wrapped to avoid performance issues.
+     * See the UnsafeNewApiCall lint rule for more details.
+     */
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() { }
+
+        @DoNotInline
+        static boolean canUseFullScreenIntent(NotificationManager notificationManager) {
+            return notificationManager.canUseFullScreenIntent();
+        }
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/app/ServiceCompat.java b/core/core/src/main/java/androidx/core/app/ServiceCompat.java
index 69d1a20..09d7b64 100644
--- a/core/core/src/main/java/androidx/core/app/ServiceCompat.java
+++ b/core/core/src/main/java/androidx/core/app/ServiceCompat.java
@@ -16,17 +16,23 @@
 
 package androidx.core.app;
 
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
+import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE;
+
 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
 
 import android.app.Notification;
 import android.app.Service;
+import android.content.pm.ServiceInfo;
 import android.os.Build;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
+import androidx.annotation.OptIn;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
+import androidx.core.os.BuildCompat;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -88,6 +94,92 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface StopForegroundFlags {}
 
+    private static final int FOREGROUND_SERVICE_TYPE_ALLOWED_SINCE_Q =
+            ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
+
+    private static final int FOREGROUND_SERVICE_TYPE_ALLOWED_SINCE_U =
+            ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_HEALTH
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE
+            | ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE;
+
+    /**
+     * {@link Service#startForeground(int, Notification, int)} with the third parameter
+     * {@code foregroundServiceType} was added in {@link android.os.Build.VERSION_CODES#Q}.
+     *
+     * <p>Before SDK Version {@link android.os.Build.VERSION_CODES#Q}, this method call should call
+     * {@link Service#startForeground(int, Notification)} without the {@code foregroundServiceType}
+     * parameter.</p>
+     *
+     * <p>Beginning with SDK Version {@link android.os.Build.VERSION_CODES#Q}, the allowed
+     * foregroundServiceType are:
+     * <ul>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_PHONE_CALL}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_LOCATION}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE}</li>
+     * </ul>
+     * </p>
+     *
+     * <p>Beginning with SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
+     * apps targeting SDK Version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} is not
+     * allowed to use {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_NONE}. The allowed
+     * foregroundServiceType are:
+     * <ul>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MANIFEST}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_DATA_SYNC}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_PHONE_CALL}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_LOCATION}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_HEALTH}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SYSTEM_EXEMPTED}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SHORT_SERVICE}</li>
+     *   <li>{@link ServiceInfo#FOREGROUND_SERVICE_TYPE_SPECIAL_USE}</li>
+     * </ul>
+     * </p>
+     *
+     * @see Service#startForeground(int, Notification)
+     * @see Service#startForeground(int, Notification, int)
+     */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    public static void startForeground(@NonNull Service service, int id,
+            @NonNull Notification notification, int foregroundServiceType) {
+        if (BuildCompat.isAtLeastU()) {
+            Api34Impl.startForeground(service, id, notification, foregroundServiceType);
+        } else if (Build.VERSION.SDK_INT >= 29) {
+            Api29Impl.startForeground(service, id, notification, foregroundServiceType);
+        } else {
+            service.startForeground(id, notification);
+        }
+    }
+
     /**
      * Remove the passed service from foreground state, allowing it to be killed if
      * more memory is needed.
@@ -115,4 +207,43 @@
             service.stopForeground(flags);
         }
     }
+
+    @RequiresApi(29)
+    static class Api29Impl {
+        private Api29Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void startForeground(Service service, int id, Notification notification,
+                int foregroundServiceType) {
+            if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_NONE
+                    || foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
+                service.startForeground(id, notification, foregroundServiceType);
+            } else {
+                service.startForeground(id, notification,
+                        foregroundServiceType & FOREGROUND_SERVICE_TYPE_ALLOWED_SINCE_Q);
+            }
+        }
+    }
+
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void startForeground(Service service, int id, Notification notification,
+                int foregroundServiceType) {
+            if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_NONE
+                    || foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
+                service.startForeground(id, notification, foregroundServiceType);
+            } else {
+                service.startForeground(id, notification,
+                        foregroundServiceType & FOREGROUND_SERVICE_TYPE_ALLOWED_SINCE_U);
+            }
+        }
+    }
+
 }
diff --git a/core/core/src/main/java/androidx/core/location/LocationCompat.java b/core/core/src/main/java/androidx/core/location/LocationCompat.java
index 6ccefa8..2e2c045 100644
--- a/core/core/src/main/java/androidx/core/location/LocationCompat.java
+++ b/core/core/src/main/java/androidx/core/location/LocationCompat.java
@@ -81,7 +81,8 @@
     @Nullable
     private static Method sSetIsFromMockProviderMethod;
 
-    private LocationCompat() {}
+    private LocationCompat() {
+    }
 
     /**
      * Return the time of this fix, in nanoseconds of elapsed real-time since system boot.
@@ -295,9 +296,17 @@
     /**
      * Returns the Mean Sea Level altitude of the location in meters.
      *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
+     * order to allow for backwards compatibility and testing however, this method will attempt
+     * to read a double extra with the key {@link #EXTRA_MSL_ALTITUDE} and return the result.
+     *
      * @throws IllegalStateException if the Mean Sea Level altitude of the location is not set
+     * @see Location#getMslAltitudeMeters()
      */
     public static double getMslAltitudeMeters(@NonNull Location location) {
+        if (VERSION.SDK_INT >= 34) {
+            return Api34Impl.getMslAltitudeMeters(location);
+        }
         Preconditions.checkState(hasMslAltitude(location),
                 "The Mean Sea Level altitude of the location is not set.");
         return getOrCreateExtras(location).getDouble(EXTRA_MSL_ALTITUDE);
@@ -305,24 +314,54 @@
 
     /**
      * Sets the Mean Sea Level altitude of the location in meters.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
+     * order to allow for backwards compatibility and testing however, this method will attempt
+     * to set a double extra with the key {@link #EXTRA_MSL_ALTITUDE} to include Mean Sea Level
+     * altitude. Be aware that this will overwrite any prior extra value under the same key.
+     *
+     * @see Location#setMslAltitudeMeters(double)
      */
     public static void setMslAltitudeMeters(@NonNull Location location,
             double mslAltitudeMeters) {
-        getOrCreateExtras(location).putDouble(EXTRA_MSL_ALTITUDE, mslAltitudeMeters);
+        if (VERSION.SDK_INT >= 34) {
+            Api34Impl.setMslAltitudeMeters(location, mslAltitudeMeters);
+        } else {
+            getOrCreateExtras(location).putDouble(EXTRA_MSL_ALTITUDE, mslAltitudeMeters);
+        }
     }
 
     /**
      * Returns true if the location has a Mean Sea Level altitude, false otherwise.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
+     * order to allow for backwards compatibility and testing however, this method will return
+     * true if an extra value is with the key {@link #EXTRA_MSL_ALTITUDE}.
+     *
+     * @see Location#hasMslAltitude()
      */
     public static boolean hasMslAltitude(@NonNull Location location) {
+        if (VERSION.SDK_INT >= 34) {
+            return Api34Impl.hasMslAltitude(location);
+        }
         return containsExtra(location, EXTRA_MSL_ALTITUDE);
     }
 
     /**
      * Removes the Mean Sea Level altitude from the location.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude does not exist. In
+     * order to allow for backwards compatibility and testing however, this method will attempt
+     * to remove any extra value with the key {@link #EXTRA_MSL_ALTITUDE}.
+     *
+     * @see Location#removeMslAltitude()
      */
     public static void removeMslAltitude(@NonNull Location location) {
-        removeExtra(location, EXTRA_MSL_ALTITUDE);
+        if (VERSION.SDK_INT >= 34) {
+            Api34Impl.removeMslAltitude(location);
+        } else {
+            removeExtra(location, EXTRA_MSL_ALTITUDE);
+        }
     }
 
     /**
@@ -331,11 +370,20 @@
      * altitude of the location falls within {@link #getMslAltitudeMeters(Location)} +/- this
      * uncertainty.
      *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
+     * exist. In order to allow for backwards compatibility and testing however, this method will
+     * attempt to read a float extra with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY} and return
+     * the result.
+     *
      * @throws IllegalStateException if the Mean Sea Level altitude accuracy of the location is not
      *                               set
+     * @see Location#setMslAltitudeAccuracyMeters(float)
      */
     public static @FloatRange(from = 0.0) float getMslAltitudeAccuracyMeters(
             @NonNull Location location) {
+        if (VERSION.SDK_INT >= 34) {
+            return Api34Impl.getMslAltitudeAccuracyMeters(location);
+        }
         Preconditions.checkState(hasMslAltitudeAccuracy(location),
                 "The Mean Sea Level altitude accuracy of the location is not set.");
         return getOrCreateExtras(location).getFloat(EXTRA_MSL_ALTITUDE_ACCURACY);
@@ -343,25 +391,56 @@
 
     /**
      * Sets the Mean Sea Level altitude accuracy of the location in meters.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
+     * exist. In order to allow for backwards compatibility and testing however, this method will
+     * attempt to set a float extra with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY} to include
+     * Mean Sea Level altitude accuracy. Be aware that this will overwrite any prior extra value
+     * under the same key.
+     *
+     * @see Location#setMslAltitudeAccuracyMeters(float)
      */
     public static void setMslAltitudeAccuracyMeters(@NonNull Location location,
             @FloatRange(from = 0.0) float mslAltitudeAccuracyMeters) {
-        getOrCreateExtras(location).putFloat(EXTRA_MSL_ALTITUDE_ACCURACY,
-                mslAltitudeAccuracyMeters);
+        if (VERSION.SDK_INT >= 34) {
+            Api34Impl.setMslAltitudeAccuracyMeters(location, mslAltitudeAccuracyMeters);
+        } else {
+            getOrCreateExtras(location).putFloat(EXTRA_MSL_ALTITUDE_ACCURACY,
+                    mslAltitudeAccuracyMeters);
+        }
     }
 
     /**
      * Returns true if the location has a Mean Sea Level altitude accuracy, false otherwise.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
+     * exist. In order to allow for backwards compatibility and testing however, this method will
+     * return true if an extra value is with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY}.
+     *
+     * @see Location#hasMslAltitudeAccuracy()
      */
     public static boolean hasMslAltitudeAccuracy(@NonNull Location location) {
+        if (VERSION.SDK_INT >= 34) {
+            return Api34Impl.hasMslAltitudeAccuracy(location);
+        }
         return containsExtra(location, EXTRA_MSL_ALTITUDE_ACCURACY);
     }
 
     /**
      * Removes the Mean Sea Level altitude accuracy from the location.
+     *
+     * <p>NOTE: On API levels below 34, the concept of Mean Sea Level altitude accuracy does not
+     * exist. In order to allow for backwards compatibility and testing however, this method will
+     * attempt to remove any extra value with the key {@link #EXTRA_MSL_ALTITUDE_ACCURACY}.
+     *
+     * @see Location#removeMslAltitudeAccuracy()
      */
     public static void removeMslAltitudeAccuracy(@NonNull Location location) {
-        removeExtra(location, EXTRA_MSL_ALTITUDE_ACCURACY);
+        if (VERSION.SDK_INT >= 34) {
+            Api34Impl.removeMslAltitudeAccuracy(location);
+        } else {
+            removeExtra(location, EXTRA_MSL_ALTITUDE_ACCURACY);
+        }
     }
 
     /**
@@ -433,10 +512,59 @@
         }
     }
 
+    @RequiresApi(34)
+    private static class Api34Impl {
+
+        private Api34Impl() {
+        }
+
+        @DoNotInline
+        static double getMslAltitudeMeters(Location location) {
+            return location.getMslAltitudeMeters();
+        }
+
+        @DoNotInline
+        static void setMslAltitudeMeters(Location location, double mslAltitudeMeters) {
+            location.setMslAltitudeMeters(mslAltitudeMeters);
+        }
+
+        @DoNotInline
+        static boolean hasMslAltitude(Location location) {
+            return location.hasMslAltitude();
+        }
+
+        @DoNotInline
+        static void removeMslAltitude(Location location) {
+            location.removeMslAltitude();
+        }
+
+        @DoNotInline
+        static float getMslAltitudeAccuracyMeters(Location location) {
+            return location.getMslAltitudeAccuracyMeters();
+        }
+
+        @DoNotInline
+        static void setMslAltitudeAccuracyMeters(Location location,
+                float mslAltitudeAccuracyMeters) {
+            location.setMslAltitudeAccuracyMeters(mslAltitudeAccuracyMeters);
+        }
+
+        @DoNotInline
+        static boolean hasMslAltitudeAccuracy(Location location) {
+            return location.hasMslAltitudeAccuracy();
+        }
+
+        @DoNotInline
+        static void removeMslAltitudeAccuracy(Location location) {
+            location.removeMslAltitudeAccuracy();
+        }
+    }
+
     @RequiresApi(26)
     private static class Api26Impl {
 
-        private Api26Impl() {}
+        private Api26Impl() {
+        }
 
         @DoNotInline
         static boolean hasVerticalAccuracy(Location location) {
@@ -487,7 +615,8 @@
     @RequiresApi(18)
     private static class Api18Impl {
 
-        private Api18Impl() {}
+        private Api18Impl() {
+        }
 
         @DoNotInline
         static boolean isMock(Location location) {
@@ -498,7 +627,8 @@
     @RequiresApi(17)
     private static class Api17Impl {
 
-        private Api17Impl() {}
+        private Api17Impl() {
+        }
 
         @DoNotInline
         static long getElapsedRealtimeNanos(Location location) {
diff --git a/core/core/src/main/java/androidx/core/service/quicksettings/PendingIntentActivityWrapper.java b/core/core/src/main/java/androidx/core/service/quicksettings/PendingIntentActivityWrapper.java
new file mode 100644
index 0000000..d42dd7c
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/service/quicksettings/PendingIntentActivityWrapper.java
@@ -0,0 +1,108 @@
+/*
+ * 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.core.service.quicksettings;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.quicksettings.TileService;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.PendingIntentCompat;
+
+/**
+ * A wrapper class for developers to use with
+ * {@link TileServiceCompat#startActivityAndCollapse(TileService, PendingIntentActivityWrapper)}.
+ */
+public class PendingIntentActivityWrapper {
+
+    private final Context mContext;
+
+    private final int mRequestCode;
+
+    @NonNull
+    private final Intent mIntent;
+
+    @PendingIntentCompat.Flags
+    private final int mFlags;
+
+    @Nullable
+    private final Bundle mOptions;
+
+    @Nullable
+    private final PendingIntent mPendingIntent;
+
+    private final boolean mIsMutable;
+
+    public PendingIntentActivityWrapper(@NonNull Context context, int requestCode,
+            @NonNull Intent intent,
+            @PendingIntentCompat.Flags int flags, boolean isMutable) {
+        this(context, requestCode, intent, flags, null, isMutable);
+    }
+
+    public PendingIntentActivityWrapper(@NonNull Context context, int requestCode,
+            @NonNull Intent intent,
+            @PendingIntentCompat.Flags int flags, @Nullable Bundle options, boolean isMutable) {
+        this.mContext = context;
+        this.mRequestCode = requestCode;
+        this.mIntent = intent;
+        this.mFlags = flags;
+        this.mOptions = options;
+        this.mIsMutable = isMutable;
+
+        mPendingIntent = createPendingIntent();
+    }
+
+    public @NonNull Context getContext() {
+        return mContext;
+    }
+
+    public int getRequestCode() {
+        return mRequestCode;
+    }
+
+    public @NonNull Intent getIntent() {
+        return mIntent;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    public @NonNull Bundle getOptions() {
+        return mOptions;
+    }
+
+    public boolean isMutable() {
+        return mIsMutable;
+    }
+
+    public @Nullable PendingIntent getPendingIntent() {
+        return mPendingIntent;
+    }
+
+    private @Nullable PendingIntent createPendingIntent() {
+        if (mOptions == null) {
+            return PendingIntentCompat.getActivity(mContext, mRequestCode, mIntent, mFlags,
+                    mIsMutable);
+        }
+        return PendingIntentCompat.getActivity(mContext, mRequestCode, mIntent, mFlags, mOptions,
+                mIsMutable);
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/service/quicksettings/TileServiceCompat.java b/core/core/src/main/java/androidx/core/service/quicksettings/TileServiceCompat.java
new file mode 100644
index 0000000..bb55828
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/service/quicksettings/TileServiceCompat.java
@@ -0,0 +1,93 @@
+/*
+ * 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.core.service.quicksettings;
+
+import static android.os.Build.VERSION.SDK_INT;
+
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.service.quicksettings.TileService;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+/**
+ * A helper for accessing {@link TileService} API methods.
+ */
+public class TileServiceCompat {
+
+    private static TileServiceWrapper sTileServiceWrapper;
+
+    /**
+     * Calls the correct {@link TileService}#startActivityAndCollapse() method
+     * depending on the app's targeted {@link android.os.Build.VERSION_CODES}.
+     */
+    public static void startActivityAndCollapse(@NonNull TileService tileService,
+            @NonNull PendingIntentActivityWrapper wrapper) {
+        if (SDK_INT >= 34) {
+            if (sTileServiceWrapper != null) {
+                sTileServiceWrapper.startActivityAndCollapse(wrapper.getPendingIntent());
+            } else {
+                Api34Impl.startActivityAndCollapse(tileService, wrapper.getPendingIntent());
+            }
+        } else if (SDK_INT >= 24) {
+            if (sTileServiceWrapper != null) {
+                sTileServiceWrapper.startActivityAndCollapse(wrapper.getIntent());
+            } else {
+                Api24Impl.startActivityAndCollapse(tileService, wrapper.getIntent());
+            }
+        }
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    public static void setTileServiceWrapper(@NonNull TileServiceWrapper serviceWrapper) {
+        sTileServiceWrapper = serviceWrapper;
+    }
+
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    public static void clearTileServiceWrapper() {
+        sTileServiceWrapper = null;
+    }
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+        @DoNotInline
+        static void startActivityAndCollapse(TileService service,
+                PendingIntent pendingIntent) {
+            service.startActivityAndCollapse(pendingIntent);
+        }
+    }
+
+    @RequiresApi(24)
+    private static class Api24Impl {
+        @DoNotInline
+        static void startActivityAndCollapse(TileService service, Intent intent) {
+            service.startActivityAndCollapse(intent);
+        }
+    }
+
+    private TileServiceCompat() {
+    }
+
+    interface TileServiceWrapper {
+        void startActivityAndCollapse(PendingIntent pendingIntent);
+
+        void startActivityAndCollapse(Intent intent);
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/text/util/LocalePreferences.java b/core/core/src/main/java/androidx/core/text/util/LocalePreferences.java
new file mode 100644
index 0000000..81f847e
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/text/util/LocalePreferences.java
@@ -0,0 +1,644 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.core.text.util;
+
+import android.icu.number.LocalizedNumberFormatter;
+import android.icu.number.NumberFormatter;
+import android.icu.text.DateFormat;
+import android.icu.text.DateTimePatternGenerator;
+import android.icu.util.MeasureUnit;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.StringDef;
+import androidx.core.os.BuildCompat;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Locale.Category;
+
+/**
+ * Provides friendly APIs to get the user's locale preferences. The data can refer to
+ * external/cldr/common/main/en.xml.
+ */
+@RequiresApi(VERSION_CODES.LOLLIPOP)
+public final class LocalePreferences {
+    private static final String TAG = LocalePreferences.class.getSimpleName();
+
+    /** APIs to get the user's preference of the hour cycle. */
+    public static class HourCycle {
+        private static final String U_EXTENSION_TAG = "hc";
+
+        /** 12 Hour System (0-11) */
+        public static final String H11 = "h11";
+        /** 12 Hour System (1-12) */
+        public static final String H12 = "h12";
+        /** 24 Hour System (0-23) */
+        public static final String H23 = "h23";
+        /** 24 Hour System (1-24) */
+        public static final String H24 = "h24";
+        /** Default hour cycle for the locale */
+        public static final String DEFAULT = "";
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @StringDef({
+                H11,
+                H12,
+                H23,
+                H24,
+                DEFAULT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface HourCycleTypes {
+        }
+
+        private HourCycle() {
+        }
+    }
+
+    /**
+     * Return the user's preference of the hour cycle which is from
+     * {@link Locale#getDefault(Locale.Category)}. The returned result is resolved and
+     * bases on the {@code Locale#getDefault(Locale.Category)}. It is one of the strings defined in
+     * {@see HourCycle}, e.g. {@code HourCycle#H11}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @HourCycle.HourCycleTypes
+    public static String getHourCycle() {
+        return getHourCycle(true);
+    }
+
+    /**
+     * Return the hour cycle setting of the inputted {@link Locale}. The returned result is resolved
+     * and based on the input {@code Locale}. It is one of the strings defined in
+     * {@see HourCycle}, e.g. {@code HourCycle#H11}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @HourCycle.HourCycleTypes
+    public static String getHourCycle(@NonNull Locale locale) {
+        return getHourCycle(locale, true);
+    }
+
+    /**
+     * Return the user's preference of the hour cycle which is from
+     * {@link Locale#getDefault(Locale.Category)}, e.g. {@code HourCycle#H11}.
+     *
+     * @param resolved If the {@code Locale#getDefault(Locale.Category)} contains hour cycle subtag,
+     *                 this argument is ignored. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain hour cycle subtag
+     *                 and the resolved argument is true, this function tries to find the default
+     *                 hour cycle for the {@code Locale#getDefault(Locale.Category)}. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain hour cycle subtag
+     *                 and the resolved argument is false, this function returns empty string
+     *                 , i.e. {@code HourCycle#DEFAULT}.
+     * @return {@link HourCycle.HourCycleTypes} If the malformed hour cycle format was specified
+     * in the hour cycle subtag, e.g. en-US-u-hc-h32, this function returns empty string, i.e.
+     * {@code HourCycle#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @HourCycle.HourCycleTypes
+    public static String getHourCycle(
+            boolean resolved) {
+        Locale defaultLocale = (Build.VERSION.SDK_INT >= VERSION_CODES.N)
+                ? Api24Impl.getDefaultLocale()
+                : getDefaultLocale();
+        return getHourCycle(defaultLocale, resolved);
+    }
+
+    /**
+     * Return the hour cycle setting of the inputted {@link Locale}. E.g. "en-US-u-hc-h23".
+     *
+     * @param locale   The {@code Locale} to get the hour cycle.
+     * @param resolved If the given {@code Locale} contains hour cycle subtag, this argument is
+     *                 ignored. If the given {@code Locale} doesn't contain hour cycle subtag and
+     *                 the resolved argument is true, this function tries to find the default
+     *                 hour cycle for the given {@code Locale}. If the given {@code Locale} doesn't
+     *                 contain hour cycle subtag and the resolved argument is false, this function
+     *                 return empty string, i.e. {@code HourCycle#DEFAULT}.
+     * @return {@link HourCycle.HourCycleTypes} If the malformed hour cycle format was specified
+     * in the hour cycle subtag, e.g. en-US-u-hc-h32, this function returns empty string, i.e.
+     * {@code HourCycle#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @HourCycle.HourCycleTypes
+    public static String getHourCycle(@NonNull Locale locale, boolean resolved) {
+        String result = getUnicodeLocaleType(HourCycle.U_EXTENSION_TAG,
+                HourCycle.DEFAULT, locale, resolved);
+        if (result != null) {
+            return result;
+        }
+        if (BuildCompat.isAtLeastT()) {
+            return Api33Impl.getHourCycle(locale);
+        } else {
+            return getBaseHourCycle(locale);
+        }
+    }
+
+    /** APIs to get the user's preference of Calendar. */
+    public static class CalendarType {
+        private static final String U_EXTENSION_TAG = "ca";
+        /** Chinese Calendar */
+        public static final String CHINESE = "chinese";
+        /** Dangi Calendar (Korea Calendar) */
+        public static final String DANGI = "dangi";
+        /** Gregorian Calendar */
+        public static final String GREGORIAN = "gregorian";
+        /** Hebrew Calendar */
+        public static final String HEBREW = "hebrew";
+        /** Indian National Calendar */
+        public static final String INDIAN = "indian";
+        /** Islamic Calendar */
+        public static final String ISLAMIC = "islamic";
+        /** Islamic Calendar (tabular, civil epoch) */
+        public static final String ISLAMIC_CIVIL = "islamic-civil";
+        /** Islamic Calendar (Saudi Arabia, sighting) */
+        public static final String ISLAMIC_RGSA = "islamic-rgsa";
+        /** Islamic Calendar (tabular, astronomical epoch) */
+        public static final String ISLAMIC_TBLA = "islamic-tbla";
+        /** Islamic Calendar (Umm al-Qura) */
+        public static final String ISLAMIC_UMALQURA = "islamic-umalqura";
+        /** Persian Calendar */
+        public static final String PERSIAN = "persian";
+        /** Default calendar for the locale */
+        public static final String DEFAULT = "";
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @StringDef({
+                CHINESE,
+                DANGI,
+                GREGORIAN,
+                HEBREW,
+                INDIAN,
+                ISLAMIC,
+                ISLAMIC_CIVIL,
+                ISLAMIC_RGSA,
+                ISLAMIC_TBLA,
+                ISLAMIC_UMALQURA,
+                PERSIAN,
+                DEFAULT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface CalendarTypes {
+        }
+
+        private CalendarType() {
+        }
+    }
+
+    /**
+     * Return the user's preference of the calendar type which is from {@link
+     * Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on
+     * the {@code Locale#getDefault(Locale.Category)} settings. It is one of the strings defined in
+     * {@see CalendarType}, e.g. {@code CalendarType#CHINESE}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @CalendarType.CalendarTypes
+    public static String getCalendarType() {
+        return getCalendarType(true);
+    }
+
+    /**
+     * Return the calendar type of the inputted {@link Locale}. The returned result is resolved and
+     * based on the input {@link Locale} settings. It is one of the strings defined in
+     * {@see CalendarType}, e.g. {@code CalendarType#CHINESE}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @CalendarType.CalendarTypes
+    public static String getCalendarType(@NonNull Locale locale) {
+        return getCalendarType(locale, true);
+    }
+
+    /**
+     * Return the user's preference of the calendar type which is from {@link
+     * Locale#getDefault(Category)}, e.g. {@code CalendarType#CHINESE}.
+     *
+     * @param resolved If the {@code Locale#getDefault(Locale.Category)} contains calendar type
+     *                 subtag, this argument is ignored. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain calendar type
+     *                 subtag and the resolved argument is true, this function tries to find
+     *                 the default calendar type for the
+     *                 {@code Locale#getDefault(Locale.Category)}. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain calendar type
+     *                 subtag and the resolved argument is false, this function returns empty string
+     *                 , i.e. {@code CalendarType#DEFAULT}.
+     * @return {@link CalendarType.CalendarTypes} If the malformed calendar type format was
+     * specified in the calendar type subtag, e.g. en-US-u-ca-calendar, this function returns
+     * empty string, i.e. {@code CalendarType#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @CalendarType.CalendarTypes
+    public static String getCalendarType(boolean resolved) {
+        Locale defaultLocale = (Build.VERSION.SDK_INT >= VERSION_CODES.N)
+                ? Api24Impl.getDefaultLocale()
+                : getDefaultLocale();
+        return getCalendarType(defaultLocale, resolved);
+    }
+
+    /**
+     * Return the calendar type of the inputted {@link Locale}, e.g. {@code CalendarType#CHINESE}.
+     *
+     * @param locale   The {@link Locale} to get the calendar type.
+     * @param resolved If the given {@code Locale} contains calendar type subtag, this argument is
+     *                 ignored. If the given {@code Locale} doesn't contain calendar type subtag and
+     *                 the resolved argument is true, this function tries to find the default
+     *                 calendar type for the given {@code Locale}. If the given {@code Locale}
+     *                 doesn't contain calendar type subtag and the resolved argument is false, this
+     *                 function return empty string, i.e. {@code CalendarType#DEFAULT}.
+     * @return {@link CalendarType.CalendarTypes} If the malformed calendar type format was
+     * specified in the calendar type subtag, e.g. en-US-u-ca-calendar, this function returns
+     * empty string, i.e. {@code CalendarType#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @CalendarType.CalendarTypes
+    public static String getCalendarType(@NonNull Locale locale, boolean resolved) {
+        String result = getUnicodeLocaleType(CalendarType.U_EXTENSION_TAG,
+                CalendarType.DEFAULT, locale, resolved);
+        if (result != null) {
+            return result;
+        }
+        if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
+            return Api24Impl.getCalendarType(locale);
+        } else {
+            return resolved ? CalendarType.GREGORIAN : CalendarType.DEFAULT;
+        }
+    }
+
+    /** APIs to get the user's preference of temperature unit. */
+    public static class TemperatureUnit {
+        private static final String U_EXTENSION_TAG = "mu";
+        /** Celsius */
+        public static final String CELSIUS = "celsius";
+        /** Fahrenheit */
+        public static final String FAHRENHEIT = "fahrenhe";
+        /** Kelvin */
+        public static final String KELVIN = "kelvin";
+        /** Default Temperature for the locale */
+        public static final String DEFAULT = "";
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @StringDef({
+                CELSIUS,
+                FAHRENHEIT,
+                KELVIN,
+                DEFAULT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TemperatureUnits {
+        }
+
+        private TemperatureUnit() {
+        }
+    }
+
+    /**
+     * Return the user's preference of the temperature unit which is from {@link
+     * Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on the
+     * {@code Locale#getDefault(Locale.Category)} settings. It is one of the strings defined in
+     * {@see TemperatureUnit}, e.g. {@code TemperatureUnit#FAHRENHEIT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @TemperatureUnit.TemperatureUnits
+    public static String getTemperatureUnit() {
+        return getTemperatureUnit(true);
+    }
+
+    /**
+     * Return the temperature unit of the inputted {@link Locale}. It is one of the strings
+     * defined in {@see TemperatureUnit}, e.g. {@code TemperatureUnit#FAHRENHEIT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @TemperatureUnit.TemperatureUnits
+    public static String getTemperatureUnit(
+            @NonNull Locale locale) {
+        return getTemperatureUnit(locale, true);
+    }
+
+    /**
+     * Return the user's preference of the temperature unit which is from {@link
+     * Locale#getDefault(Locale.Category)}, e.g. {@code TemperatureUnit#FAHRENHEIT}.
+     *
+     * @param resolved If the {@code Locale#getDefault(Locale.Category)} contains temperature unit
+     *                 subtag, this argument is ignored. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain temperature unit
+     *                 subtag and the resolved argument is true, this function tries to find
+     *                 the default temperature unit for the
+     *                 {@code Locale#getDefault(Locale.Category)}. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain temperature unit
+     *                 subtag and the resolved argument is false, this function returns empty string
+     *                 , i.e. {@code TemperatureUnit#DEFAULT}.
+     * @return {@link TemperatureUnit.TemperatureUnits} If the malformed temperature unit format was
+     * specified in the temperature unit subtag, e.g. en-US-u-mu-temperature, this function returns
+     * empty string, i.e. {@code TemperatureUnit#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @TemperatureUnit.TemperatureUnits
+    public static String getTemperatureUnit(boolean resolved) {
+        Locale defaultLocale = (Build.VERSION.SDK_INT >= VERSION_CODES.N)
+                ? Api24Impl.getDefaultLocale()
+                : getDefaultLocale();
+        return getTemperatureUnit(defaultLocale, resolved);
+    }
+
+    /**
+     * Return the temperature unit of the inputted {@link Locale}. E.g. "fahrenheit"
+     *
+     * @param locale   The {@link Locale} to get the temperature unit.
+     * @param resolved If the given {@code Locale} contains temperature unit subtag, this argument
+     *                 is ignored. If the given {@code Locale} doesn't contain temperature unit
+     *                 subtag and the resolved argument is true, this function tries to find
+     *                 the default temperature unit for the given {@code Locale}. If the given
+     *                 {@code Locale} doesn't contain temperature unit subtag and the resolved
+     *                 argument is false, this function return empty string, i.e.
+     *                 {@code TemperatureUnit#DEFAULT}.
+     * @return {@link TemperatureUnit.TemperatureUnits} If the malformed temperature unit format was
+     * specified in the temperature unit subtag, e.g. en-US-u-mu-temperature, this function returns
+     * empty string, i.e. {@code TemperatureUnit#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @TemperatureUnit.TemperatureUnits
+    public static String getTemperatureUnit(@NonNull Locale locale, boolean resolved) {
+        String result = getUnicodeLocaleType(TemperatureUnit.U_EXTENSION_TAG,
+                TemperatureUnit.DEFAULT, locale, resolved);
+        if (result != null) {
+            return result;
+        }
+        if (BuildCompat.isAtLeastT()) {
+            return Api33Impl.getResolvedTemperatureUnit(locale);
+        } else {
+            return getTemperatureHardCoded(locale);
+        }
+    }
+
+    /** APIs to get the user's preference of the first day of week. */
+    public static class FirstDayOfWeek {
+        private static final String U_EXTENSION_TAG = "fw";
+        /** Sunday */
+        public static final String SUNDAY = "sun";
+        /** Monday */
+        public static final String MONDAY = "mon";
+        /** Tuesday */
+        public static final String TUESDAY = "tue";
+        /** Wednesday */
+        public static final String WEDNESDAY = "wed";
+        /** Thursday */
+        public static final String THURSDAY = "thu";
+        /** Friday */
+        public static final String FRIDAY = "fri";
+        /** Saturday */
+        public static final String SATURDAY = "sat";
+        /** Default first day of week for the locale */
+        public static final String DEFAULT = "";
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @StringDef({
+                SUNDAY,
+                MONDAY,
+                TUESDAY,
+                WEDNESDAY,
+                THURSDAY,
+                FRIDAY,
+                SATURDAY,
+                DEFAULT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Days {
+        }
+
+        private FirstDayOfWeek() {
+        }
+    }
+
+    /**
+     * Return the user's preference of the first day of week which is from
+     * {@link Locale#getDefault(Locale.Category)}. The returned result is resolved and bases on the
+     * {@code Locale#getDefault(Locale.Category)} settings. It is one of the strings defined in
+     * {@see FirstDayOfWeek}, e.g. {@code FirstDayOfWeek#SUNDAY}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @FirstDayOfWeek.Days
+    public static String getFirstDayOfWeek() {
+        return getFirstDayOfWeek(true);
+    }
+
+    /**
+     * Return the first day of week of the inputted {@link Locale}. The returned result is resolved
+     * and based on the input {@code Locale} settings. It is one of the strings defined in
+     * {@see FirstDayOfWeek}, e.g. {@code FirstDayOfWeek#SUNDAY}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @FirstDayOfWeek.Days
+    public static String getFirstDayOfWeek(@NonNull Locale locale) {
+        return getFirstDayOfWeek(locale, true);
+    }
+
+    /**
+     * Return the user's preference of the first day of week which is from {@link
+     * Locale#getDefault(Locale.Category)}, e.g. {@code FirstDayOfWeek#SUNDAY}.
+     *
+     * @param resolved If the {@code Locale#getDefault(Locale.Category)} contains first day of week
+     *                 subtag, this argument is ignored. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain first day of week
+     *                 subtag and the resolved argument is true, this function tries to find
+     *                 the default first day of week for the
+     *                 {@code Locale#getDefault(Locale.Category)}. If the
+     *                 {@code Locale#getDefault(Locale.Category)} doesn't contain first day of week
+     *                 subtag and the resolved argument is false, this function returns empty string
+     *                 , i.e. {@code FirstDayOfWeek#DEFAULT}.
+     * @return {@link FirstDayOfWeek.Days} If the malformed first day of week format was specified
+     * in the first day of week subtag, e.g. en-US-u-fw-days, this function returns empty string,
+     * i.e. {@code FirstDayOfWeek#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @FirstDayOfWeek.Days
+    public static String getFirstDayOfWeek(boolean resolved) {
+        Locale defaultLocale = (Build.VERSION.SDK_INT >= VERSION_CODES.N)
+                ? Api24Impl.getDefaultLocale()
+                : getDefaultLocale();
+        return getFirstDayOfWeek(defaultLocale, resolved);
+    }
+
+    /**
+     * Return the first day of week of the inputted {@link Locale},
+     * e.g. {@code FirstDayOfWeek#SUNDAY}.
+     *
+     * @param locale   The {@link Locale} to get the first day of week.
+     * @param resolved If the given {@code Locale} contains first day of week subtag, this argument
+     *                 is ignored. If the given {@code Locale} doesn't contain first day of week
+     *                 subtag and the resolved argument is true, this function tries to find
+     *                 the default first day of week for the given {@code Locale}. If the given
+     *                 {@code Locale} doesn't contain first day of week subtag and the resolved
+     *                 argument is false, this function return empty string, i.e.
+     *                 {@code FirstDayOfWeek#DEFAULT}.
+     * @return {@link FirstDayOfWeek.Days} If the malformed first day of week format was
+     * specified in the first day of week subtag, e.g. en-US-u-fw-days, this function returns
+     * empty string, i.e. {@code FirstDayOfWeek#DEFAULT}.
+     */
+    @NonNull
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @FirstDayOfWeek.Days
+    public static String getFirstDayOfWeek(
+            @NonNull Locale locale, boolean resolved) {
+        String result = getUnicodeLocaleType(FirstDayOfWeek.U_EXTENSION_TAG,
+                FirstDayOfWeek.DEFAULT, locale, resolved);
+        return result != null ? result : getBaseFirstDayOfWeek(locale);
+    }
+
+    private static String getUnicodeLocaleType(String tag, String defaultValue, Locale locale,
+            boolean resolved) {
+        String ext = locale.getUnicodeLocaleType(tag);
+        if (ext != null) {
+            return ext;
+        }
+        if (!resolved) {
+            return defaultValue;
+        }
+        return null;
+    }
+
+
+    // Warning: This list of country IDs must be in alphabetical order for binarySearch to
+    // work correctly.
+    private static final String[] WEATHER_FAHRENHEIT_COUNTRIES =
+            {"BS", "BZ", "KY", "PR", "PW", "US"};
+
+    @TemperatureUnit.TemperatureUnits
+    private static String getTemperatureHardCoded(Locale locale) {
+        return Arrays.binarySearch(WEATHER_FAHRENHEIT_COUNTRIES, locale.getCountry()) >= 0
+                ? TemperatureUnit.FAHRENHEIT
+                : TemperatureUnit.CELSIUS;
+    }
+
+    @HourCycle.HourCycleTypes
+    private static String getBaseHourCycle(@NonNull Locale locale) {
+        String pattern =
+                android.text.format.DateFormat.getBestDateTimePattern(
+                        locale, "jm");
+        return pattern.contains("H") ? HourCycle.H23 : HourCycle.H12;
+    }
+
+    @FirstDayOfWeek.Days
+    private static String getBaseFirstDayOfWeek(@NonNull Locale locale) {
+        // A known bug affects both the {@code android.icu.util.Calendar} and
+        // {@code java.util.Calendar}: they ignore the "fw" field in the -u- extension, even if
+        // present. So please do not remove the explicit check on getUnicodeLocaleType,
+        // which protects us from that bug.
+        return getStringOfFirstDayOfWeek(
+                java.util.Calendar.getInstance(locale).getFirstDayOfWeek());
+    }
+
+    private static String getStringOfFirstDayOfWeek(int fw) {
+        String[] arrDays = {
+                FirstDayOfWeek.SUNDAY,
+                FirstDayOfWeek.MONDAY,
+                FirstDayOfWeek.TUESDAY,
+                FirstDayOfWeek.WEDNESDAY,
+                FirstDayOfWeek.THURSDAY,
+                FirstDayOfWeek.FRIDAY,
+                FirstDayOfWeek.SATURDAY};
+        return fw >= 1 && fw <= 7 ? arrDays[fw - 1] : FirstDayOfWeek.DEFAULT;
+    }
+
+    private static Locale getDefaultLocale() {
+        return Locale.getDefault();
+    }
+
+    @RequiresApi(VERSION_CODES.N)
+    private static class Api24Impl {
+        @DoNotInline
+        @CalendarType.CalendarTypes
+        static String getCalendarType(@NonNull Locale locale) {
+            return android.icu.util.Calendar.getInstance(locale).getType();
+        }
+
+        @DoNotInline
+        static Locale getDefaultLocale() {
+            return Locale.getDefault(Category.FORMAT);
+        }
+
+        private Api24Impl() {
+        }
+    }
+
+    @RequiresApi(VERSION_CODES.TIRAMISU)
+    private static class Api33Impl {
+        @DoNotInline
+        @TemperatureUnit.TemperatureUnits
+        static String getResolvedTemperatureUnit(@NonNull Locale locale) {
+            LocalizedNumberFormatter nf = NumberFormatter.with()
+                    .usage("weather")
+                    .unit(MeasureUnit.CELSIUS)
+                    .locale(locale);
+            String unit = nf.format(1).getOutputUnit().getIdentifier();
+            if (unit.startsWith(TemperatureUnit.FAHRENHEIT)) {
+                return TemperatureUnit.FAHRENHEIT;
+            }
+            return unit;
+        }
+
+        @DoNotInline
+        @HourCycle.HourCycleTypes
+        static String getHourCycle(@NonNull Locale locale) {
+            return getHourCycleType(
+                    DateTimePatternGenerator.getInstance(locale).getDefaultHourCycle());
+        }
+
+        @HourCycle.HourCycleTypes
+        private static String getHourCycleType(
+                DateFormat.HourCycle hourCycle) {
+            switch (hourCycle) {
+                case HOUR_CYCLE_11:
+                    return HourCycle.H11;
+                case HOUR_CYCLE_12:
+                    return HourCycle.H12;
+                case HOUR_CYCLE_23:
+                    return HourCycle.H23;
+                case HOUR_CYCLE_24:
+                    return HourCycle.H24;
+                default:
+                    return HourCycle.DEFAULT;
+            }
+        }
+
+        private Api33Impl() {
+        }
+    }
+
+    private LocalePreferences() {
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/util/Function.java b/core/core/src/main/java/androidx/core/util/Function.java
new file mode 100644
index 0000000..682c961
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/util/Function.java
@@ -0,0 +1,32 @@
+/*
+ * 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.core.util;
+
+/**
+ * Compat version of {@link java.util.function.Function}
+ * @param <T> the type of the input to the operation
+ * @param <R>: the type of the output of the function
+ */
+@FunctionalInterface
+public interface Function<T, R> {
+    /**
+     * Applies the function to the argument parameter.
+     *
+     * @param t the argument for the function
+     * @return the result after applying function
+     */
+    R apply(T t);
+}
diff --git a/core/core/src/main/java/androidx/core/util/TypedValueCompat.java b/core/core/src/main/java/androidx/core/util/TypedValueCompat.java
new file mode 100644
index 0000000..49f3bab
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/util/TypedValueCompat.java
@@ -0,0 +1,176 @@
+/*
+ * 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.core.util;
+
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.util.TypedValue.COMPLEX_UNIT_IN;
+import static android.util.TypedValue.COMPLEX_UNIT_MM;
+import static android.util.TypedValue.COMPLEX_UNIT_PT;
+import static android.util.TypedValue.COMPLEX_UNIT_PX;
+import static android.util.TypedValue.COMPLEX_UNIT_SP;
+
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+
+/**
+ * Container for a dynamically typed data value.  Primarily used with
+ * {@link android.content.res.Resources} for holding resource values.
+ *
+ * <p>Used to convert between dimension values like DP and SP to pixels, and vice versa.
+ */
+public class TypedValueCompat {
+    private static final float INCHES_PER_PT = (1.0f / 72);
+    private static final float INCHES_PER_MM = (1.0f / 25.4f);
+
+    private TypedValueCompat() {}
+
+    /**
+     * Converts a pixel value to the given dimension, e.g. PX to DP.
+     *
+     * <p>This is the inverse of {@link TypedValue#applyDimension(int, float, DisplayMetrics)}
+     *
+     * @param unitToConvertTo The unit to convert to.
+     * @param pixelValue The raw pixels value to convert from.
+     * @param metrics Current display metrics to use in the conversion --
+     *                supplies display density and scaling information.
+     *
+     * @return A dimension value equivalent to the given number of pixels
+     * @throws IllegalArgumentException if unitToConvertTo is not valid.
+     */
+    public static float deriveDimension(
+            int unitToConvertTo,
+            float pixelValue,
+            @NonNull DisplayMetrics metrics) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.deriveDimension(unitToConvertTo, pixelValue, metrics);
+        }
+
+        switch (unitToConvertTo) {
+            case COMPLEX_UNIT_PX:
+                return pixelValue;
+            case COMPLEX_UNIT_DIP: {
+                // Avoid divide-by-zero, and return 0 since that's what the inverse function will do
+                if (metrics.density == 0) {
+                    return 0;
+                }
+                return pixelValue / metrics.density;
+            }
+            case COMPLEX_UNIT_SP:
+                // Versions earlier than U don't get the fancy non-linear scaling
+                if (metrics.scaledDensity == 0) {
+                    return 0;
+                }
+                return pixelValue / metrics.scaledDensity;
+            case COMPLEX_UNIT_PT: {
+                if (metrics.xdpi == 0) {
+                    return 0;
+                }
+                return pixelValue / metrics.xdpi / INCHES_PER_PT;
+            }
+            case COMPLEX_UNIT_IN: {
+                if (metrics.xdpi == 0) {
+                    return 0;
+                }
+                return pixelValue / metrics.xdpi;
+            }
+            case COMPLEX_UNIT_MM: {
+                if (metrics.xdpi == 0) {
+                    return 0;
+                }
+                return pixelValue / metrics.xdpi / INCHES_PER_MM;
+            }
+            default:
+                throw new IllegalArgumentException("Invalid unitToConvertTo " + unitToConvertTo);
+        }
+    }
+
+    /**
+     * Converts a density-independent pixels (DP) value to pixels
+     *
+     * <p>This is a convenience function for
+     * {@link TypedValue#applyDimension(int, float, DisplayMetrics)}
+     *
+     * @param dpValue The value in DP to convert from.
+     * @param metrics Current display metrics to use in the conversion --
+     *                supplies display density and scaling information.
+     *
+     * @return A raw pixel value
+     */
+    public static float dpToPx(float dpValue, @NonNull DisplayMetrics metrics) {
+        return TypedValue.applyDimension(COMPLEX_UNIT_DIP, dpValue, metrics);
+    }
+
+    /**
+     * Converts a pixel value to density-independent pixels (DP)
+     *
+     * <p>This is a convenience function for {@link #deriveDimension(int, float, DisplayMetrics)}
+     *
+     * @param pixelValue The raw pixels value to convert from.
+     * @param metrics Current display metrics to use in the conversion --
+     *                supplies display density and scaling information.
+     *
+     * @return A dimension value (in DP) representing the given number of pixels.
+     */
+    public static float pxToDp(float pixelValue, @NonNull DisplayMetrics metrics) {
+        return deriveDimension(COMPLEX_UNIT_DIP, pixelValue, metrics);
+    }
+
+    /**
+     * Converts a scaled pixels (SP) value to pixels
+     *
+     * <p>This is a convenience function for
+     * {@link TypedValue#applyDimension(int, float, DisplayMetrics)}
+     *
+     * @param spValue The value in SP to convert from.
+     * @param metrics Current display metrics to use in the conversion --
+     *                supplies display density and scaling information.
+     *
+     * @return A raw pixel value
+     */
+    public static float spToPx(float spValue, @NonNull DisplayMetrics metrics) {
+        return TypedValue.applyDimension(COMPLEX_UNIT_SP, spValue, metrics);
+    }
+
+    /**
+     * Converts a pixel value to scaled pixels (SP)
+     *
+     * <p>This is a convenience function for {@link #deriveDimension(int, float, DisplayMetrics)}
+     *
+     * @param pixelValue The raw pixels value to convert from.
+     * @param metrics Current display metrics to use in the conversion --
+     *                supplies display density and scaling information.
+     *
+     * @return A dimension value (in SP) representing the given number of pixels.
+     */
+    public static float pxToSp(float pixelValue, @NonNull DisplayMetrics metrics) {
+        return deriveDimension(COMPLEX_UNIT_SP, pixelValue, metrics);
+    }
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+        @DoNotInline
+        public static float deriveDimension(int unitToConvertTo, float pixelValue,
+                DisplayMetrics metrics) {
+            return TypedValue.deriveDimension(unitToConvertTo, pixelValue, metrics);
+        }
+    }
+}
diff --git a/core/core/src/main/java/androidx/core/view/VelocityTrackerCompat.java b/core/core/src/main/java/androidx/core/view/VelocityTrackerCompat.java
index a0d31d1..23fb371 100644
--- a/core/core/src/main/java/androidx/core/view/VelocityTrackerCompat.java
+++ b/core/core/src/main/java/androidx/core/view/VelocityTrackerCompat.java
@@ -16,18 +16,35 @@
 
 package androidx.core.view;
 
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.os.Build;
+import android.view.MotionEvent;
 import android.view.VelocityTracker;
 
-/**
- * Helper for accessing features in {@link VelocityTracker}.
- *
- * @deprecated Use {@link VelocityTracker} directly.
- */
-@Deprecated
+import androidx.annotation.DoNotInline;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
+
+import java.lang.annotation.Retention;
+
+/** Helper for accessing features in {@link VelocityTracker}. */
 public final class VelocityTrackerCompat {
+    @RestrictTo(LIBRARY_GROUP_PREFIX)
+    @Retention(SOURCE)
+    @IntDef(value = {
+            MotionEvent.AXIS_X,
+            MotionEvent.AXIS_Y,
+            MotionEvent.AXIS_SCROLL
+    })
+    public @interface VelocityTrackableMotionEventAxis {}
     /**
      * Call {@link VelocityTracker#getXVelocity(int)}.
-     * If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device,
+     * If running on a pre-{@link Build.VERSION_CODES#HONEYCOMB} device,
      * returns {@link VelocityTracker#getXVelocity()}.
      *
      * @deprecated Use {@link VelocityTracker#getXVelocity(int)} directly.
@@ -39,7 +56,7 @@
 
     /**
      * Call {@link VelocityTracker#getYVelocity(int)}.
-     * If running on a pre-{@link android.os.Build.VERSION_CODES#HONEYCOMB} device,
+     * If running on a pre-{@link Build.VERSION_CODES#HONEYCOMB} device,
      * returns {@link VelocityTracker#getYVelocity()}.
      *
      * @deprecated Use {@link VelocityTracker#getYVelocity(int)} directly.
@@ -49,5 +66,119 @@
         return tracker.getYVelocity(pointerId);
     }
 
+    /**
+     * Checks whether a given velocity-trackable {@link MotionEvent} axis is supported for velocity
+     * tracking by this {@link VelocityTracker} instance (refer to
+     * {@link #getAxisVelocity(VelocityTracker, int, int)} for a list of potentially
+     * velocity-trackable axes).
+     *
+     * <p>Note that the value returned from this method will stay the same for a given instance, so
+     * a single check for axis support is enough per a {@link VelocityTracker} instance.
+     *
+     * @param tracker The {@link VelocityTracker} for which to check axis support.
+     * @param axis The axis to check for velocity support.
+     * @return {@code true} if {@code axis} is supported for velocity tracking, or {@code false}
+     *         otherwise.
+     * @see #getAxisVelocity(VelocityTracker, int, int)
+     * @see #getAxisVelocity(VelocityTracker, int)
+     */
+    public static boolean isAxisSupported(@NonNull VelocityTracker tracker,
+            @VelocityTrackableMotionEventAxis int axis) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.isAxisSupported(tracker, axis);
+        }
+        return axis == MotionEvent.AXIS_X || axis == MotionEvent.AXIS_Y;
+    }
+
+    /**
+     * Equivalent to calling {@link #getAxisVelocity(VelocityTracker, int, int)} for {@code axis}
+     * and the active pointer.
+     *
+     * @param tracker The {@link VelocityTracker} from which to get axis velocity.
+     * @param axis Which axis' velocity to return.
+     * @return The previously computed velocity for {@code axis} for the active pointer if
+     *         {@code axis} is supported for velocity tracking, or 0 if velocity tracking is not
+     *         supported for the axis.
+     * @see #isAxisSupported(VelocityTracker, int)
+     * @see #getAxisVelocity(VelocityTracker, int, int)
+     */
+    public static float getAxisVelocity(@NonNull VelocityTracker tracker,
+            @VelocityTrackableMotionEventAxis int axis) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.getAxisVelocity(tracker, axis);
+        }
+        if (axis == MotionEvent.AXIS_X) {
+            return tracker.getXVelocity();
+        }
+        if (axis == MotionEvent.AXIS_Y) {
+            return tracker.getYVelocity();
+        }
+        return  0;
+    }
+
+    /**
+     * Retrieve the last computed velocity for a given motion axis. You must first call
+     * {@link VelocityTracker#computeCurrentVelocity(int)} or
+     * {@link VelocityTracker#computeCurrentVelocity(int, float)} before calling this function.
+     *
+     * <p>In addition to {@link MotionEvent#AXIS_X} and {@link MotionEvent#AXIS_Y} which have been
+     * supported since the introduction of this class, the following axes can be candidates for this
+     * method:
+     * <ul>
+     *   <li> {@link MotionEvent#AXIS_SCROLL}: supported starting
+     *        {@link Build.VERSION_CODES#UPSIDE_DOWN_CAKE}
+     * </ul>
+     *
+     * <p>Before accessing velocities of an axis using this method, check that your
+     * {@link VelocityTracker} instance supports the axis by using
+     * {@link #isAxisSupported(VelocityTracker, int)}.
+     *
+     * @param tracker The {@link VelocityTracker} from which to get axis velocity.
+     * @param axis Which axis' velocity to return.
+     * @param pointerId Which pointer's velocity to return.
+     * @return The previously computed velocity for {@code axis} for pointer ID of {@code id} if
+     *         {@code axis} is supported for velocity tracking, or 0 if velocity tracking is not
+     *         supported for the axis.
+     * @see #isAxisSupported(VelocityTracker, int)
+     */
+    public static float getAxisVelocity(
+            @NonNull VelocityTracker tracker,
+            @VelocityTrackableMotionEventAxis int axis,
+            int pointerId) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.getAxisVelocity(tracker, axis, pointerId);
+        }
+        if (axis == MotionEvent.AXIS_X) {
+            return tracker.getXVelocity(pointerId);
+        }
+        if (axis == MotionEvent.AXIS_Y) {
+            return tracker.getYVelocity(pointerId);
+        }
+        return  0;
+
+    }
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static boolean isAxisSupported(VelocityTracker velocityTracker, int axis) {
+            return velocityTracker.isAxisSupported(axis);
+        }
+
+        @DoNotInline
+        static float getAxisVelocity(VelocityTracker velocityTracker, int axis, int id) {
+            return velocityTracker.getAxisVelocity(axis, id);
+        }
+
+        @DoNotInline
+        static float getAxisVelocity(VelocityTracker velocityTracker, int axis) {
+            return velocityTracker.getAxisVelocity(axis);
+        }
+    }
+
     private VelocityTrackerCompat() {}
 }
diff --git a/core/core/src/main/java/androidx/core/view/ViewConfigurationCompat.java b/core/core/src/main/java/androidx/core/view/ViewConfigurationCompat.java
index 628a379..597e8928 100644
--- a/core/core/src/main/java/androidx/core/view/ViewConfigurationCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewConfigurationCompat.java
@@ -18,9 +18,13 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.hardware.input.InputManager;
 import android.os.Build;
 import android.util.Log;
 import android.util.TypedValue;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
 
 import androidx.annotation.DoNotInline;
@@ -147,11 +151,133 @@
             return Api28Impl.shouldShowMenuShortcutsWhenKeyboardPresent(config);
         }
         final Resources res = context.getResources();
-        final int platformResId = res.getIdentifier(
-                "config_showMenuShortcutsWhenKeyboardPresent", "bool", "android");
+        final int platformResId =
+                getPlatformResId(res, "config_showMenuShortcutsWhenKeyboardPresent", "bool");
         return platformResId != 0 && res.getBoolean(platformResId);
     }
 
+    /**
+     * Minimum absolute value of velocity to initiate a fling for a motion generated by an
+     * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on
+     * a given motion event {@code axis}.
+     *
+     * <p>Before utilizing this method to get a minimum fling velocity for a motion generated by the
+     * input device, scale the velocity of the motion events generated by the input device to pixels
+     * per second.
+     *
+     * <p>For instance, if you tracked {@link MotionEvent#AXIS_SCROLL} vertical velocities generated
+     * from a {@link InputDevice#SOURCE_ROTARY_ENCODER}, the velocity returned from
+     * {@link VelocityTracker} will be in the units with which the axis values were reported in the
+     * motion event. Before comparing that velocity against the minimum fling velocity specified
+     * here, make sure that the {@link MotionEvent#AXIS_SCROLL} velocity from the tracker is
+     * calculated in "units per second" (see {@link VelocityTracker#computeCurrentVelocity(int)},
+     * {@link VelocityTracker#computeCurrentVelocity(int, float)} to adjust your velocity
+     * computations to "per second"), and use {@link #getScaledVerticalScrollFactor} to change this
+     * velocity value to "pixels/second".
+     *
+     * <p>If the provided {@code inputDeviceId} is not valid, or if the input device whose ID is
+     * provided does not support the given motion event source and/or axis, this method will return
+     * {@code Integer.MAX_VALUE}.
+     *
+     * <h3>Obtaining the correct arguments for this method call</h3>
+     * <p><b>inputDeviceId</b>: if calling this method in response to a {@link MotionEvent}, use
+     * the device ID that is reported by the event, which can be obtained using
+     * {@link MotionEvent#getDeviceId()}. Otherwise, use a valid ID that is obtained from
+     * {@link InputDevice#getId()}, or from an {@link InputManager} instance
+     * ({@link InputManager#getInputDeviceIds()} gives all the valid input device IDs).
+     *
+     * <p><b>axis</b>: a {@link MotionEvent} may report data for multiple axes, and each axis may
+     * have multiple data points for different pointers. Use the axis for which you obtained the
+     * velocity for ({@link VelocityTracker} lets you calculate velocities for a specific axis. Use
+     * the axis for which you calculated velocity). You can use
+     * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
+     * {@link InputDevice}, from which you can derive all the valid axes for the device.
+     *
+     * <p><b>source</b>: use {@link MotionEvent#getSource()} if calling this method in response to a
+     * {@link MotionEvent}. Otherwise, use a valid source for the {@link InputDevice}. You can use
+     * {@link InputDevice#getMotionRanges()} to get all the {@link InputDevice.MotionRange}s for the
+     * {@link InputDevice}, from which you can derive all the valid sources for the device.
+     *
+     *
+     * <p>This method optimizes calls over multiple input device IDs, so caching the return value of
+     * the method is not necessary if you are handling multiple input devices.
+     *
+     * @param context the {@link Context} associated with the view.
+     * @param config the {@link ViewConfiguration} to derive the minimum fling velocity from.
+     * @param inputDeviceId the ID of the {@link InputDevice} that generated the motion triggering
+     *          fling.
+     * @param axis the axis on which the motion triggering the fling happened. This axis should be
+     *          a valid axis that can be reported by the provided input device from the provided
+     *          input device source.
+     * @param source the input source of the motion causing fling. This source should be a valid
+     *          source for the {@link InputDevice} whose ID is {@code inputDeviceId}.
+     *
+     * @return the minimum velocity, in pixels/second, to trigger fling.
+     *
+     * @see InputDevice#getMotionRange(int, int)
+     * @see InputDevice#getMotionRanges()
+     * @see VelocityTracker#getAxisVelocity(int, int)
+     * @see VelocityTracker#getAxisVelocity(int)
+     */
+    public static int getScaledMinimumFlingVelocity(
+            @NonNull Context context,
+            @NonNull ViewConfiguration config,
+            int inputDeviceId,
+            int axis,
+            int source) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.getScaledMinimumFlingVelocity(config, inputDeviceId, axis, source);
+        }
+
+        if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) {
+            return Integer.MAX_VALUE;
+        }
+
+        Resources res = context.getResources();
+        int platformResId = getPreApi34MinimumFlingVelocityResId(res, source, axis);
+        if (platformResId != 0) {
+            int minFlingVelocity = res.getDimensionPixelSize(platformResId);
+            return minFlingVelocity < 0 ? Integer.MAX_VALUE : minFlingVelocity;
+        }
+
+        return config.getScaledMinimumFlingVelocity();
+    }
+
+    /**
+     * Maximum absolute value of velocity to initiate a fling for a motion generated by an
+     * {@link InputDevice} with an id of {@code inputDeviceId}, from an input {@code source} and on
+     * a given motion event {@code axis}.
+     *
+     * <p>Similar to
+     * {@link #getScaledMinimumFlingVelocity(Context, ViewConfiguration, int, int, int)}, but for
+     * maximum fling velocity, instead of minimum. Also, unlike that method which returns
+     * {@code Integer.MAX_VALUE} for bad input device ID, source and/or motion event axis inputs,
+     * this method returns {@code Integer.MIN_VALUE} for such bad inputs.
+     */
+    public static int getScaledMaximumFlingVelocity(
+            @NonNull Context context,
+            @NonNull ViewConfiguration config,
+            int inputDeviceId,
+            int axis,
+            int source) {
+        if (Build.VERSION.SDK_INT >= 34) {
+            return Api34Impl.getScaledMaximumFlingVelocity(config, inputDeviceId, axis, source);
+        }
+
+        if (!isInputDeviceInfoValid(inputDeviceId, axis, source)) {
+            return Integer.MIN_VALUE;
+        }
+
+        Resources res = context.getResources();
+        int platformResId = getPreApi34MaximumFlingVelocityResId(res, source, axis);
+        if (platformResId != 0) {
+            int maxFlingVelocity = res.getDimensionPixelSize(platformResId);
+            return maxFlingVelocity < 0 ? Integer.MIN_VALUE : maxFlingVelocity;
+        }
+
+        return config.getScaledMaximumFlingVelocity();
+    }
+
     private ViewConfigurationCompat() {
     }
 
@@ -189,4 +315,52 @@
             return viewConfiguration.shouldShowMenuShortcutsWhenKeyboardPresent();
         }
     }
+
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static int getScaledMaximumFlingVelocity(
+                @NonNull ViewConfiguration viewConfiguration,
+                int inputDeviceId,
+                int axis,
+                int source) {
+            return viewConfiguration.getScaledMaximumFlingVelocity(inputDeviceId, axis, source);
+        }
+
+        @DoNotInline
+        static int getScaledMinimumFlingVelocity(
+                @NonNull ViewConfiguration viewConfiguration,
+                int inputDeviceId,
+                int axis,
+                int source) {
+            return viewConfiguration.getScaledMinimumFlingVelocity(inputDeviceId, axis, source);
+        }
+    }
+
+    private static int getPreApi34MaximumFlingVelocityResId(Resources res, int source, int axis) {
+        if (source == InputDeviceCompat.SOURCE_ROTARY_ENCODER && axis == MotionEvent.AXIS_SCROLL) {
+            return getPlatformResId(res, "config_viewMaxRotaryEncoderFlingVelocity", "dimen");
+        }
+        return 0;
+    }
+
+    private static int getPreApi34MinimumFlingVelocityResId(Resources res, int source, int axis) {
+        if (source == InputDeviceCompat.SOURCE_ROTARY_ENCODER && axis == MotionEvent.AXIS_SCROLL) {
+            return getPlatformResId(res, "config_viewMinRotaryEncoderFlingVelocity", "dimen");
+        }
+        return 0;
+    }
+
+    private static int getPlatformResId(Resources res, String name, String defType) {
+        return res.getIdentifier(name, defType, /* defPackage= */ "android");
+    }
+
+    private static boolean isInputDeviceInfoValid(int id, int axis, int source) {
+        InputDevice device = InputDevice.getDevice(id);
+        return device != null && device.getMotionRange(axis, source) != null;
+    }
 }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
index 3157094..957d459 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityEventCompat.java
@@ -169,6 +169,11 @@
     public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000;
 
     /**
+     * Represents the event of a scroll having completed and brought the target node on screen.
+     */
+    public static final int TYPE_VIEW_TARGETED_BY_SCROLL = 0x04000000;
+
+    /**
      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
      * The type of change is not defined.
      */
@@ -270,6 +275,7 @@
      * @see AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
      * @see AccessibilityEvent#TYPE_VIEW_SCROLLED
      * @see AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
+     * @see AccessibilityEvent#TYPE_VIEW_TARGETED_BY_SCROLL
      * @see #TYPE_ANNOUNCEMENT
      * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
      * @see #TYPE_GESTURE_DETECTION_START
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 3837165..6e63749 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -654,6 +654,40 @@
                         :   null, android.R.id.accessibilityActionShowTextSuggestions, null,
                         null, null);
 
+        /**
+         * Action that brings fully on screen the next node in the specified direction.
+         *
+         * <p>
+         *     This should include wrapping around to the next/previous row, column, etc. in a
+         *     collection if one is available. If there is no node in that direction, the action
+         *     should fail and return false.
+         * </p>
+         * <p>
+         *     This action should be used instead of
+         *     {@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION} when a widget does not
+         *     have clear row and column semantics or if a directional search is needed to find a
+         *     node in a complex ViewGroup where individual nodes may span multiple rows or
+         *     columns. The implementing widget must send a
+         *     {@link AccessibilityEventCompat#TYPE_VIEW_TARGETED_BY_SCROLL} accessibility event
+         *     with the scroll target as the source.  An accessibility service can listen for this
+         *     event, inspect its source, and use the result when determining where to place
+         *     accessibility focus.
+         * <p>
+         *     <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_DIRECTION_INT}. This is a
+         *     required argument.<br>
+         * </p>
+         */
+        @NonNull
+        @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
+        public static final AccessibilityActionCompat ACTION_SCROLL_IN_DIRECTION =
+                new AccessibilityActionCompat(BuildCompat.isAtLeastU()
+                        ? AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_IN_DIRECTION
+                        : null,
+                        // TODO (267511848): update ID value once U resources are finalized.
+                        BuildCompat.isAtLeastU()
+                                ? android.R.id.accessibilityActionScrollInDirection : -1,
+                        null, null, null);
+
         final Object mAction;
         private final int mId;
         private final Class<? extends CommandArguments> mViewCommandArgumentClass;
@@ -1363,6 +1397,7 @@
     private static final int BOOLEAN_PROPERTY_IS_SHOWING_HINT = 0x00000004;
     private static final int BOOLEAN_PROPERTY_IS_TEXT_ENTRY_KEY = 0x00000008;
     private static final int BOOLEAN_PROPERTY_HAS_REQUEST_INITIAL_ACCESSIBILITY_FOCUS = 1 << 5;
+    private static final int BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING = 1 << 26;
 
     private final AccessibilityNodeInfo mInfo;
 
@@ -1751,6 +1786,71 @@
     public static final String ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT =
             "android.view.accessibility.action.ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT";
 
+    /**
+     * <p>Argument to represent the direction when using
+     * {@link AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}.</p>
+     *
+     * <p>
+     *     The value of this argument can be one of:
+     *     <ul>
+     *         <li>{@link View#FOCUS_DOWN}</li>
+     *         <li>{@link View#FOCUS_UP}</li>
+     *         <li>{@link View#FOCUS_LEFT}</li>
+     *         <li>{@link View#FOCUS_RIGHT}</li>
+     *         <li>{@link View#FOCUS_FORWARD}</li>
+     *         <li>{@link View#FOCUS_BACKWARD}</li>
+     *     </ul>
+     * </p>
+     */
+    public static final String ACTION_ARGUMENT_DIRECTION_INT =
+            "androidx.core.view.accessibility.action.ARGUMENT_DIRECTION_INT";
+
+    /**
+     * <p>Argument to represent the scroll amount as a percent of the visible area of a node, with
+     * 1.0F as the default. Values smaller than 1.0F represent a partial scroll of the node, and
+     * values larger than 1.0F represent a scroll that extends beyond the currently visible node
+     * Rect. Setting this to {@link Float#POSITIVE_INFINITY} or to another "too large" value should
+     * scroll to the end of the node. Negative values should not be used with this argument.
+     * </p>
+     *
+     * <p>
+     *     This argument should be used with the following scroll actions:
+     *     <ul>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_FORWARD}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_BACKWARD}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_UP}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_DOWN}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_LEFT}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_RIGHT}</li>
+     *     </ul>
+     * </p>
+     * <p>
+     *     Example: if a view representing a list of items implements
+     *     {@link AccessibilityActionCompat#ACTION_SCROLL_FORWARD} to scroll forward by an entire
+     *     screen
+     *     (one "page"), then passing a value of .25F via this argument should scroll that view
+     *     only by 1/4th of a screen. Passing a value of 1.50F via this argument should scroll the
+     *     view by 1 1/2 screens or to end of the node if the node doesn't extend to 1 1/2 screens.
+     * </p>
+     *
+     * <p>
+     *     This argument should not be used with the following scroll actions, which don't cleanly
+     *     conform to granular scroll semantics:
+     *     <ul>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}</li>
+     *         <li>{@link AccessibilityActionCompat#ACTION_SCROLL_TO_POSITION}</li>
+     *     </ul>
+     * </p>
+     *
+     * <p>
+     *     Views that support this argument should set
+     *     {@link #setGranularScrollingSupported(boolean)} to true. Clients should use
+     *     {@link #isGranularScrollingSupported()} to check if granular scrolling is supported.
+     * </p>
+     */
+    public static final String ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT =
+            "androidx.core.view.accessibility.action.ARGUMENT_SCROLL_AMOUNT_FLOAT";
+
     // Focus types
 
     /**
@@ -2730,6 +2830,36 @@
         mInfo.setScrollable(scrollable);
     }
 
+
+    /**
+     * Gets if the node supports granular scrolling.
+     *
+     * @return True if all scroll actions that could support
+     * {@link #ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT} have done so, false otherwise.
+     */
+    public boolean isGranularScrollingSupported() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING);
+    }
+
+    /**
+     * Sets if the node supports granular scrolling. This should be set to true if all scroll
+     * actions which could support {@link #ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT} have done so.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param granularScrollingSupported True if the node supports granular scrolling, false
+     *                                  otherwise.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setGranularScrollingSupported(boolean granularScrollingSupported) {
+        setBooleanProperty(BOOLEAN_PROPERTY_SUPPORTS_GRANULAR_SCROLLING,
+                granularScrollingSupported);
+    }
+
     /**
      * Gets if the node has selectable text.
      *
@@ -4609,6 +4739,11 @@
             case android.R.id.accessibilityActionDragCancel:
                 return "ACTION_DRAG_CANCEL";
             default:
+                // TODO (b/267511848): fix after Android U constants are finalized.
+                if (Build.VERSION.SDK_INT >= 34
+                        && action == android.R.id.accessibilityActionScrollInDirection) {
+                    return "ACTION_SCROLL_IN_DIRECTION";
+                }
                 return "ACTION_UNKNOWN";
         }
     }
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompat.java
index 511d9b8..91586a5 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityWindowInfoCompat.java
@@ -87,6 +87,25 @@
         return null;
     }
 
+    /**
+     * Creates a new AccessibilityWindowInfoCompat.
+     * <p>
+     * Compatibility:
+     *  <ul>
+     *      <li>Api &lt; 30: Will not wrap an
+     *      {@link android.view.accessibility.AccessibilityWindowInfo} instance.</li>
+     *  </ul>
+     * </p>
+     *
+     */
+    public AccessibilityWindowInfoCompat() {
+        if (SDK_INT >= 30) {
+            mInfo = Api30Impl.instantiateAccessibilityWindowInfo();
+        } else {
+            mInfo = null;
+        }
+    }
+
     private AccessibilityWindowInfoCompat(Object info) {
         mInfo = info;
     }
@@ -541,6 +560,18 @@
         }
     }
 
+    @RequiresApi(30)
+    private static class Api30Impl {
+        private Api30Impl() {
+            // This class is non instantiable.
+        }
+
+        @DoNotInline
+        static AccessibilityWindowInfo instantiateAccessibilityWindowInfo() {
+            return new AccessibilityWindowInfo();
+        }
+    }
+
     @RequiresApi(33)
     private static class Api33Impl {
         private Api33Impl() {
diff --git a/core/core/src/main/java/androidx/core/view/contentcapture/ContentCaptureSessionCompat.java b/core/core/src/main/java/androidx/core/view/contentcapture/ContentCaptureSessionCompat.java
index a672caa..c5c89d7 100644
--- a/core/core/src/main/java/androidx/core/view/contentcapture/ContentCaptureSessionCompat.java
+++ b/core/core/src/main/java/androidx/core/view/contentcapture/ContentCaptureSessionCompat.java
@@ -246,8 +246,7 @@
         @DoNotInline
         static void notifyViewsAppeared(
                 ContentCaptureSession contentCaptureSession, List<ViewStructure> appearedNodes) {
-            // new API in U
-            // contentCaptureSession.notifyViewsAppeared(appearedNodes);
+            contentCaptureSession.notifyViewsAppeared(appearedNodes);
         }
     }
     @RequiresApi(29)
diff --git a/core/core/src/test/resources/robolectric.properties b/core/core/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/core/core/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/credentials/credentials-play-services-auth/build.gradle b/credentials/credentials-play-services-auth/build.gradle
index dab1da2..2e458ea 100644
--- a/credentials/credentials-play-services-auth/build.gradle
+++ b/credentials/credentials-play-services-auth/build.gradle
@@ -33,13 +33,11 @@
     // Closed source dependencies
     implementation(libs.playServicesAuth){
         exclude group: "androidx.loader"
-        exclude group: "androidx.fragment"
         exclude group: "androidx.core"
     }
 
     implementation(libs.playServicesFido){
         exclude group: "androidx.loader"
-        exclude group: "androidx.fragment"
         exclude group: "androidx.core"
     }
 
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplJavaTest.java
index 5767643..36bdbc8 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplJavaTest.java
@@ -21,8 +21,10 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import androidx.core.os.BuildCompat;
 import androidx.test.core.app.ActivityScenario;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 
 import com.google.android.gms.common.ConnectionResult;
@@ -36,7 +38,11 @@
 public class CredentialProviderPlayServicesImplJavaTest {
 
     @Test
+    @SdkSuppress(maxSdkVersion = 33)
     public void isAvailableOnDevice_apiSuccess_returnsTrue() {
+        if (BuildCompat.isAtLeastU()) {
+            return; // Wait until Mockito fixes 'mock' for API 34
+        }
         ActivityScenario<TestCredentialsActivity> activityScenario =
                 ActivityScenario.launch(TestCredentialsActivity.class);
         activityScenario.onActivity(activity -> {
@@ -55,8 +61,11 @@
     }
 
     @Test
+    @SdkSuppress(maxSdkVersion = 33)
     public void isAvailableOnDevice_apiNotSuccess_returnsFalse() {
-        // TODO("If retryables are accounted for, add a third test")
+        if (BuildCompat.isAtLeastU()) {
+            return; // Wait until Mockito fixes 'mock' for API 34
+        }
         ActivityScenario<TestCredentialsActivity> activityScenario =
                 ActivityScenario.launch(TestCredentialsActivity.class);
         activityScenario.onActivity(activity -> {
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplTest.kt
index 65dbd50..63226ec 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/CredentialProviderPlayServicesImplTest.kt
@@ -16,9 +16,11 @@
 
 package androidx.credentials.playservices
 
+import androidx.core.os.BuildCompat
 import androidx.credentials.playservices.TestUtils.Companion.ConnectionResultFailureCases
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import com.google.android.gms.common.ConnectionResult
 import com.google.android.gms.common.GoogleApiAvailability
@@ -32,7 +34,11 @@
 class CredentialProviderPlayServicesImplTest {
 
     @Test
+    @SdkSuppress(maxSdkVersion = 33)
     fun isAvailableOnDevice_apiSuccess_returnsTrue() {
+        if (BuildCompat.isAtLeastU()) {
+            return // TODO(b/285651071) : Fix once Mockito fixes mock issue, around these test cases
+        }
         val activityScenario = ActivityScenario.launch(
             TestCredentialsActivity::class.java
         )
@@ -53,8 +59,11 @@
     }
 
     @Test
+    @SdkSuppress(maxSdkVersion = 33)
     fun isAvailableOnDevice_apiNotSuccess_returnsFalse() {
-        // TODO("If retryables are accounted for, add a third test")
+        if (BuildCompat.isAtLeastU()) {
+            return // Wait until Mockito fixes 'mock' for API 34
+        }
         val activityScenario = ActivityScenario.launch(
             TestCredentialsActivity::class.java
         )
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
index 969f941..45af09f 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerJavaTest.java
@@ -34,6 +34,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.HashSet;
 import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
@@ -68,7 +69,7 @@
                     CredentialProviderBeginSignInController
                             .getInstance(activity)
                             .convertRequestToPlayServices(new GetCredentialRequest(List.of(
-                                    new GetPasswordOption(true)
+                                    new GetPasswordOption(new HashSet<>(), true)
                             )));
 
             assertThat(actualResponse.getPasswordRequestOptions().isSupported()).isTrue();
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
index a783ea6..e579c2b 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
@@ -66,7 +66,7 @@
                 .convertRequestToPlayServices(
                     GetCredentialRequest(
                         listOf(
-                            GetPasswordOption(true)
+                            GetPasswordOption(isAutoSelectAllowed = true)
                         )
                     )
                 )
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
index 22a6e01..8e5e883 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
@@ -16,7 +16,6 @@
 
 package androidx.credentials.playservices
 
-import android.app.Activity
 import android.content.Context
 import android.os.CancellationSignal
 import android.util.Log
@@ -54,21 +53,21 @@
     @VisibleForTesting
     var googleApiAvailability = GoogleApiAvailability.getInstance()
     override fun onGetCredential(
+        context: Context,
         request: GetCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>
     ) {
         if (cancellationReviewer(cancellationSignal)) { return }
-        CredentialProviderBeginSignInController(activity).invokePlayServices(
+        CredentialProviderBeginSignInController(context).invokePlayServices(
             request, callback, executor, cancellationSignal)
     }
 
     @SuppressWarnings("deprecated")
     override fun onCreateCredential(
+        context: Context,
         request: CreateCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>
@@ -77,7 +76,7 @@
         when (request) {
             is CreatePasswordRequest -> {
                 CredentialProviderCreatePasswordController.getInstance(
-                    activity).invokePlayServices(
+                    context).invokePlayServices(
                     request,
                     callback,
                     executor,
@@ -85,7 +84,7 @@
             }
             is CreatePublicKeyCredentialRequest -> {
                 CredentialProviderCreatePublicKeyCredentialController.getInstance(
-                    activity).invokePlayServices(
+                    context).invokePlayServices(
                     request,
                     callback,
                     executor,
@@ -104,8 +103,9 @@
     }
 
     // https://developers.google.com/android/reference/com/google/android/gms/common/ConnectionResult
-    // TODO(b/262924507): Most codes indicate failure, but two indicate retry-ability -
-    //  look into handling.
+    // There is one error code that supports retry API_DISABLED_FOR_CONNECTION but it would not
+    // be useful to retry that one because our connection to GMSCore is a static variable
+    // (see GoogleApiAvailability.getInstance()) so we cannot recreate the connection to retry.
     private fun isGooglePlayServicesAvailable(context: Context): Int {
         return googleApiAvailability.isGooglePlayServicesAvailable(context)
     }
@@ -116,33 +116,23 @@
         executor: Executor,
         callback: CredentialManagerCallback<Void?, ClearCredentialException>
     ) {
-        if (cancellationReviewer(cancellationSignal)) {
-            return
-        }
+        if (cancellationReviewer(cancellationSignal)) { return }
         Identity.getSignInClient(context)
             .signOut()
             .addOnSuccessListener {
-                var isCanceled = false
-                cancellationSignal?.let {
-                    isCanceled = cancellationSignal.isCanceled
-                }
-                if (!isCanceled) {
+                cancellationReviewerWithCallback(cancellationSignal, {
                     Log.i(TAG, "During clear credential, signed out successfully!")
                     executor.execute { callback.onResult(null) }
-                }
+                })
             }
             .addOnFailureListener { e ->
                 run {
-                    var isCanceled = false
-                    cancellationSignal?.let {
-                        isCanceled = cancellationSignal.isCanceled
-                    }
-                    if (!isCanceled) {
+                    cancellationReviewerWithCallback(cancellationSignal, {
                         Log.w(TAG, "During clear credential sign out failed with $e")
                         executor.execute {
                             callback.onError(ClearCredentialUnknownException(e.message))
                         }
-                    }
+                    })
                 }
             }
     }
@@ -150,14 +140,21 @@
     companion object {
         private const val TAG = "PlayServicesImpl"
 
+        internal fun cancellationReviewerWithCallback(
+            cancellationSignal: CancellationSignal?,
+            callback: () -> Unit,
+        ) {
+            if (!cancellationReviewer(cancellationSignal)) {
+                callback()
+            }
+        }
+
         internal fun cancellationReviewer(
             cancellationSignal: CancellationSignal?
         ): Boolean {
             if (cancellationSignal != null) {
                 if (cancellationSignal.isCanceled) {
                     Log.i(TAG, "the flow has been canceled")
-                    // TODO(b/262924507): See if there's a better way to message pass to avoid
-                    //  if statements and to use a single listener instead
                     return true
                 }
             } else {
diff --git a/credentials/credentials/api/api_lint.ignore b/credentials/credentials/api/api_lint.ignore
index be1a990..8d0b1d6 100644
--- a/credentials/credentials/api/api_lint.ignore
+++ b/credentials/credentials/api/api_lint.ignore
@@ -1,5 +1,7 @@
 // Baseline format: 1.0
-GetterSetterNames: field CreatePublicKeyCredentialRequest.preferImmediatelyAvailableCredentials:
+GetterSetterNames: field CreateCredentialRequest.preferImmediatelyAvailableCredentials:
     Invalid name for boolean property `preferImmediatelyAvailableCredentials`. Should start with one of `has`, `can`, `should`, `is`.
-GetterSetterNames: field GetPublicKeyCredentialOption.preferImmediatelyAvailableCredentials:
+GetterSetterNames: field GetCredentialRequest.preferIdentityDocUi:
+    Invalid name for boolean property `preferIdentityDocUi`. Should start with one of `has`, `can`, `should`, `is`.
+GetterSetterNames: field GetCredentialRequest.preferImmediatelyAvailableCredentials:
     Invalid name for boolean property `preferImmediatelyAvailableCredentials`. Should start with one of `has`, `can`, `should`, `is`.
diff --git a/credentials/credentials/api/current.txt b/credentials/credentials/api/current.txt
index 5f71623..6d9da2c 100644
--- a/credentials/credentials/api/current.txt
+++ b/credentials/credentials/api/current.txt
@@ -6,13 +6,28 @@
   }
 
   public abstract class CreateCredentialRequest {
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final android.os.Bundle getCredentialData();
+    method public final androidx.credentials.CreateCredentialRequest.DisplayInfo getDisplayInfo();
     method public final String? getOrigin();
+    method public final boolean getPreferImmediatelyAvailableCredentials();
+    method public final String getType();
+    method public final boolean isAutoSelectAllowed();
+    method public final boolean isSystemProviderRequired();
+    property public final android.os.Bundle candidateQueryData;
+    property public final android.os.Bundle credentialData;
+    property public final androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo;
+    property public final boolean isAutoSelectAllowed;
+    property public final boolean isSystemProviderRequired;
     property public final String? origin;
+    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final String type;
   }
 
   public static final class CreateCredentialRequest.DisplayInfo {
     ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId);
     ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId, optional CharSequence? userDisplayName);
+    ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId, CharSequence? userDisplayName, String? preferDefaultProvider);
     method public CharSequence? getUserDisplayName();
     method public CharSequence getUserId();
     property public final CharSequence? userDisplayName;
@@ -20,35 +35,29 @@
   }
 
   public abstract class CreateCredentialResponse {
-  }
-
-  public class CreateCustomCredentialRequest extends androidx.credentials.CreateCredentialRequest {
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo);
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed);
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin);
-    method public final android.os.Bundle getCandidateQueryData();
-    method public final android.os.Bundle getCredentialData();
-    method public final String getType();
-    method public final boolean isAutoSelectAllowed();
-    method public final boolean isSystemProviderRequired();
-    property public final android.os.Bundle candidateQueryData;
-    property public final android.os.Bundle credentialData;
-    property public final boolean isAutoSelectAllowed;
-    property public final boolean isSystemProviderRequired;
-    property public final String type;
-  }
-
-  public class CreateCustomCredentialResponse extends androidx.credentials.CreateCredentialResponse {
-    ctor public CreateCustomCredentialResponse(String type, android.os.Bundle data);
     method public final android.os.Bundle getData();
     method public final String getType();
     property public final android.os.Bundle data;
     property public final String type;
   }
 
+  public class CreateCustomCredentialRequest extends androidx.credentials.CreateCredentialRequest {
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin, optional boolean preferImmediatelyAvailableCredentials);
+  }
+
+  public class CreateCustomCredentialResponse extends androidx.credentials.CreateCredentialResponse {
+    ctor public CreateCustomCredentialResponse(String type, android.os.Bundle data);
+  }
+
   public final class CreatePasswordRequest extends androidx.credentials.CreateCredentialRequest {
     ctor public CreatePasswordRequest(String id, String password);
     ctor public CreatePasswordRequest(String id, String password, optional String? origin);
+    ctor public CreatePasswordRequest(String id, String password, optional String? origin, optional boolean preferImmediatelyAvailableCredentials);
+    ctor public CreatePasswordRequest(String id, String password, optional String? origin, optional boolean preferImmediatelyAvailableCredentials, optional boolean isAutoSelectAllowed);
+    ctor public CreatePasswordRequest(String id, String password, String? origin, String? preferDefaultProvider, boolean preferImmediatelyAvailableCredentials, boolean isAutoSelectAllowed);
     method public String getId();
     method public String getPassword();
     property public final String id;
@@ -61,14 +70,14 @@
 
   public final class CreatePublicKeyCredentialRequest extends androidx.credentials.CreateCredentialRequest {
     ctor public CreatePublicKeyCredentialRequest(String requestJson);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin);
-    method public String? getClientDataHash();
-    method public boolean getPreferImmediatelyAvailableCredentials();
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin, optional boolean isAutoSelectAllowed);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, byte[]? clientDataHash, boolean preferImmediatelyAvailableCredentials, String? origin, String? preferDefaultProvider, boolean isAutoSelectAllowed);
+    method public byte[]? getClientDataHash();
     method public String getRequestJson();
-    property public final String? clientDataHash;
-    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final byte[]? clientDataHash;
     property public final String requestJson;
   }
 
@@ -79,16 +88,25 @@
   }
 
   public abstract class Credential {
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
-  public final class CredentialManager {
-    method public suspend Object? clearCredentialState(androidx.credentials.ClearCredentialStateRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  @RequiresApi(16) public interface CredentialManager {
+    method public default suspend Object? clearCredentialState(androidx.credentials.ClearCredentialStateRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public void clearCredentialStateAsync(androidx.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
-    method public static androidx.credentials.CredentialManager create(android.content.Context context);
-    method public suspend Object? createCredential(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, kotlin.coroutines.Continuation<? super androidx.credentials.CreateCredentialResponse>);
-    method public void createCredentialAsync(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
-    method public suspend Object? getCredential(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
-    method public void getCredentialAsync(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public default static androidx.credentials.CredentialManager create(android.content.Context context);
+    method public default suspend Object? createCredential(android.content.Context context, androidx.credentials.CreateCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.CreateCredentialResponse>);
+    method public void createCredentialAsync(android.content.Context context, androidx.credentials.CreateCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method @RequiresApi(34) public android.app.PendingIntent createSettingsPendingIntent();
+    method public default suspend Object? getCredential(android.content.Context context, androidx.credentials.GetCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
+    method @RequiresApi(34) public default suspend Object? getCredential(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
+    method public void getCredentialAsync(android.content.Context context, androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public void getCredentialAsync(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default suspend Object? prepareGetCredential(androidx.credentials.GetCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.PrepareGetCredentialResponse>);
+    method @RequiresApi(34) public void prepareGetCredentialAsync(androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.PrepareGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
     field public static final androidx.credentials.CredentialManager.Companion Companion;
   }
 
@@ -102,30 +120,49 @@
   }
 
   public abstract class CredentialOption {
+    method public final java.util.Set<android.content.ComponentName> getAllowedProviders();
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final android.os.Bundle getRequestData();
+    method public final String getType();
+    method public final boolean isAutoSelectAllowed();
+    method public final boolean isSystemProviderRequired();
+    property public final java.util.Set<android.content.ComponentName> allowedProviders;
+    property public final android.os.Bundle candidateQueryData;
+    property public final boolean isAutoSelectAllowed;
+    property public final boolean isSystemProviderRequired;
+    property public final android.os.Bundle requestData;
+    property public final String type;
   }
 
   public interface CredentialProvider {
     method public boolean isAvailableOnDevice();
     method public void onClearCredential(androidx.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
-    method public void onCreateCredential(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
-    method public void onGetCredential(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public void onCreateCredential(android.content.Context context, androidx.credentials.CreateCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method public void onGetCredential(android.content.Context context, androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default void onGetCredential(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default void onPrepareCredential(androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.PrepareGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
   }
 
   public class CustomCredential extends androidx.credentials.Credential {
     ctor public CustomCredential(String type, android.os.Bundle data);
-    method public final android.os.Bundle getData();
-    method public final String getType();
-    property public final android.os.Bundle data;
-    property public final String type;
   }
 
   public final class GetCredentialRequest {
     ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions);
     ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi, optional android.content.ComponentName? preferUiBrandingComponentName);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi, optional android.content.ComponentName? preferUiBrandingComponentName, optional boolean preferImmediatelyAvailableCredentials);
     method public java.util.List<androidx.credentials.CredentialOption> getCredentialOptions();
     method public String? getOrigin();
+    method public boolean getPreferIdentityDocUi();
+    method public boolean getPreferImmediatelyAvailableCredentials();
+    method public android.content.ComponentName? getPreferUiBrandingComponentName();
     property public final java.util.List<androidx.credentials.CredentialOption> credentialOptions;
     property public final String? origin;
+    property public final boolean preferIdentityDocUi;
+    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final android.content.ComponentName? preferUiBrandingComponentName;
   }
 
   public static final class GetCredentialRequest.Builder {
@@ -134,6 +171,9 @@
     method public androidx.credentials.GetCredentialRequest build();
     method public androidx.credentials.GetCredentialRequest.Builder setCredentialOptions(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions);
     method public androidx.credentials.GetCredentialRequest.Builder setOrigin(String origin);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferIdentityDocUi(boolean preferIdentityDocUi);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferImmediatelyAvailableCredentials(boolean preferImmediatelyAvailableCredentials);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferUiBrandingComponentName(android.content.ComponentName? component);
   }
 
   public final class GetCredentialResponse {
@@ -145,34 +185,25 @@
   public class GetCustomCredentialOption extends androidx.credentials.CredentialOption {
     ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired);
     ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, optional boolean isAutoSelectAllowed);
-    method public final android.os.Bundle getCandidateQueryData();
-    method public final android.os.Bundle getRequestData();
-    method public final String getType();
-    method public final boolean isAutoSelectAllowed();
-    method public final boolean isSystemProviderRequired();
-    property public final android.os.Bundle candidateQueryData;
-    property public final boolean isAutoSelectAllowed;
-    property public final boolean isSystemProviderRequired;
-    property public final android.os.Bundle requestData;
-    property public final String type;
+    ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, optional boolean isAutoSelectAllowed, optional java.util.Set<android.content.ComponentName> allowedProviders);
   }
 
   public final class GetPasswordOption extends androidx.credentials.CredentialOption {
     ctor public GetPasswordOption();
-    ctor public GetPasswordOption(optional boolean isAutoSelectAllowed);
-    method public boolean isAutoSelectAllowed();
-    property public boolean isAutoSelectAllowed;
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds);
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds, optional boolean isAutoSelectAllowed);
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds, optional boolean isAutoSelectAllowed, optional java.util.Set<android.content.ComponentName> allowedProviders);
+    method public java.util.Set<java.lang.String> getAllowedUserIds();
+    property public final java.util.Set<java.lang.String> allowedUserIds;
   }
 
   public final class GetPublicKeyCredentialOption extends androidx.credentials.CredentialOption {
     ctor public GetPublicKeyCredentialOption(String requestJson);
-    ctor public GetPublicKeyCredentialOption(String requestJson, optional String? clientDataHash);
-    ctor public GetPublicKeyCredentialOption(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
-    method public String? getClientDataHash();
-    method public boolean getPreferImmediatelyAvailableCredentials();
+    ctor public GetPublicKeyCredentialOption(String requestJson, optional byte[]? clientDataHash);
+    ctor public GetPublicKeyCredentialOption(String requestJson, optional byte[]? clientDataHash, optional java.util.Set<android.content.ComponentName> allowedProviders);
+    method public byte[]? getClientDataHash();
     method public String getRequestJson();
-    property public final String? clientDataHash;
-    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final byte[]? clientDataHash;
     property public final String requestJson;
   }
 
@@ -182,12 +213,34 @@
     method public String getPassword();
     property public final String id;
     property public final String password;
+    field public static final androidx.credentials.PasswordCredential.Companion Companion;
+    field public static final String TYPE_PASSWORD_CREDENTIAL = "android.credentials.TYPE_PASSWORD_CREDENTIAL";
+  }
+
+  public static final class PasswordCredential.Companion {
+  }
+
+  @RequiresApi(34) public final class PrepareGetCredentialResponse {
+    method public androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle getPendingGetCredentialHandle();
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasAuthenticationResults();
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasCredentialResults(String credentialType);
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasRemoteResults();
+    property public final androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle;
+  }
+
+  @RequiresApi(34) public static final class PrepareGetCredentialResponse.PendingGetCredentialHandle {
+    ctor public PrepareGetCredentialResponse.PendingGetCredentialHandle(android.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle? frameworkHandle);
   }
 
   public final class PublicKeyCredential extends androidx.credentials.Credential {
     ctor public PublicKeyCredential(String authenticationResponseJson);
     method public String getAuthenticationResponseJson();
     property public final String authenticationResponseJson;
+    field public static final androidx.credentials.PublicKeyCredential.Companion Companion;
+    field public static final String TYPE_PUBLIC_KEY_CREDENTIAL = "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL";
+  }
+
+  public static final class PublicKeyCredential.Companion {
   }
 
 }
@@ -454,3 +507,378 @@
 
 }
 
+package androidx.credentials.provider {
+
+  public final class Action {
+    ctor public Action(CharSequence title, android.app.PendingIntent pendingIntent, optional CharSequence? subtitle);
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence? getSubtitle();
+    method public CharSequence getTitle();
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence? subtitle;
+    property public final CharSequence title;
+  }
+
+  public static final class Action.Builder {
+    ctor public Action.Builder(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.Action build();
+    method public androidx.credentials.provider.Action.Builder setSubtitle(CharSequence? subtitle);
+  }
+
+  public final class AuthenticationAction {
+    ctor public AuthenticationAction(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTitle();
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence title;
+  }
+
+  public static final class AuthenticationAction.Builder {
+    ctor public AuthenticationAction.Builder(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.AuthenticationAction build();
+  }
+
+  public abstract class BeginCreateCredentialRequest {
+    ctor public BeginCreateCredentialRequest(String type, android.os.Bundle candidateQueryData, androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+    method public static final android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialRequest request);
+    method public static final androidx.credentials.provider.BeginCreateCredentialRequest? fromBundle(android.os.Bundle bundle);
+    method public final androidx.credentials.provider.CallingAppInfo? getCallingAppInfo();
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final String getType();
+    property public final androidx.credentials.provider.CallingAppInfo? callingAppInfo;
+    property public final android.os.Bundle candidateQueryData;
+    property public final String type;
+    field public static final androidx.credentials.provider.BeginCreateCredentialRequest.Companion Companion;
+  }
+
+  public static final class BeginCreateCredentialRequest.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialRequest request);
+    method public androidx.credentials.provider.BeginCreateCredentialRequest? fromBundle(android.os.Bundle bundle);
+  }
+
+  public final class BeginCreateCredentialResponse {
+    ctor public BeginCreateCredentialResponse(optional java.util.List<androidx.credentials.provider.CreateEntry> createEntries, optional androidx.credentials.provider.RemoteEntry? remoteEntry);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialResponse response);
+    method public static androidx.credentials.provider.BeginCreateCredentialResponse? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.CreateEntry> getCreateEntries();
+    method public androidx.credentials.provider.RemoteEntry? getRemoteEntry();
+    property public final java.util.List<androidx.credentials.provider.CreateEntry> createEntries;
+    property public final androidx.credentials.provider.RemoteEntry? remoteEntry;
+    field public static final androidx.credentials.provider.BeginCreateCredentialResponse.Companion Companion;
+  }
+
+  public static final class BeginCreateCredentialResponse.Builder {
+    ctor public BeginCreateCredentialResponse.Builder();
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder addCreateEntry(androidx.credentials.provider.CreateEntry createEntry);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse build();
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder setCreateEntries(java.util.List<androidx.credentials.provider.CreateEntry> createEntries);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder setRemoteEntry(androidx.credentials.provider.RemoteEntry? remoteEntry);
+  }
+
+  public static final class BeginCreateCredentialResponse.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialResponse response);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse? fromBundle(android.os.Bundle bundle);
+  }
+
+  public class BeginCreateCustomCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreateCustomCredentialRequest(String type, android.os.Bundle candidateQueryData, androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+  }
+
+  public final class BeginCreatePasswordCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreatePasswordCredentialRequest(androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData);
+  }
+
+  public final class BeginCreatePublicKeyCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreatePublicKeyCredentialRequest(String requestJson, androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData);
+    ctor public BeginCreatePublicKeyCredentialRequest(String requestJson, androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData, optional byte[]? clientDataHash);
+    method public byte[]? getClientDataHash();
+    method public String getRequestJson();
+    property public final byte[]? clientDataHash;
+    property public final String requestJson;
+  }
+
+  public abstract class BeginGetCredentialOption {
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final String getId();
+    method public final String getType();
+    property public final android.os.Bundle candidateQueryData;
+    property public final String id;
+    property public final String type;
+  }
+
+  public final class BeginGetCredentialRequest {
+    ctor public BeginGetCredentialRequest(java.util.List<? extends androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions);
+    ctor public BeginGetCredentialRequest(java.util.List<? extends androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions, optional androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialRequest request);
+    method public static androidx.credentials.provider.BeginGetCredentialRequest? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.BeginGetCredentialOption> getBeginGetCredentialOptions();
+    method public androidx.credentials.provider.CallingAppInfo? getCallingAppInfo();
+    property public final java.util.List<androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions;
+    property public final androidx.credentials.provider.CallingAppInfo? callingAppInfo;
+    field public static final androidx.credentials.provider.BeginGetCredentialRequest.Companion Companion;
+  }
+
+  public static final class BeginGetCredentialRequest.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialRequest request);
+    method public androidx.credentials.provider.BeginGetCredentialRequest? fromBundle(android.os.Bundle bundle);
+  }
+
+  public final class BeginGetCredentialResponse {
+    ctor public BeginGetCredentialResponse(optional java.util.List<? extends androidx.credentials.provider.CredentialEntry> credentialEntries, optional java.util.List<androidx.credentials.provider.Action> actions, optional java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationActions, optional androidx.credentials.provider.RemoteEntry? remoteEntry);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public static androidx.credentials.provider.BeginGetCredentialResponse? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.Action> getActions();
+    method public java.util.List<androidx.credentials.provider.AuthenticationAction> getAuthenticationActions();
+    method public java.util.List<androidx.credentials.provider.CredentialEntry> getCredentialEntries();
+    method public androidx.credentials.provider.RemoteEntry? getRemoteEntry();
+    property public final java.util.List<androidx.credentials.provider.Action> actions;
+    property public final java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationActions;
+    property public final java.util.List<androidx.credentials.provider.CredentialEntry> credentialEntries;
+    property public final androidx.credentials.provider.RemoteEntry? remoteEntry;
+    field public static final androidx.credentials.provider.BeginGetCredentialResponse.Companion Companion;
+  }
+
+  public static final class BeginGetCredentialResponse.Builder {
+    ctor public BeginGetCredentialResponse.Builder();
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addAction(androidx.credentials.provider.Action action);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addAuthenticationAction(androidx.credentials.provider.AuthenticationAction authenticationAction);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addCredentialEntry(androidx.credentials.provider.CredentialEntry entry);
+    method public androidx.credentials.provider.BeginGetCredentialResponse build();
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setActions(java.util.List<androidx.credentials.provider.Action> actions);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setAuthenticationActions(java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationEntries);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setCredentialEntries(java.util.List<? extends androidx.credentials.provider.CredentialEntry> entries);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setRemoteEntry(androidx.credentials.provider.RemoteEntry? remoteEntry);
+  }
+
+  public static final class BeginGetCredentialResponse.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public androidx.credentials.provider.BeginGetCredentialResponse? fromBundle(android.os.Bundle bundle);
+  }
+
+  public class BeginGetCustomCredentialOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetCustomCredentialOption(String id, String type, android.os.Bundle candidateQueryData);
+  }
+
+  public final class BeginGetPasswordOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetPasswordOption(java.util.Set<java.lang.String> allowedUserIds, android.os.Bundle candidateQueryData, String id);
+    method public java.util.Set<java.lang.String> getAllowedUserIds();
+    property public final java.util.Set<java.lang.String> allowedUserIds;
+  }
+
+  public final class BeginGetPublicKeyCredentialOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetPublicKeyCredentialOption(android.os.Bundle candidateQueryData, String id, String requestJson);
+    ctor public BeginGetPublicKeyCredentialOption(android.os.Bundle candidateQueryData, String id, String requestJson, optional byte[]? clientDataHash);
+    method public byte[]? getClientDataHash();
+    method public String getRequestJson();
+    property public final byte[]? clientDataHash;
+    property public final String requestJson;
+  }
+
+  public final class CallingAppInfo {
+    ctor public CallingAppInfo(String packageName, android.content.pm.SigningInfo signingInfo);
+    ctor public CallingAppInfo(String packageName, android.content.pm.SigningInfo signingInfo, optional String? origin);
+    method public String? getOrigin();
+    method public String getPackageName();
+    method public android.content.pm.SigningInfo getSigningInfo();
+    property public final String? origin;
+    property public final String packageName;
+    property public final android.content.pm.SigningInfo signingInfo;
+  }
+
+  @RequiresApi(28) public final class CreateEntry {
+    ctor public CreateEntry(CharSequence accountName, android.app.PendingIntent pendingIntent, optional CharSequence? description, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon? icon, optional Integer? passwordCredentialCount, optional Integer? publicKeyCredentialCount, optional Integer? totalCredentialCount, optional boolean isAutoSelectAllowed);
+    method public CharSequence getAccountName();
+    method public CharSequence? getDescription();
+    method public android.graphics.drawable.Icon? getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public Integer? getPasswordCredentialCount();
+    method public android.app.PendingIntent getPendingIntent();
+    method public Integer? getPublicKeyCredentialCount();
+    method public Integer? getTotalCredentialCount();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence accountName;
+    property public final CharSequence? description;
+    property public final android.graphics.drawable.Icon? icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+  }
+
+  public static final class CreateEntry.Builder {
+    ctor public CreateEntry.Builder(CharSequence accountName, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.CreateEntry build();
+    method public androidx.credentials.provider.CreateEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.CreateEntry.Builder setDescription(CharSequence? description);
+    method public androidx.credentials.provider.CreateEntry.Builder setIcon(android.graphics.drawable.Icon? icon);
+    method public androidx.credentials.provider.CreateEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+    method public androidx.credentials.provider.CreateEntry.Builder setPasswordCredentialCount(int count);
+    method public androidx.credentials.provider.CreateEntry.Builder setPublicKeyCredentialCount(int count);
+    method public androidx.credentials.provider.CreateEntry.Builder setTotalCredentialCount(int count);
+  }
+
+  public abstract class CredentialEntry {
+    method public final androidx.credentials.provider.BeginGetCredentialOption getBeginGetCredentialOption();
+    property public final androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption;
+  }
+
+  @RequiresApi(34) public abstract class CredentialProviderService extends android.service.credentials.CredentialProviderService {
+    ctor public CredentialProviderService();
+    method public final void onBeginCreateCredential(android.service.credentials.BeginCreateCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<android.service.credentials.BeginCreateCredentialResponse,android.credentials.CreateCredentialException> callback);
+    method public abstract void onBeginCreateCredentialRequest(androidx.credentials.provider.BeginCreateCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<androidx.credentials.provider.BeginCreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method public final void onBeginGetCredential(android.service.credentials.BeginGetCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<android.service.credentials.BeginGetCredentialResponse,android.credentials.GetCredentialException> callback);
+    method public abstract void onBeginGetCredentialRequest(androidx.credentials.provider.BeginGetCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<androidx.credentials.provider.BeginGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public final void onClearCredentialState(android.service.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException> callback);
+    method public abstract void onClearCredentialStateRequest(androidx.credentials.provider.ProviderClearCredentialStateRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
+  }
+
+  @RequiresApi(28) public final class CustomCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public CustomCredentialEntry(android.content.Context context, CharSequence title, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption, optional CharSequence? subtitle, optional CharSequence? typeDisplayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence? getSubtitle();
+    method public CharSequence getTitle();
+    method public String getType();
+    method public CharSequence? getTypeDisplayName();
+    method public boolean isAutoSelectAllowed();
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence? subtitle;
+    property public final CharSequence title;
+    property public String type;
+    property public final CharSequence? typeDisplayName;
+  }
+
+  public static final class CustomCredentialEntry.Builder {
+    ctor public CustomCredentialEntry.Builder(android.content.Context context, String type, CharSequence title, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption);
+    method public androidx.credentials.provider.CustomCredentialEntry build();
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setSubtitle(CharSequence? subtitle);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setTypeDisplayName(CharSequence? typeDisplayName);
+  }
+
+  public final class IntentHandlerConverters {
+    method @RequiresApi(34) public static androidx.credentials.provider.BeginGetCredentialResponse? getBeginGetResponse(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.CreateCredentialResponse? getCreateCredentialCredentialResponse(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.CreateCredentialException? getCreateCredentialException(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.GetCredentialException? getGetCredentialException(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.GetCredentialResponse? getGetCredentialResponse(android.content.Intent);
+  }
+
+  @RequiresApi(28) public final class PasswordCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public PasswordCredentialEntry(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPasswordOption beginGetPasswordOption, optional CharSequence? displayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public CharSequence? getDisplayName();
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTypeDisplayName();
+    method public CharSequence getUsername();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence? displayName;
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence typeDisplayName;
+    property public final CharSequence username;
+  }
+
+  public static final class PasswordCredentialEntry.Builder {
+    ctor public PasswordCredentialEntry.Builder(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPasswordOption beginGetPasswordOption);
+    method public androidx.credentials.provider.PasswordCredentialEntry build();
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setDisplayName(CharSequence? displayName);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+  }
+
+  @RequiresApi(34) public final class PendingIntentHandler {
+    ctor public PendingIntentHandler();
+    method public static androidx.credentials.provider.BeginGetCredentialRequest? retrieveBeginGetCredentialRequest(android.content.Intent intent);
+    method public static androidx.credentials.provider.ProviderCreateCredentialRequest? retrieveProviderCreateCredentialRequest(android.content.Intent intent);
+    method public static androidx.credentials.provider.ProviderGetCredentialRequest? retrieveProviderGetCredentialRequest(android.content.Intent intent);
+    method public static void setBeginGetCredentialResponse(android.content.Intent intent, androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public static void setCreateCredentialException(android.content.Intent intent, androidx.credentials.exceptions.CreateCredentialException exception);
+    method public static void setCreateCredentialResponse(android.content.Intent intent, androidx.credentials.CreateCredentialResponse response);
+    method public static void setGetCredentialException(android.content.Intent intent, androidx.credentials.exceptions.GetCredentialException exception);
+    method public static void setGetCredentialResponse(android.content.Intent intent, androidx.credentials.GetCredentialResponse response);
+    field public static final androidx.credentials.provider.PendingIntentHandler.Companion Companion;
+  }
+
+  public static final class PendingIntentHandler.Companion {
+    method public androidx.credentials.provider.BeginGetCredentialRequest? retrieveBeginGetCredentialRequest(android.content.Intent intent);
+    method public androidx.credentials.provider.ProviderCreateCredentialRequest? retrieveProviderCreateCredentialRequest(android.content.Intent intent);
+    method public androidx.credentials.provider.ProviderGetCredentialRequest? retrieveProviderGetCredentialRequest(android.content.Intent intent);
+    method public void setBeginGetCredentialResponse(android.content.Intent intent, androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public void setCreateCredentialException(android.content.Intent intent, androidx.credentials.exceptions.CreateCredentialException exception);
+    method public void setCreateCredentialResponse(android.content.Intent intent, androidx.credentials.CreateCredentialResponse response);
+    method public void setGetCredentialException(android.content.Intent intent, androidx.credentials.exceptions.GetCredentialException exception);
+    method public void setGetCredentialResponse(android.content.Intent intent, androidx.credentials.GetCredentialResponse response);
+  }
+
+  public final class ProviderClearCredentialStateRequest {
+    ctor public ProviderClearCredentialStateRequest(androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+  }
+
+  public final class ProviderCreateCredentialRequest {
+    ctor public ProviderCreateCredentialRequest(androidx.credentials.CreateCredentialRequest callingRequest, androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    method public androidx.credentials.CreateCredentialRequest getCallingRequest();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+    property public final androidx.credentials.CreateCredentialRequest callingRequest;
+  }
+
+  public final class ProviderGetCredentialRequest {
+    ctor public ProviderGetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    method public java.util.List<androidx.credentials.CredentialOption> getCredentialOptions();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+    property public final java.util.List<androidx.credentials.CredentialOption> credentialOptions;
+  }
+
+  @RequiresApi(28) public final class PublicKeyCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public PublicKeyCredentialEntry(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPublicKeyCredentialOption beginGetPublicKeyCredentialOption, optional CharSequence? displayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public CharSequence? getDisplayName();
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTypeDisplayName();
+    method public CharSequence getUsername();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence? displayName;
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence typeDisplayName;
+    property public final CharSequence username;
+  }
+
+  public static final class PublicKeyCredentialEntry.Builder {
+    ctor public PublicKeyCredentialEntry.Builder(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPublicKeyCredentialOption beginGetPublicKeyCredentialOption);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry build();
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setDisplayName(CharSequence? displayName);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+  }
+
+  public final class RemoteEntry {
+    ctor public RemoteEntry(android.app.PendingIntent pendingIntent);
+    method public android.app.PendingIntent getPendingIntent();
+    property public final android.app.PendingIntent pendingIntent;
+  }
+
+  public static final class RemoteEntry.Builder {
+    ctor public RemoteEntry.Builder(android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.RemoteEntry build();
+  }
+
+}
+
diff --git a/credentials/credentials/api/restricted_current.txt b/credentials/credentials/api/restricted_current.txt
index 5f71623..6d9da2c 100644
--- a/credentials/credentials/api/restricted_current.txt
+++ b/credentials/credentials/api/restricted_current.txt
@@ -6,13 +6,28 @@
   }
 
   public abstract class CreateCredentialRequest {
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final android.os.Bundle getCredentialData();
+    method public final androidx.credentials.CreateCredentialRequest.DisplayInfo getDisplayInfo();
     method public final String? getOrigin();
+    method public final boolean getPreferImmediatelyAvailableCredentials();
+    method public final String getType();
+    method public final boolean isAutoSelectAllowed();
+    method public final boolean isSystemProviderRequired();
+    property public final android.os.Bundle candidateQueryData;
+    property public final android.os.Bundle credentialData;
+    property public final androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo;
+    property public final boolean isAutoSelectAllowed;
+    property public final boolean isSystemProviderRequired;
     property public final String? origin;
+    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final String type;
   }
 
   public static final class CreateCredentialRequest.DisplayInfo {
     ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId);
     ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId, optional CharSequence? userDisplayName);
+    ctor public CreateCredentialRequest.DisplayInfo(CharSequence userId, CharSequence? userDisplayName, String? preferDefaultProvider);
     method public CharSequence? getUserDisplayName();
     method public CharSequence getUserId();
     property public final CharSequence? userDisplayName;
@@ -20,35 +35,29 @@
   }
 
   public abstract class CreateCredentialResponse {
-  }
-
-  public class CreateCustomCredentialRequest extends androidx.credentials.CreateCredentialRequest {
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo);
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed);
-    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin);
-    method public final android.os.Bundle getCandidateQueryData();
-    method public final android.os.Bundle getCredentialData();
-    method public final String getType();
-    method public final boolean isAutoSelectAllowed();
-    method public final boolean isSystemProviderRequired();
-    property public final android.os.Bundle candidateQueryData;
-    property public final android.os.Bundle credentialData;
-    property public final boolean isAutoSelectAllowed;
-    property public final boolean isSystemProviderRequired;
-    property public final String type;
-  }
-
-  public class CreateCustomCredentialResponse extends androidx.credentials.CreateCredentialResponse {
-    ctor public CreateCustomCredentialResponse(String type, android.os.Bundle data);
     method public final android.os.Bundle getData();
     method public final String getType();
     property public final android.os.Bundle data;
     property public final String type;
   }
 
+  public class CreateCustomCredentialRequest extends androidx.credentials.CreateCredentialRequest {
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin);
+    ctor public CreateCustomCredentialRequest(String type, android.os.Bundle credentialData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, androidx.credentials.CreateCredentialRequest.DisplayInfo displayInfo, optional boolean isAutoSelectAllowed, optional String? origin, optional boolean preferImmediatelyAvailableCredentials);
+  }
+
+  public class CreateCustomCredentialResponse extends androidx.credentials.CreateCredentialResponse {
+    ctor public CreateCustomCredentialResponse(String type, android.os.Bundle data);
+  }
+
   public final class CreatePasswordRequest extends androidx.credentials.CreateCredentialRequest {
     ctor public CreatePasswordRequest(String id, String password);
     ctor public CreatePasswordRequest(String id, String password, optional String? origin);
+    ctor public CreatePasswordRequest(String id, String password, optional String? origin, optional boolean preferImmediatelyAvailableCredentials);
+    ctor public CreatePasswordRequest(String id, String password, optional String? origin, optional boolean preferImmediatelyAvailableCredentials, optional boolean isAutoSelectAllowed);
+    ctor public CreatePasswordRequest(String id, String password, String? origin, String? preferDefaultProvider, boolean preferImmediatelyAvailableCredentials, boolean isAutoSelectAllowed);
     method public String getId();
     method public String getPassword();
     property public final String id;
@@ -61,14 +70,14 @@
 
   public final class CreatePublicKeyCredentialRequest extends androidx.credentials.CreateCredentialRequest {
     ctor public CreatePublicKeyCredentialRequest(String requestJson);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
-    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin);
-    method public String? getClientDataHash();
-    method public boolean getPreferImmediatelyAvailableCredentials();
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, optional byte[]? clientDataHash, optional boolean preferImmediatelyAvailableCredentials, optional String? origin, optional boolean isAutoSelectAllowed);
+    ctor public CreatePublicKeyCredentialRequest(String requestJson, byte[]? clientDataHash, boolean preferImmediatelyAvailableCredentials, String? origin, String? preferDefaultProvider, boolean isAutoSelectAllowed);
+    method public byte[]? getClientDataHash();
     method public String getRequestJson();
-    property public final String? clientDataHash;
-    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final byte[]? clientDataHash;
     property public final String requestJson;
   }
 
@@ -79,16 +88,25 @@
   }
 
   public abstract class Credential {
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
-  public final class CredentialManager {
-    method public suspend Object? clearCredentialState(androidx.credentials.ClearCredentialStateRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  @RequiresApi(16) public interface CredentialManager {
+    method public default suspend Object? clearCredentialState(androidx.credentials.ClearCredentialStateRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
     method public void clearCredentialStateAsync(androidx.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
-    method public static androidx.credentials.CredentialManager create(android.content.Context context);
-    method public suspend Object? createCredential(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, kotlin.coroutines.Continuation<? super androidx.credentials.CreateCredentialResponse>);
-    method public void createCredentialAsync(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
-    method public suspend Object? getCredential(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
-    method public void getCredentialAsync(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public default static androidx.credentials.CredentialManager create(android.content.Context context);
+    method public default suspend Object? createCredential(android.content.Context context, androidx.credentials.CreateCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.CreateCredentialResponse>);
+    method public void createCredentialAsync(android.content.Context context, androidx.credentials.CreateCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method @RequiresApi(34) public android.app.PendingIntent createSettingsPendingIntent();
+    method public default suspend Object? getCredential(android.content.Context context, androidx.credentials.GetCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
+    method @RequiresApi(34) public default suspend Object? getCredential(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, kotlin.coroutines.Continuation<? super androidx.credentials.GetCredentialResponse>);
+    method public void getCredentialAsync(android.content.Context context, androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public void getCredentialAsync(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default suspend Object? prepareGetCredential(androidx.credentials.GetCredentialRequest request, kotlin.coroutines.Continuation<? super androidx.credentials.PrepareGetCredentialResponse>);
+    method @RequiresApi(34) public void prepareGetCredentialAsync(androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.PrepareGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
     field public static final androidx.credentials.CredentialManager.Companion Companion;
   }
 
@@ -102,30 +120,49 @@
   }
 
   public abstract class CredentialOption {
+    method public final java.util.Set<android.content.ComponentName> getAllowedProviders();
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final android.os.Bundle getRequestData();
+    method public final String getType();
+    method public final boolean isAutoSelectAllowed();
+    method public final boolean isSystemProviderRequired();
+    property public final java.util.Set<android.content.ComponentName> allowedProviders;
+    property public final android.os.Bundle candidateQueryData;
+    property public final boolean isAutoSelectAllowed;
+    property public final boolean isSystemProviderRequired;
+    property public final android.os.Bundle requestData;
+    property public final String type;
   }
 
   public interface CredentialProvider {
     method public boolean isAvailableOnDevice();
     method public void onClearCredential(androidx.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
-    method public void onCreateCredential(androidx.credentials.CreateCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
-    method public void onGetCredential(androidx.credentials.GetCredentialRequest request, android.app.Activity activity, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public void onCreateCredential(android.content.Context context, androidx.credentials.CreateCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.CreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method public void onGetCredential(android.content.Context context, androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default void onGetCredential(android.content.Context context, androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.GetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method @RequiresApi(34) public default void onPrepareCredential(androidx.credentials.GetCredentialRequest request, android.os.CancellationSignal? cancellationSignal, java.util.concurrent.Executor executor, androidx.credentials.CredentialManagerCallback<androidx.credentials.PrepareGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
   }
 
   public class CustomCredential extends androidx.credentials.Credential {
     ctor public CustomCredential(String type, android.os.Bundle data);
-    method public final android.os.Bundle getData();
-    method public final String getType();
-    property public final android.os.Bundle data;
-    property public final String type;
   }
 
   public final class GetCredentialRequest {
     ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions);
     ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi, optional android.content.ComponentName? preferUiBrandingComponentName);
+    ctor public GetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, optional String? origin, optional boolean preferIdentityDocUi, optional android.content.ComponentName? preferUiBrandingComponentName, optional boolean preferImmediatelyAvailableCredentials);
     method public java.util.List<androidx.credentials.CredentialOption> getCredentialOptions();
     method public String? getOrigin();
+    method public boolean getPreferIdentityDocUi();
+    method public boolean getPreferImmediatelyAvailableCredentials();
+    method public android.content.ComponentName? getPreferUiBrandingComponentName();
     property public final java.util.List<androidx.credentials.CredentialOption> credentialOptions;
     property public final String? origin;
+    property public final boolean preferIdentityDocUi;
+    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final android.content.ComponentName? preferUiBrandingComponentName;
   }
 
   public static final class GetCredentialRequest.Builder {
@@ -134,6 +171,9 @@
     method public androidx.credentials.GetCredentialRequest build();
     method public androidx.credentials.GetCredentialRequest.Builder setCredentialOptions(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions);
     method public androidx.credentials.GetCredentialRequest.Builder setOrigin(String origin);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferIdentityDocUi(boolean preferIdentityDocUi);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferImmediatelyAvailableCredentials(boolean preferImmediatelyAvailableCredentials);
+    method public androidx.credentials.GetCredentialRequest.Builder setPreferUiBrandingComponentName(android.content.ComponentName? component);
   }
 
   public final class GetCredentialResponse {
@@ -145,34 +185,25 @@
   public class GetCustomCredentialOption extends androidx.credentials.CredentialOption {
     ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired);
     ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, optional boolean isAutoSelectAllowed);
-    method public final android.os.Bundle getCandidateQueryData();
-    method public final android.os.Bundle getRequestData();
-    method public final String getType();
-    method public final boolean isAutoSelectAllowed();
-    method public final boolean isSystemProviderRequired();
-    property public final android.os.Bundle candidateQueryData;
-    property public final boolean isAutoSelectAllowed;
-    property public final boolean isSystemProviderRequired;
-    property public final android.os.Bundle requestData;
-    property public final String type;
+    ctor public GetCustomCredentialOption(String type, android.os.Bundle requestData, android.os.Bundle candidateQueryData, boolean isSystemProviderRequired, optional boolean isAutoSelectAllowed, optional java.util.Set<android.content.ComponentName> allowedProviders);
   }
 
   public final class GetPasswordOption extends androidx.credentials.CredentialOption {
     ctor public GetPasswordOption();
-    ctor public GetPasswordOption(optional boolean isAutoSelectAllowed);
-    method public boolean isAutoSelectAllowed();
-    property public boolean isAutoSelectAllowed;
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds);
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds, optional boolean isAutoSelectAllowed);
+    ctor public GetPasswordOption(optional java.util.Set<java.lang.String> allowedUserIds, optional boolean isAutoSelectAllowed, optional java.util.Set<android.content.ComponentName> allowedProviders);
+    method public java.util.Set<java.lang.String> getAllowedUserIds();
+    property public final java.util.Set<java.lang.String> allowedUserIds;
   }
 
   public final class GetPublicKeyCredentialOption extends androidx.credentials.CredentialOption {
     ctor public GetPublicKeyCredentialOption(String requestJson);
-    ctor public GetPublicKeyCredentialOption(String requestJson, optional String? clientDataHash);
-    ctor public GetPublicKeyCredentialOption(String requestJson, optional String? clientDataHash, optional boolean preferImmediatelyAvailableCredentials);
-    method public String? getClientDataHash();
-    method public boolean getPreferImmediatelyAvailableCredentials();
+    ctor public GetPublicKeyCredentialOption(String requestJson, optional byte[]? clientDataHash);
+    ctor public GetPublicKeyCredentialOption(String requestJson, optional byte[]? clientDataHash, optional java.util.Set<android.content.ComponentName> allowedProviders);
+    method public byte[]? getClientDataHash();
     method public String getRequestJson();
-    property public final String? clientDataHash;
-    property public final boolean preferImmediatelyAvailableCredentials;
+    property public final byte[]? clientDataHash;
     property public final String requestJson;
   }
 
@@ -182,12 +213,34 @@
     method public String getPassword();
     property public final String id;
     property public final String password;
+    field public static final androidx.credentials.PasswordCredential.Companion Companion;
+    field public static final String TYPE_PASSWORD_CREDENTIAL = "android.credentials.TYPE_PASSWORD_CREDENTIAL";
+  }
+
+  public static final class PasswordCredential.Companion {
+  }
+
+  @RequiresApi(34) public final class PrepareGetCredentialResponse {
+    method public androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle getPendingGetCredentialHandle();
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasAuthenticationResults();
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasCredentialResults(String credentialType);
+    method @RequiresPermission(android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS) public boolean hasRemoteResults();
+    property public final androidx.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle pendingGetCredentialHandle;
+  }
+
+  @RequiresApi(34) public static final class PrepareGetCredentialResponse.PendingGetCredentialHandle {
+    ctor public PrepareGetCredentialResponse.PendingGetCredentialHandle(android.credentials.PrepareGetCredentialResponse.PendingGetCredentialHandle? frameworkHandle);
   }
 
   public final class PublicKeyCredential extends androidx.credentials.Credential {
     ctor public PublicKeyCredential(String authenticationResponseJson);
     method public String getAuthenticationResponseJson();
     property public final String authenticationResponseJson;
+    field public static final androidx.credentials.PublicKeyCredential.Companion Companion;
+    field public static final String TYPE_PUBLIC_KEY_CREDENTIAL = "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL";
+  }
+
+  public static final class PublicKeyCredential.Companion {
   }
 
 }
@@ -454,3 +507,378 @@
 
 }
 
+package androidx.credentials.provider {
+
+  public final class Action {
+    ctor public Action(CharSequence title, android.app.PendingIntent pendingIntent, optional CharSequence? subtitle);
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence? getSubtitle();
+    method public CharSequence getTitle();
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence? subtitle;
+    property public final CharSequence title;
+  }
+
+  public static final class Action.Builder {
+    ctor public Action.Builder(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.Action build();
+    method public androidx.credentials.provider.Action.Builder setSubtitle(CharSequence? subtitle);
+  }
+
+  public final class AuthenticationAction {
+    ctor public AuthenticationAction(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTitle();
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence title;
+  }
+
+  public static final class AuthenticationAction.Builder {
+    ctor public AuthenticationAction.Builder(CharSequence title, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.AuthenticationAction build();
+  }
+
+  public abstract class BeginCreateCredentialRequest {
+    ctor public BeginCreateCredentialRequest(String type, android.os.Bundle candidateQueryData, androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+    method public static final android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialRequest request);
+    method public static final androidx.credentials.provider.BeginCreateCredentialRequest? fromBundle(android.os.Bundle bundle);
+    method public final androidx.credentials.provider.CallingAppInfo? getCallingAppInfo();
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final String getType();
+    property public final androidx.credentials.provider.CallingAppInfo? callingAppInfo;
+    property public final android.os.Bundle candidateQueryData;
+    property public final String type;
+    field public static final androidx.credentials.provider.BeginCreateCredentialRequest.Companion Companion;
+  }
+
+  public static final class BeginCreateCredentialRequest.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialRequest request);
+    method public androidx.credentials.provider.BeginCreateCredentialRequest? fromBundle(android.os.Bundle bundle);
+  }
+
+  public final class BeginCreateCredentialResponse {
+    ctor public BeginCreateCredentialResponse(optional java.util.List<androidx.credentials.provider.CreateEntry> createEntries, optional androidx.credentials.provider.RemoteEntry? remoteEntry);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialResponse response);
+    method public static androidx.credentials.provider.BeginCreateCredentialResponse? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.CreateEntry> getCreateEntries();
+    method public androidx.credentials.provider.RemoteEntry? getRemoteEntry();
+    property public final java.util.List<androidx.credentials.provider.CreateEntry> createEntries;
+    property public final androidx.credentials.provider.RemoteEntry? remoteEntry;
+    field public static final androidx.credentials.provider.BeginCreateCredentialResponse.Companion Companion;
+  }
+
+  public static final class BeginCreateCredentialResponse.Builder {
+    ctor public BeginCreateCredentialResponse.Builder();
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder addCreateEntry(androidx.credentials.provider.CreateEntry createEntry);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse build();
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder setCreateEntries(java.util.List<androidx.credentials.provider.CreateEntry> createEntries);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse.Builder setRemoteEntry(androidx.credentials.provider.RemoteEntry? remoteEntry);
+  }
+
+  public static final class BeginCreateCredentialResponse.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginCreateCredentialResponse response);
+    method public androidx.credentials.provider.BeginCreateCredentialResponse? fromBundle(android.os.Bundle bundle);
+  }
+
+  public class BeginCreateCustomCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreateCustomCredentialRequest(String type, android.os.Bundle candidateQueryData, androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+  }
+
+  public final class BeginCreatePasswordCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreatePasswordCredentialRequest(androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData);
+  }
+
+  public final class BeginCreatePublicKeyCredentialRequest extends androidx.credentials.provider.BeginCreateCredentialRequest {
+    ctor public BeginCreatePublicKeyCredentialRequest(String requestJson, androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData);
+    ctor public BeginCreatePublicKeyCredentialRequest(String requestJson, androidx.credentials.provider.CallingAppInfo? callingAppInfo, android.os.Bundle candidateQueryData, optional byte[]? clientDataHash);
+    method public byte[]? getClientDataHash();
+    method public String getRequestJson();
+    property public final byte[]? clientDataHash;
+    property public final String requestJson;
+  }
+
+  public abstract class BeginGetCredentialOption {
+    method public final android.os.Bundle getCandidateQueryData();
+    method public final String getId();
+    method public final String getType();
+    property public final android.os.Bundle candidateQueryData;
+    property public final String id;
+    property public final String type;
+  }
+
+  public final class BeginGetCredentialRequest {
+    ctor public BeginGetCredentialRequest(java.util.List<? extends androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions);
+    ctor public BeginGetCredentialRequest(java.util.List<? extends androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions, optional androidx.credentials.provider.CallingAppInfo? callingAppInfo);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialRequest request);
+    method public static androidx.credentials.provider.BeginGetCredentialRequest? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.BeginGetCredentialOption> getBeginGetCredentialOptions();
+    method public androidx.credentials.provider.CallingAppInfo? getCallingAppInfo();
+    property public final java.util.List<androidx.credentials.provider.BeginGetCredentialOption> beginGetCredentialOptions;
+    property public final androidx.credentials.provider.CallingAppInfo? callingAppInfo;
+    field public static final androidx.credentials.provider.BeginGetCredentialRequest.Companion Companion;
+  }
+
+  public static final class BeginGetCredentialRequest.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialRequest request);
+    method public androidx.credentials.provider.BeginGetCredentialRequest? fromBundle(android.os.Bundle bundle);
+  }
+
+  public final class BeginGetCredentialResponse {
+    ctor public BeginGetCredentialResponse(optional java.util.List<? extends androidx.credentials.provider.CredentialEntry> credentialEntries, optional java.util.List<androidx.credentials.provider.Action> actions, optional java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationActions, optional androidx.credentials.provider.RemoteEntry? remoteEntry);
+    method public static android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public static androidx.credentials.provider.BeginGetCredentialResponse? fromBundle(android.os.Bundle bundle);
+    method public java.util.List<androidx.credentials.provider.Action> getActions();
+    method public java.util.List<androidx.credentials.provider.AuthenticationAction> getAuthenticationActions();
+    method public java.util.List<androidx.credentials.provider.CredentialEntry> getCredentialEntries();
+    method public androidx.credentials.provider.RemoteEntry? getRemoteEntry();
+    property public final java.util.List<androidx.credentials.provider.Action> actions;
+    property public final java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationActions;
+    property public final java.util.List<androidx.credentials.provider.CredentialEntry> credentialEntries;
+    property public final androidx.credentials.provider.RemoteEntry? remoteEntry;
+    field public static final androidx.credentials.provider.BeginGetCredentialResponse.Companion Companion;
+  }
+
+  public static final class BeginGetCredentialResponse.Builder {
+    ctor public BeginGetCredentialResponse.Builder();
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addAction(androidx.credentials.provider.Action action);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addAuthenticationAction(androidx.credentials.provider.AuthenticationAction authenticationAction);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder addCredentialEntry(androidx.credentials.provider.CredentialEntry entry);
+    method public androidx.credentials.provider.BeginGetCredentialResponse build();
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setActions(java.util.List<androidx.credentials.provider.Action> actions);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setAuthenticationActions(java.util.List<androidx.credentials.provider.AuthenticationAction> authenticationEntries);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setCredentialEntries(java.util.List<? extends androidx.credentials.provider.CredentialEntry> entries);
+    method public androidx.credentials.provider.BeginGetCredentialResponse.Builder setRemoteEntry(androidx.credentials.provider.RemoteEntry? remoteEntry);
+  }
+
+  public static final class BeginGetCredentialResponse.Companion {
+    method public android.os.Bundle asBundle(androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public androidx.credentials.provider.BeginGetCredentialResponse? fromBundle(android.os.Bundle bundle);
+  }
+
+  public class BeginGetCustomCredentialOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetCustomCredentialOption(String id, String type, android.os.Bundle candidateQueryData);
+  }
+
+  public final class BeginGetPasswordOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetPasswordOption(java.util.Set<java.lang.String> allowedUserIds, android.os.Bundle candidateQueryData, String id);
+    method public java.util.Set<java.lang.String> getAllowedUserIds();
+    property public final java.util.Set<java.lang.String> allowedUserIds;
+  }
+
+  public final class BeginGetPublicKeyCredentialOption extends androidx.credentials.provider.BeginGetCredentialOption {
+    ctor public BeginGetPublicKeyCredentialOption(android.os.Bundle candidateQueryData, String id, String requestJson);
+    ctor public BeginGetPublicKeyCredentialOption(android.os.Bundle candidateQueryData, String id, String requestJson, optional byte[]? clientDataHash);
+    method public byte[]? getClientDataHash();
+    method public String getRequestJson();
+    property public final byte[]? clientDataHash;
+    property public final String requestJson;
+  }
+
+  public final class CallingAppInfo {
+    ctor public CallingAppInfo(String packageName, android.content.pm.SigningInfo signingInfo);
+    ctor public CallingAppInfo(String packageName, android.content.pm.SigningInfo signingInfo, optional String? origin);
+    method public String? getOrigin();
+    method public String getPackageName();
+    method public android.content.pm.SigningInfo getSigningInfo();
+    property public final String? origin;
+    property public final String packageName;
+    property public final android.content.pm.SigningInfo signingInfo;
+  }
+
+  @RequiresApi(28) public final class CreateEntry {
+    ctor public CreateEntry(CharSequence accountName, android.app.PendingIntent pendingIntent, optional CharSequence? description, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon? icon, optional Integer? passwordCredentialCount, optional Integer? publicKeyCredentialCount, optional Integer? totalCredentialCount, optional boolean isAutoSelectAllowed);
+    method public CharSequence getAccountName();
+    method public CharSequence? getDescription();
+    method public android.graphics.drawable.Icon? getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public Integer? getPasswordCredentialCount();
+    method public android.app.PendingIntent getPendingIntent();
+    method public Integer? getPublicKeyCredentialCount();
+    method public Integer? getTotalCredentialCount();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence accountName;
+    property public final CharSequence? description;
+    property public final android.graphics.drawable.Icon? icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+  }
+
+  public static final class CreateEntry.Builder {
+    ctor public CreateEntry.Builder(CharSequence accountName, android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.CreateEntry build();
+    method public androidx.credentials.provider.CreateEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.CreateEntry.Builder setDescription(CharSequence? description);
+    method public androidx.credentials.provider.CreateEntry.Builder setIcon(android.graphics.drawable.Icon? icon);
+    method public androidx.credentials.provider.CreateEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+    method public androidx.credentials.provider.CreateEntry.Builder setPasswordCredentialCount(int count);
+    method public androidx.credentials.provider.CreateEntry.Builder setPublicKeyCredentialCount(int count);
+    method public androidx.credentials.provider.CreateEntry.Builder setTotalCredentialCount(int count);
+  }
+
+  public abstract class CredentialEntry {
+    method public final androidx.credentials.provider.BeginGetCredentialOption getBeginGetCredentialOption();
+    property public final androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption;
+  }
+
+  @RequiresApi(34) public abstract class CredentialProviderService extends android.service.credentials.CredentialProviderService {
+    ctor public CredentialProviderService();
+    method public final void onBeginCreateCredential(android.service.credentials.BeginCreateCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<android.service.credentials.BeginCreateCredentialResponse,android.credentials.CreateCredentialException> callback);
+    method public abstract void onBeginCreateCredentialRequest(androidx.credentials.provider.BeginCreateCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<androidx.credentials.provider.BeginCreateCredentialResponse,androidx.credentials.exceptions.CreateCredentialException> callback);
+    method public final void onBeginGetCredential(android.service.credentials.BeginGetCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<android.service.credentials.BeginGetCredentialResponse,android.credentials.GetCredentialException> callback);
+    method public abstract void onBeginGetCredentialRequest(androidx.credentials.provider.BeginGetCredentialRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<androidx.credentials.provider.BeginGetCredentialResponse,androidx.credentials.exceptions.GetCredentialException> callback);
+    method public final void onClearCredentialState(android.service.credentials.ClearCredentialStateRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<java.lang.Void,android.credentials.ClearCredentialStateException> callback);
+    method public abstract void onClearCredentialStateRequest(androidx.credentials.provider.ProviderClearCredentialStateRequest request, android.os.CancellationSignal cancellationSignal, android.os.OutcomeReceiver<java.lang.Void,androidx.credentials.exceptions.ClearCredentialException> callback);
+  }
+
+  @RequiresApi(28) public final class CustomCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public CustomCredentialEntry(android.content.Context context, CharSequence title, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption, optional CharSequence? subtitle, optional CharSequence? typeDisplayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence? getSubtitle();
+    method public CharSequence getTitle();
+    method public String getType();
+    method public CharSequence? getTypeDisplayName();
+    method public boolean isAutoSelectAllowed();
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence? subtitle;
+    property public final CharSequence title;
+    property public String type;
+    property public final CharSequence? typeDisplayName;
+  }
+
+  public static final class CustomCredentialEntry.Builder {
+    ctor public CustomCredentialEntry.Builder(android.content.Context context, String type, CharSequence title, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetCredentialOption beginGetCredentialOption);
+    method public androidx.credentials.provider.CustomCredentialEntry build();
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setSubtitle(CharSequence? subtitle);
+    method public androidx.credentials.provider.CustomCredentialEntry.Builder setTypeDisplayName(CharSequence? typeDisplayName);
+  }
+
+  public final class IntentHandlerConverters {
+    method @RequiresApi(34) public static androidx.credentials.provider.BeginGetCredentialResponse? getBeginGetResponse(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.CreateCredentialResponse? getCreateCredentialCredentialResponse(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.CreateCredentialException? getCreateCredentialException(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.GetCredentialException? getGetCredentialException(android.content.Intent);
+    method @RequiresApi(34) public static android.credentials.GetCredentialResponse? getGetCredentialResponse(android.content.Intent);
+  }
+
+  @RequiresApi(28) public final class PasswordCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public PasswordCredentialEntry(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPasswordOption beginGetPasswordOption, optional CharSequence? displayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public CharSequence? getDisplayName();
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTypeDisplayName();
+    method public CharSequence getUsername();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence? displayName;
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence typeDisplayName;
+    property public final CharSequence username;
+  }
+
+  public static final class PasswordCredentialEntry.Builder {
+    ctor public PasswordCredentialEntry.Builder(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPasswordOption beginGetPasswordOption);
+    method public androidx.credentials.provider.PasswordCredentialEntry build();
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setDisplayName(CharSequence? displayName);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.PasswordCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+  }
+
+  @RequiresApi(34) public final class PendingIntentHandler {
+    ctor public PendingIntentHandler();
+    method public static androidx.credentials.provider.BeginGetCredentialRequest? retrieveBeginGetCredentialRequest(android.content.Intent intent);
+    method public static androidx.credentials.provider.ProviderCreateCredentialRequest? retrieveProviderCreateCredentialRequest(android.content.Intent intent);
+    method public static androidx.credentials.provider.ProviderGetCredentialRequest? retrieveProviderGetCredentialRequest(android.content.Intent intent);
+    method public static void setBeginGetCredentialResponse(android.content.Intent intent, androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public static void setCreateCredentialException(android.content.Intent intent, androidx.credentials.exceptions.CreateCredentialException exception);
+    method public static void setCreateCredentialResponse(android.content.Intent intent, androidx.credentials.CreateCredentialResponse response);
+    method public static void setGetCredentialException(android.content.Intent intent, androidx.credentials.exceptions.GetCredentialException exception);
+    method public static void setGetCredentialResponse(android.content.Intent intent, androidx.credentials.GetCredentialResponse response);
+    field public static final androidx.credentials.provider.PendingIntentHandler.Companion Companion;
+  }
+
+  public static final class PendingIntentHandler.Companion {
+    method public androidx.credentials.provider.BeginGetCredentialRequest? retrieveBeginGetCredentialRequest(android.content.Intent intent);
+    method public androidx.credentials.provider.ProviderCreateCredentialRequest? retrieveProviderCreateCredentialRequest(android.content.Intent intent);
+    method public androidx.credentials.provider.ProviderGetCredentialRequest? retrieveProviderGetCredentialRequest(android.content.Intent intent);
+    method public void setBeginGetCredentialResponse(android.content.Intent intent, androidx.credentials.provider.BeginGetCredentialResponse response);
+    method public void setCreateCredentialException(android.content.Intent intent, androidx.credentials.exceptions.CreateCredentialException exception);
+    method public void setCreateCredentialResponse(android.content.Intent intent, androidx.credentials.CreateCredentialResponse response);
+    method public void setGetCredentialException(android.content.Intent intent, androidx.credentials.exceptions.GetCredentialException exception);
+    method public void setGetCredentialResponse(android.content.Intent intent, androidx.credentials.GetCredentialResponse response);
+  }
+
+  public final class ProviderClearCredentialStateRequest {
+    ctor public ProviderClearCredentialStateRequest(androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+  }
+
+  public final class ProviderCreateCredentialRequest {
+    ctor public ProviderCreateCredentialRequest(androidx.credentials.CreateCredentialRequest callingRequest, androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    method public androidx.credentials.CreateCredentialRequest getCallingRequest();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+    property public final androidx.credentials.CreateCredentialRequest callingRequest;
+  }
+
+  public final class ProviderGetCredentialRequest {
+    ctor public ProviderGetCredentialRequest(java.util.List<? extends androidx.credentials.CredentialOption> credentialOptions, androidx.credentials.provider.CallingAppInfo callingAppInfo);
+    method public androidx.credentials.provider.CallingAppInfo getCallingAppInfo();
+    method public java.util.List<androidx.credentials.CredentialOption> getCredentialOptions();
+    property public final androidx.credentials.provider.CallingAppInfo callingAppInfo;
+    property public final java.util.List<androidx.credentials.CredentialOption> credentialOptions;
+  }
+
+  @RequiresApi(28) public final class PublicKeyCredentialEntry extends androidx.credentials.provider.CredentialEntry {
+    ctor public PublicKeyCredentialEntry(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPublicKeyCredentialOption beginGetPublicKeyCredentialOption, optional CharSequence? displayName, optional java.time.Instant? lastUsedTime, optional android.graphics.drawable.Icon icon, optional boolean isAutoSelectAllowed);
+    method public CharSequence? getDisplayName();
+    method public android.graphics.drawable.Icon getIcon();
+    method public java.time.Instant? getLastUsedTime();
+    method public android.app.PendingIntent getPendingIntent();
+    method public CharSequence getTypeDisplayName();
+    method public CharSequence getUsername();
+    method public boolean isAutoSelectAllowed();
+    property public final CharSequence? displayName;
+    property public final android.graphics.drawable.Icon icon;
+    property public final boolean isAutoSelectAllowed;
+    property public final java.time.Instant? lastUsedTime;
+    property public final android.app.PendingIntent pendingIntent;
+    property public final CharSequence typeDisplayName;
+    property public final CharSequence username;
+  }
+
+  public static final class PublicKeyCredentialEntry.Builder {
+    ctor public PublicKeyCredentialEntry.Builder(android.content.Context context, CharSequence username, android.app.PendingIntent pendingIntent, androidx.credentials.provider.BeginGetPublicKeyCredentialOption beginGetPublicKeyCredentialOption);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry build();
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setAutoSelectAllowed(boolean autoSelectAllowed);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setDisplayName(CharSequence? displayName);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setIcon(android.graphics.drawable.Icon icon);
+    method public androidx.credentials.provider.PublicKeyCredentialEntry.Builder setLastUsedTime(java.time.Instant? lastUsedTime);
+  }
+
+  public final class RemoteEntry {
+    ctor public RemoteEntry(android.app.PendingIntent pendingIntent);
+    method public android.app.PendingIntent getPendingIntent();
+    property public final android.app.PendingIntent pendingIntent;
+  }
+
+  public static final class RemoteEntry.Builder {
+    ctor public RemoteEntry.Builder(android.app.PendingIntent pendingIntent);
+    method public androidx.credentials.provider.RemoteEntry build();
+  }
+
+}
+
diff --git a/credentials/credentials/build.gradle b/credentials/credentials/build.gradle
index c548aa0..0a9bae2 100644
--- a/credentials/credentials/build.gradle
+++ b/credentials/credentials/build.gradle
@@ -26,6 +26,7 @@
     api("androidx.annotation:annotation:1.5.0")
     api(libs.kotlinStdlib)
     implementation(libs.kotlinCoroutinesCore)
+    api(project(":core:core"))
 
     androidTestImplementation("androidx.activity:activity:1.2.0")
     androidTestImplementation(libs.junit)
@@ -36,6 +37,9 @@
     androidTestImplementation(libs.truth)
     androidTestImplementation(project(":internal-testutils-truth"))
     androidTestImplementation(libs.kotlinCoroutinesAndroid)
+    androidTestImplementation(project(":internal-testutils-runtime"), {
+        exclude group: "androidx.fragment", module: "fragment"
+    })
 }
 
 android {
diff --git a/credentials/credentials/lint-baseline.xml b/credentials/credentials/lint-baseline.xml
index 7371789..48549177 100644
--- a/credentials/credentials/lint-baseline.xml
+++ b/credentials/credentials/lint-baseline.xml
@@ -2,6 +2,744 @@
 <issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder("
+        errorLine2="                                     ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder("
+        errorLine2="                                     ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Uri.EMPTY, SliceSpec("
+        errorLine2="                           ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Uri.EMPTY, SliceSpec("
+        errorLine2="                           ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText("
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText("
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText("
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText("
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            sliceBuilder.addAction("
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            sliceBuilder.addAction("
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Slice.Builder(sliceBuilder)"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Slice.Builder(sliceBuilder)"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .build(),"
+        errorLine2="                     ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .build(),"
+        errorLine2="                     ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_TITLE)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_TITLE)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    title = it.text"
+        errorLine2="                               ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    title = it.text"
+        errorLine2="                               ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    subtitle = it.text"
+        errorLine2="                                  ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    subtitle = it.text"
+        errorLine2="                                  ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.Action.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/Action.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder("
+        errorLine2="                                     ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder("
+        errorLine2="                                     ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Uri.EMPTY, SliceSpec("
+        errorLine2="                           ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Uri.EMPTY, SliceSpec("
+        errorLine2="                           ^">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addAction("
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addAction("
+        errorLine2="                 ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    Slice.Builder(sliceBuilder)"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    Slice.Builder(sliceBuilder)"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                         ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                         ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                        .build(),"
+        errorLine2="                         ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                        .build(),"
+        errorLine2="                         ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText(title, /*subType=*/null, listOf(SLICE_HINT_TITLE))"
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                .addText(title, /*subType=*/null, listOf(SLICE_HINT_TITLE))"
+        errorLine2="                 ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_TITLE)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                } else if (it.hasHint(SLICE_HINT_TITLE)) {"
+        errorLine2="                              ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    title = it.text"
+        errorLine2="                               ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.AuthenticationAction.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    title = it.text"
+        errorLine2="                               ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/AuthenticationAction.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.CredentialEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                when (slice.spec?.type) {"
+        errorLine2="                            ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/CredentialEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.CredentialEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                when (slice.spec?.type) {"
+        errorLine2="                                  ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/CredentialEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.CredentialEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                when (slice.spec?.type) {"
+        errorLine2="                            ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/CredentialEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.CredentialEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                when (slice.spec?.type) {"
+        errorLine2="                                  ~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/CredentialEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec(&quot;type&quot;, 1))"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec(&quot;type&quot;, 1))"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec(&quot;type&quot;, 1))"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec(&quot;type&quot;, 1))"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            sliceBuilder.addAction("
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            sliceBuilder.addAction("
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Slice.Builder(sliceBuilder)"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                Slice.Builder(sliceBuilder)"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))"
+        errorLine2="                     ~~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .build(), /*subType=*/null"
+        errorLine2="                     ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    .build(), /*subType=*/null"
+        errorLine2="                     ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            return sliceBuilder.build()"
+        errorLine2="                                ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="            slice.items.forEach {"
+        errorLine2="                  ~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {"
+        errorLine2="                       ~~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
+        id="ClassVerificationFailure"
+        message="This call references a method added in API level 28; however, the containing class androidx.credentials.provider.RemoteEntry.Companion is reachable from earlier API levels and will fail run-time class verification."
+        errorLine1="                    pendingIntent = it.action"
+        errorLine2="                                       ~~~~~~">
+        <location
+            file="src/main/java/androidx/credentials/provider/RemoteEntry.kt"/>
+    </issue>
+
+    <issue
         id="UsesNonDefaultVisibleForTesting"
         message="Found non-default `otherwise` value for @VisibleForTesting"
         errorLine1="    @get:VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)"
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoJavaTest.java
index 40acdb0..62ef10f 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoJavaTest.java
@@ -78,7 +78,24 @@
         assertThat(displayInfo.getUserId()).isEqualTo(expectedUserId);
         assertThat(displayInfo.getUserDisplayName()).isEqualTo(expectedDisplayName);
         assertThat(displayInfo.getCredentialTypeIcon()).isNull();
-        assertThat(displayInfo.getDefaultProvider()).isNull();
+        assertThat(displayInfo.getPreferDefaultProvider()).isNull();
+    }
+
+    @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+    @Test
+    public void constructWithUserIdAndDisplayNameAndDefaultProvider_success() {
+        CharSequence expectedUserId = "userId";
+        CharSequence expectedDisplayName = "displayName";
+        String expectedDefaultProvider = "com.test/com.test.TestProviderComponent";
+
+        CreateCredentialRequest.DisplayInfo displayInfo =
+                new CreateCredentialRequest.DisplayInfo(expectedUserId,
+                        expectedDisplayName, expectedDefaultProvider);
+
+        assertThat(displayInfo.getUserId()).isEqualTo(expectedUserId);
+        assertThat(displayInfo.getUserDisplayName()).isEqualTo(expectedDisplayName);
+        assertThat(displayInfo.getCredentialTypeIcon()).isNull();
+        assertThat(displayInfo.getPreferDefaultProvider()).isEqualTo(expectedDefaultProvider);
     }
 
     @SdkSuppress(minSdkVersion = 28)
@@ -96,7 +113,7 @@
         assertThat(displayInfo.getUserId()).isEqualTo(expectedUserId);
         assertThat(displayInfo.getUserDisplayName()).isEqualTo(expectedDisplayName);
         assertThat(displayInfo.getCredentialTypeIcon()).isEqualTo(expectedIcon);
-        assertThat(displayInfo.getDefaultProvider()).isEqualTo(expectedDefaultProvider);
+        assertThat(displayInfo.getPreferDefaultProvider()).isEqualTo(expectedDefaultProvider);
     }
 
     @SdkSuppress(minSdkVersion = 28)
@@ -115,6 +132,6 @@
         assertThat(displayInfo.getUserDisplayName()).isNull();
         assertThat(displayInfo.getCredentialTypeIcon().getResId()).isEqualTo(
                 R.drawable.ic_password);
-        assertThat(displayInfo.getDefaultProvider()).isNull();
+        assertThat(displayInfo.getPreferDefaultProvider()).isNull();
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoTest.kt
index bfde3e9..a495264 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCredentialRequestDisplayInfoTest.kt
@@ -66,7 +66,26 @@
         assertThat(displayInfo.userId).isEqualTo(expectedUserId)
         assertThat(displayInfo.userDisplayName).isEqualTo(expectedDisplayName)
         assertThat(displayInfo.credentialTypeIcon).isNull()
-        assertThat(displayInfo.defaultProvider).isNull()
+        assertThat(displayInfo.preferDefaultProvider).isNull()
+    }
+
+    @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+    @Test
+    fun constructWithUserIdAndDisplayNameAndDefaultProvider_success() {
+        val expectedUserId: CharSequence = "userId"
+        val expectedDisplayName: CharSequence = "displayName"
+        val expectedDefaultProvider = "com.test/com.test.TestProviderComponent"
+
+        val displayInfo = DisplayInfo(
+            userId = expectedUserId,
+            userDisplayName = expectedDisplayName,
+            preferDefaultProvider = expectedDefaultProvider
+        )
+
+        assertThat(displayInfo.userId).isEqualTo(expectedUserId)
+        assertThat(displayInfo.userDisplayName).isEqualTo(expectedDisplayName)
+        assertThat(displayInfo.credentialTypeIcon).isNull()
+        assertThat(displayInfo.preferDefaultProvider).isEqualTo(expectedDefaultProvider)
     }
 
     @SdkSuppress(minSdkVersion = 28)
@@ -85,7 +104,7 @@
         assertThat(displayInfo.userId).isEqualTo(expectedUserId)
         assertThat(displayInfo.userDisplayName).isEqualTo(expectedDisplayName)
         assertThat(displayInfo.credentialTypeIcon).isEqualTo(expectedIcon)
-        assertThat(displayInfo.defaultProvider).isEqualTo(expectedDefaultProvider)
+        assertThat(displayInfo.preferDefaultProvider).isEqualTo(expectedDefaultProvider)
     }
 
     @SdkSuppress(minSdkVersion = 28)
@@ -105,6 +124,6 @@
         assertThat(displayInfo.credentialTypeIcon?.resId).isEqualTo(
             R.drawable.ic_password
         )
-        assertThat(displayInfo.defaultProvider).isNull()
+        assertThat(displayInfo.preferDefaultProvider).isNull()
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestJavaTest.java
index 893f37b..66ef8ac 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestJavaTest.java
@@ -16,12 +16,17 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED;
+import static androidx.credentials.CreateCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
 import android.os.Bundle;
 
+import androidx.test.filters.SdkSuppress;
+
 import org.junit.Test;
 
 public class CreateCustomCredentialRequestJavaTest {
@@ -71,24 +76,37 @@
                 new CreateCredentialRequest.DisplayInfo("userId"), true);
     }
 
+    @SdkSuppress(minSdkVersion = 26)
     @Test
     public void getter() {
         String expectedType = "TYPE";
-        Bundle expectedCredentialDataBundle = new Bundle();
-        expectedCredentialDataBundle.putString("Test", "Test");
-        Bundle expectedCandidateQueryDataBundle = new Bundle();
-        expectedCandidateQueryDataBundle.putBoolean("key", true);
+        boolean expectedAutoSelectAllowed = true;
+        boolean expectedPreferImmediatelyAvailableCredentials = true;
+        Bundle inputCredentialDataBundle = new Bundle();
+        inputCredentialDataBundle.putString("Test", "Test");
+        Bundle expectedCredentialDataBundle = inputCredentialDataBundle.deepCopy();
+        expectedCredentialDataBundle.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+                expectedAutoSelectAllowed);
+        expectedCredentialDataBundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+                expectedPreferImmediatelyAvailableCredentials);
+        Bundle inputCandidateQueryDataBundle = new Bundle();
+        inputCandidateQueryDataBundle.putBoolean("key", true);
+        Bundle expectedCandidateQueryDataBundle = inputCandidateQueryDataBundle.deepCopy();
+        expectedCandidateQueryDataBundle.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+                expectedAutoSelectAllowed);
         CreateCredentialRequest.DisplayInfo expectedDisplayInfo =
                 new CreateCredentialRequest.DisplayInfo("userId");
         boolean expectedSystemProvider = true;
-        boolean expectedAutoSelectAllowed = false;
+        String expectedOrigin = "Origin";
 
         CreateCustomCredentialRequest request = new CreateCustomCredentialRequest(expectedType,
-                expectedCredentialDataBundle,
-                expectedCandidateQueryDataBundle,
+                inputCredentialDataBundle,
+                inputCandidateQueryDataBundle,
                 expectedSystemProvider,
                 expectedDisplayInfo,
-                expectedAutoSelectAllowed);
+                expectedAutoSelectAllowed,
+                expectedOrigin,
+                expectedPreferImmediatelyAvailableCredentials);
 
         assertThat(request.getType()).isEqualTo(expectedType);
         assertThat(TestUtilsKt.equals(request.getCredentialData(), expectedCredentialDataBundle))
@@ -97,7 +115,10 @@
                 expectedCandidateQueryDataBundle)).isTrue();
         assertThat(request.isSystemProviderRequired()).isEqualTo(expectedSystemProvider);
         assertThat(request.isAutoSelectAllowed()).isEqualTo(expectedAutoSelectAllowed);
+        assertThat(request.preferImmediatelyAvailableCredentials()).isEqualTo(
+                expectedPreferImmediatelyAvailableCredentials);
         assertThat(request.getDisplayInfo()).isEqualTo(expectedDisplayInfo);
+        assertThat(request.getOrigin()).isEqualTo(expectedOrigin);
     }
 
     @Test
@@ -107,4 +128,57 @@
                         new Bundle(), new Bundle(), false,
                         /* requestDisplayInfo= */null, false));
     }
+
+
+    @SdkSuppress(minSdkVersion = 23)
+    @Test
+    public void frameworkConversion_success() {
+        String expectedType = "TYPE";
+        Bundle expectedCredentialDataBundle = new Bundle();
+        expectedCredentialDataBundle.putString("Test", "Test");
+        Bundle expectedCandidateQueryDataBundle = new Bundle();
+        expectedCandidateQueryDataBundle.putBoolean("key", true);
+        CreateCredentialRequest.DisplayInfo expectedDisplayInfo =
+                new CreateCredentialRequest.DisplayInfo("userId");
+        boolean expectedSystemProvider = true;
+        boolean expectedAutoSelectAllowed = true;
+        boolean expectedPreferImmediatelyAvailableCredentials = true;
+        String expectedOrigin = "Origin";
+        CreateCustomCredentialRequest request = new CreateCustomCredentialRequest(expectedType,
+                expectedCredentialDataBundle,
+                expectedCandidateQueryDataBundle,
+                expectedSystemProvider,
+                expectedDisplayInfo,
+                expectedAutoSelectAllowed,
+                expectedOrigin,
+                expectedPreferImmediatelyAvailableCredentials);
+        Bundle finalCredentialData = request.getCredentialData();
+        finalCredentialData.putBundle(
+                CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_REQUEST_DISPLAY_INFO,
+                expectedDisplayInfo.toBundle()
+        );
+
+        CreateCredentialRequest convertedRequest = CreateCredentialRequest.createFrom(
+                request.getType(), request.getCredentialData(), request.getCandidateQueryData(),
+                request.isSystemProviderRequired(), request.getOrigin());
+
+        assertThat(convertedRequest).isInstanceOf(CreateCustomCredentialRequest.class);
+        CreateCustomCredentialRequest actualRequest =
+                (CreateCustomCredentialRequest) convertedRequest;
+        assertThat(actualRequest.getType()).isEqualTo(expectedType);
+        assertThat(TestUtilsKt.equals(actualRequest.getCredentialData(),
+                expectedCredentialDataBundle))
+                .isTrue();
+        assertThat(TestUtilsKt.equals(actualRequest.getCandidateQueryData(),
+                expectedCandidateQueryDataBundle)).isTrue();
+        assertThat(actualRequest.isSystemProviderRequired()).isEqualTo(expectedSystemProvider);
+        assertThat(actualRequest.isAutoSelectAllowed()).isEqualTo(expectedAutoSelectAllowed);
+        assertThat(actualRequest.getDisplayInfo().getUserId())
+                .isEqualTo(expectedDisplayInfo.getUserId());
+        assertThat(actualRequest.getDisplayInfo().getUserDisplayName())
+                .isEqualTo(expectedDisplayInfo.getUserDisplayName());
+        assertThat(actualRequest.getOrigin()).isEqualTo(expectedOrigin);
+        assertThat(actualRequest.preferImmediatelyAvailableCredentials()).isEqualTo(
+                expectedPreferImmediatelyAvailableCredentials);
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestTest.kt
index def2dfb..ccc00f3 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreateCustomCredentialRequestTest.kt
@@ -17,7 +17,9 @@
 package androidx.credentials
 
 import android.os.Bundle
+import androidx.credentials.CreateCredentialRequest.Companion.createFrom
 import androidx.credentials.CreateCredentialRequest.DisplayInfo
+import androidx.test.filters.SdkSuppress
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertThrows
 import org.junit.Test
@@ -36,24 +38,43 @@
         }
     }
 
+    @SdkSuppress(minSdkVersion = 26)
     @Test
     fun getter() {
         val expectedType = "TYPE"
-        val expectedCredentialDataBundle = Bundle()
-        expectedCredentialDataBundle.putString("Test", "Test")
-        val expectedCandidateQueryDataBundle = Bundle()
-        expectedCandidateQueryDataBundle.putBoolean("key", true)
+        val expectedAutoSelectAllowed = true
+        val expectedPreferImmediatelyAvailableCredentials = true
+        val inputCredentialDataBundle = Bundle()
+        inputCredentialDataBundle.putString("Test", "Test")
+        val expectedCredentialDataBundle = inputCredentialDataBundle.deepCopy()
+        expectedCredentialDataBundle.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+            expectedAutoSelectAllowed
+        )
+        expectedCredentialDataBundle.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+            expectedPreferImmediatelyAvailableCredentials
+        )
+        val inputCandidateQueryDataBundle = Bundle()
+        inputCandidateQueryDataBundle.putBoolean("key", true)
+        val expectedCandidateQueryDataBundle = inputCandidateQueryDataBundle.deepCopy()
+        expectedCandidateQueryDataBundle.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+            expectedAutoSelectAllowed
+        )
         val expectedDisplayInfo = DisplayInfo("userId")
-        val expectedAutoSelectAllowed = false
         val expectedSystemProvider = true
+        val expectedOrigin = "Origin"
 
         val request = CreateCustomCredentialRequest(
             expectedType,
-            expectedCredentialDataBundle,
-            expectedCandidateQueryDataBundle,
+            inputCredentialDataBundle,
+            inputCandidateQueryDataBundle,
             expectedSystemProvider,
             expectedDisplayInfo,
-            expectedAutoSelectAllowed
+            expectedAutoSelectAllowed,
+            expectedOrigin,
+            expectedPreferImmediatelyAvailableCredentials
         )
 
         assertThat(request.type).isEqualTo(expectedType)
@@ -65,8 +86,74 @@
                 expectedCandidateQueryDataBundle
             )
         ).isTrue()
-        assertThat(request.isAutoSelectAllowed).isEqualTo(expectedAutoSelectAllowed)
         assertThat(request.isSystemProviderRequired).isEqualTo(expectedSystemProvider)
+        assertThat(request.isAutoSelectAllowed).isEqualTo(expectedAutoSelectAllowed)
+        assertThat(request.preferImmediatelyAvailableCredentials).isEqualTo(
+            expectedPreferImmediatelyAvailableCredentials
+        )
         assertThat(request.displayInfo).isEqualTo(expectedDisplayInfo)
+        assertThat(request.origin).isEqualTo(expectedOrigin)
+    }
+
+    @SdkSuppress(minSdkVersion = 23)
+    @Test
+    fun frameworkConversion_success() {
+        val expectedType = "TYPE"
+        val expectedCredentialDataBundle = Bundle()
+        expectedCredentialDataBundle.putString("Test", "Test")
+        val expectedCandidateQueryDataBundle = Bundle()
+        expectedCandidateQueryDataBundle.putBoolean("key", true)
+        val expectedDisplayInfo = DisplayInfo("userId")
+        val expectedSystemProvider = true
+        val expectedAutoSelectAllowed = true
+        val expectedPreferImmediatelyAvailableCredentials = true
+        val expectedOrigin = "Origin"
+        val request = CreateCustomCredentialRequest(
+            expectedType,
+            expectedCredentialDataBundle,
+            expectedCandidateQueryDataBundle,
+            expectedSystemProvider,
+            expectedDisplayInfo,
+            expectedAutoSelectAllowed,
+            expectedOrigin,
+            expectedPreferImmediatelyAvailableCredentials,
+        )
+        val finalCredentialData = request.credentialData
+        finalCredentialData.putBundle(
+            DisplayInfo.BUNDLE_KEY_REQUEST_DISPLAY_INFO,
+            expectedDisplayInfo.toBundle()
+        )
+
+        val convertedRequest = createFrom(
+            request.type, request.credentialData, request.candidateQueryData,
+            request.isSystemProviderRequired, request.origin
+        )!!
+
+        assertThat(convertedRequest).isInstanceOf(CreateCustomCredentialRequest::class.java)
+        val actualRequest = convertedRequest as CreateCustomCredentialRequest
+        assertThat(actualRequest.type).isEqualTo(expectedType)
+        assertThat(
+            equals(
+                actualRequest.credentialData,
+                expectedCredentialDataBundle
+            )
+        ).isTrue()
+        assertThat(
+            equals(
+                actualRequest.candidateQueryData,
+                expectedCandidateQueryDataBundle
+            )
+        ).isTrue()
+        assertThat(actualRequest.isSystemProviderRequired).isEqualTo(expectedSystemProvider)
+        assertThat(actualRequest.isAutoSelectAllowed).isEqualTo(expectedAutoSelectAllowed)
+        assertThat(actualRequest.displayInfo.userId)
+            .isEqualTo(expectedDisplayInfo.userId)
+        assertThat(actualRequest.displayInfo.userDisplayName)
+            .isEqualTo(expectedDisplayInfo.userDisplayName)
+        assertThat(actualRequest.origin).isEqualTo(expectedOrigin)
+        assertThat(actualRequest.origin).isEqualTo(expectedOrigin)
+        assertThat(actualRequest.preferImmediatelyAvailableCredentials).isEqualTo(
+            expectedPreferImmediatelyAvailableCredentials
+        )
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java
index d002fbd..1e8d7ad 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java
@@ -16,6 +16,7 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.CreateCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS;
 import static androidx.credentials.internal.FrameworkImplHelper.getFinalCreateCredentialData;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -56,6 +57,42 @@
     }
 
     @Test
+    public void constructor_withDefaults() {
+        String idExpected = "id";
+        String passwordExpected = "password";
+
+        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, passwordExpected);
+
+        assertThat(request.getDisplayInfo().getPreferDefaultProvider()).isNull();
+        assertThat(request.preferImmediatelyAvailableCredentials()).isFalse();
+        assertThat(request.getOrigin()).isNull();
+        assertThat(request.getId()).isEqualTo(idExpected);
+        assertThat(request.getPassword()).isEqualTo(passwordExpected);
+        assertThat(request.isAutoSelectAllowed()).isFalse();
+    }
+
+    @Test
+    public void constructor_withoutDefaults() {
+        String idExpected = "id";
+        String passwordExpected = "password";
+        String originExpected = "origin";
+        boolean preferImmediatelyAvailableCredentialsExpected = true;
+        boolean isAutoSelectAllowedExpected = true;
+
+        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, passwordExpected,
+                originExpected, preferImmediatelyAvailableCredentialsExpected,
+                isAutoSelectAllowedExpected);
+
+        assertThat(request.preferImmediatelyAvailableCredentials())
+                .isEqualTo(preferImmediatelyAvailableCredentialsExpected);
+        assertThat(request.getDisplayInfo().getPreferDefaultProvider()).isNull();
+        assertThat(request.getOrigin()).isEqualTo(originExpected);
+        assertThat(request.getId()).isEqualTo(idExpected);
+        assertThat(request.getPassword()).isEqualTo(passwordExpected);
+        assertThat(request.isAutoSelectAllowed()).isEqualTo(isAutoSelectAllowedExpected);
+    }
+
+    @Test
     public void constructor_emptyPassword_throws() {
         assertThrows(
                 IllegalArgumentException.class,
@@ -63,6 +100,31 @@
         );
     }
 
+    @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+    @Test
+    public void constructor_defaultProviderVariant() {
+        String idExpected = "id";
+        String passwordExpected = "pwd";
+        String originExpected = "origin";
+        boolean preferImmediatelyAvailableCredentialsExpected = true;
+        String defaultProviderExpected = "com.test/com.test.TestProviderComponent";
+        boolean isAutoSelectAllowedExpected = true;
+
+        CreatePasswordRequest request = new CreatePasswordRequest(
+                idExpected, passwordExpected, originExpected, defaultProviderExpected,
+                preferImmediatelyAvailableCredentialsExpected,
+                isAutoSelectAllowedExpected);
+
+        assertThat(request.getDisplayInfo().getPreferDefaultProvider())
+                .isEqualTo(defaultProviderExpected);
+        assertThat(request.preferImmediatelyAvailableCredentials())
+                .isEqualTo(preferImmediatelyAvailableCredentialsExpected);
+        assertThat(request.getOrigin()).isEqualTo(originExpected);
+        assertThat(request.getId()).isEqualTo(idExpected);
+        assertThat(request.getPassword()).isEqualTo(passwordExpected);
+        assertThat(request.isAutoSelectAllowed()).isEqualTo(isAutoSelectAllowedExpected);
+    }
+
     @Test
     public void getter_id() {
         String idExpected = "id";
@@ -83,29 +145,40 @@
     public void getter_frameworkProperties() {
         String idExpected = "id";
         String passwordExpected = "pwd";
-        Bundle expectedData = new Bundle();
-        boolean expectedAutoSelect = false;
-        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_ID, idExpected);
-        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_PASSWORD, passwordExpected);
-        expectedData.putBoolean(CreatePasswordRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+        boolean preferImmediatelyAvailableCredentialsExpected = true;
+        Bundle expectedCredentialData = new Bundle();
+        boolean expectedAutoSelect = true;
+        expectedCredentialData.putString(CreatePasswordRequest.BUNDLE_KEY_ID, idExpected);
+        expectedCredentialData.putString(CreatePasswordRequest.BUNDLE_KEY_PASSWORD,
+                passwordExpected);
+        expectedCredentialData.putBoolean(CreatePasswordRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+                expectedAutoSelect);
+        expectedCredentialData.putBoolean(
+                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+                preferImmediatelyAvailableCredentialsExpected);
+        Bundle expectedCandidateData = new Bundle();
+        expectedCandidateData.putBoolean(CreatePasswordRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
                 expectedAutoSelect);
 
-        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, passwordExpected);
+        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, passwordExpected,
+                /*origin=*/ null, preferImmediatelyAvailableCredentialsExpected,
+                expectedAutoSelect);
 
         assertThat(request.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
         CreateCredentialRequest.DisplayInfo displayInfo =
                 request.getDisplayInfo();
         assertThat(displayInfo.getUserDisplayName()).isNull();
         assertThat(displayInfo.getUserId()).isEqualTo(idExpected);
-        assertThat(TestUtilsKt.equals(request.getCandidateQueryData(), Bundle.EMPTY)).isTrue();
+        assertThat(TestUtilsKt.equals(request.getCandidateQueryData(), expectedCandidateData))
+                .isTrue();
         assertThat(request.isSystemProviderRequired()).isFalse();
         Bundle credentialData =
                 getFinalCreateCredentialData(
                         request, mContext);
         assertThat(credentialData.keySet())
-                .hasSize(expectedData.size() + /* added request info */ 1);
-        for (String key : expectedData.keySet()) {
-            assertThat(credentialData.get(key)).isEqualTo(credentialData.get(key));
+                .hasSize(expectedCredentialData.size() + /* added request info */ 1);
+        for (String key : expectedCredentialData.keySet()) {
+            assertThat(credentialData.get(key)).isEqualTo(expectedCredentialData.get(key));
         }
         Bundle displayInfoBundle =
                 credentialData.getBundle(
@@ -122,25 +195,50 @@
     @Test
     public void frameworkConversion_success() {
         String idExpected = "id";
-        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, "password");
+        String passwordExpected = "pwd";
+        boolean preferImmediatelyAvailableCredentialsExpected = true;
+        String originExpected = "origin";
+        String defaultProviderExpected = "com.test/com.test.TestProviderComponent";
+        boolean isAutoSelectAllowedExpected = true;
+        CreatePasswordRequest request = new CreatePasswordRequest(
+                idExpected, passwordExpected, originExpected, defaultProviderExpected,
+                preferImmediatelyAvailableCredentialsExpected, isAutoSelectAllowedExpected);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle credentialData = getFinalCreateCredentialData(
+                request, mContext);
+        String customRequestDataKey = "customRequestDataKey";
+        String customRequestDataValue = "customRequestDataValue";
+        credentialData.putString(customRequestDataKey, customRequestDataValue);
+        Bundle candidateQueryData = request.getCandidateQueryData();
+        String customCandidateQueryDataKey = "customRequestDataKey";
+        Boolean customCandidateQueryDataValue = true;
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue);
 
         CreateCredentialRequest convertedRequest = CreateCredentialRequest.createFrom(
-                request.getType(), getFinalCreateCredentialData(
-                        request, mContext),
-                request.getCandidateQueryData(), request.isSystemProviderRequired(),
-                request.getOrigin()
-        );
+                request.getType(), credentialData, candidateQueryData,
+                request.isSystemProviderRequired(), request.getOrigin());
 
         assertThat(convertedRequest).isInstanceOf(CreatePasswordRequest.class);
         CreatePasswordRequest convertedCreatePasswordRequest =
                 (CreatePasswordRequest) convertedRequest;
-        assertThat(convertedCreatePasswordRequest.getPassword()).isEqualTo(request.getPassword());
-        assertThat(convertedCreatePasswordRequest.getId()).isEqualTo(request.getId());
+        assertThat(convertedCreatePasswordRequest.getPassword()).isEqualTo(passwordExpected);
+        assertThat(convertedCreatePasswordRequest.getId()).isEqualTo(idExpected);
+        assertThat(convertedCreatePasswordRequest.preferImmediatelyAvailableCredentials())
+                .isEqualTo(preferImmediatelyAvailableCredentialsExpected);
+        assertThat(convertedCreatePasswordRequest.getOrigin()).isEqualTo(originExpected);
+        assertThat(convertedCreatePasswordRequest.isAutoSelectAllowed())
+                .isEqualTo(isAutoSelectAllowedExpected);
         CreateCredentialRequest.DisplayInfo displayInfo =
                 convertedCreatePasswordRequest.getDisplayInfo();
         assertThat(displayInfo.getUserDisplayName()).isNull();
         assertThat(displayInfo.getUserId()).isEqualTo(idExpected);
         assertThat(displayInfo.getCredentialTypeIcon().getResId())
                 .isEqualTo(R.drawable.ic_password);
+        assertThat(displayInfo.getPreferDefaultProvider()).isEqualTo(defaultProviderExpected);
+        assertThat(convertedRequest.getCredentialData().getString(customRequestDataKey))
+                .isEqualTo(customRequestDataValue);
+        assertThat(convertedRequest.getCandidateQueryData().getBoolean(customCandidateQueryDataKey))
+                .isEqualTo(customCandidateQueryDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt
index 6aeb65d..bb39755 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt
@@ -18,7 +18,9 @@
 
 import android.graphics.drawable.Icon
 import android.os.Bundle
+import android.os.Parcelable
 import androidx.credentials.CreateCredentialRequest.Companion.createFrom
+import androidx.credentials.CreateCredentialRequest.DisplayInfo
 import androidx.credentials.internal.FrameworkImplHelper.Companion.getFinalCreateCredentialData
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
@@ -43,6 +45,71 @@
     }
 
     @Test
+    fun constructor_withDefaults() {
+        val idExpected = "id"
+        val passwordExpected = "password"
+
+        val request = CreatePasswordRequest(idExpected, passwordExpected)
+
+        assertThat(request.displayInfo.preferDefaultProvider).isNull()
+        assertThat(request.preferImmediatelyAvailableCredentials).isFalse()
+        assertThat(request.origin).isNull()
+        assertThat(request.id).isEqualTo(idExpected)
+        assertThat(request.password).isEqualTo(passwordExpected)
+        assertThat(request.isAutoSelectAllowed).isFalse()
+    }
+
+    @Test
+    fun constructor_withoutDefaults() {
+        val idExpected = "id"
+        val passwordExpected = "password"
+        val originExpected = "origin"
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val isAutoSelectAllowedExpected = true
+
+        val request = CreatePasswordRequest(
+            idExpected, passwordExpected,
+            originExpected, preferImmediatelyAvailableCredentialsExpected,
+            isAutoSelectAllowedExpected,
+        )
+
+        assertThat(request.preferImmediatelyAvailableCredentials)
+            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        assertThat(request.displayInfo.preferDefaultProvider).isNull()
+        assertThat(request.origin).isEqualTo(originExpected)
+        assertThat(request.id).isEqualTo(idExpected)
+        assertThat(request.password).isEqualTo(passwordExpected)
+        assertThat(request.isAutoSelectAllowed).isEqualTo(isAutoSelectAllowedExpected)
+    }
+
+    @Test
+    fun constructor_defaultProviderVariant() {
+        val idExpected = "id"
+        val passwordExpected = "pwd"
+        val originExpected = "origin"
+        val defaultProviderExpected = "com.test/com.test.TestProviderComponent"
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val isAutoSelectAllowedExpected = true
+
+        val request = CreatePasswordRequest(
+            id = idExpected,
+            password = passwordExpected,
+            origin = originExpected,
+            preferDefaultProvider = defaultProviderExpected,
+            preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentialsExpected,
+            isAutoSelectAllowed = isAutoSelectAllowedExpected
+        )
+
+        assertThat(request.displayInfo.preferDefaultProvider).isEqualTo(defaultProviderExpected)
+        assertThat(request.origin).isEqualTo(originExpected)
+        assertThat(request.password).isEqualTo(passwordExpected)
+        assertThat(request.id).isEqualTo(idExpected)
+        assertThat(request.preferImmediatelyAvailableCredentials)
+            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        assertThat(request.isAutoSelectAllowed).isEqualTo(isAutoSelectAllowedExpected)
+    }
+
+    @Test
     fun getter_id() {
         val idExpected = "id"
         val request = CreatePasswordRequest(idExpected, "password")
@@ -62,39 +129,61 @@
     fun getter_frameworkProperties() {
         val idExpected = "id"
         val passwordExpected = "pwd"
+        val preferImmediatelyAvailableCredentialsExpected = true
         val expectedCredentialData = Bundle()
-        val expectedAutoSelect = false
+        val expectedAutoSelect = true
         expectedCredentialData.putString(CreatePasswordRequest.BUNDLE_KEY_ID, idExpected)
         expectedCredentialData.putString(
             CreatePasswordRequest.BUNDLE_KEY_PASSWORD,
             passwordExpected
         )
-        expectedCredentialData.putBoolean(CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
-            expectedAutoSelect)
+        expectedCredentialData.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+            expectedAutoSelect
+        )
+        expectedCredentialData.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+            preferImmediatelyAvailableCredentialsExpected
+        )
+        val expectedCandidateData = Bundle()
+        expectedCandidateData.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+            expectedAutoSelect
+        )
 
-        val request = CreatePasswordRequest(idExpected, passwordExpected)
+        val request = CreatePasswordRequest(
+            idExpected, passwordExpected, /*origin=*/null,
+            preferImmediatelyAvailableCredentialsExpected, expectedAutoSelect
+        )
 
         assertThat(request.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
-        assertThat(equals(request.candidateQueryData, Bundle.EMPTY)).isTrue()
+        val displayInfo = request.displayInfo
+        assertThat(displayInfo.userDisplayName).isNull()
+        assertThat(displayInfo.userId).isEqualTo(idExpected)
+        assertThat(equals(request.candidateQueryData, expectedCandidateData))
+            .isTrue()
         assertThat(request.isSystemProviderRequired).isFalse()
-        assertThat(request.displayInfo.userDisplayName).isNull()
-        assertThat(request.displayInfo.userId).isEqualTo(idExpected)
         val credentialData = getFinalCreateCredentialData(
             request, mContext
         )
         assertThat(credentialData.keySet())
-            .hasSize(expectedCredentialData.size() + /* added request info */ 1)
+            .hasSize(expectedCredentialData.size() + /* added request info */1)
         for (key in expectedCredentialData.keySet()) {
-            assertThat(expectedCredentialData.get(key)).isEqualTo(credentialData.get(key))
+            assertThat(credentialData[key]).isEqualTo(expectedCredentialData[key])
         }
-        val displayInfoBundle =
-            credentialData.getBundle(
-                CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_REQUEST_DISPLAY_INFO)!!
-        assertThat(displayInfoBundle.keySet()).hasSize(2)
-        assertThat(displayInfoBundle.getString(
-            CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_USER_ID)).isEqualTo(idExpected)
-        assertThat((displayInfoBundle.getParcelable(
-            CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_CREDENTIAL_TYPE_ICON) as Icon?)!!.resId
+        val displayInfoBundle = credentialData.getBundle(
+            DisplayInfo.BUNDLE_KEY_REQUEST_DISPLAY_INFO
+        )
+        assertThat(displayInfoBundle!!.keySet()).hasSize(2)
+        assertThat(
+            displayInfoBundle.getString(
+                DisplayInfo.BUNDLE_KEY_USER_ID
+            )
+        ).isEqualTo(idExpected)
+        assertThat(
+            (displayInfoBundle.getParcelable<Parcelable>(
+                DisplayInfo.BUNDLE_KEY_CREDENTIAL_TYPE_ICON
+            ) as Icon?)!!.resId
         ).isEqualTo(R.drawable.ic_password)
     }
 
@@ -102,27 +191,53 @@
     @Test
     fun frameworkConversion_success() {
         val idExpected = "id"
-        val request = CreatePasswordRequest(idExpected, "password")
-        val origin = "origin"
+        val passwordExpected = "pwd"
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val isAutoSelectAllowedExpected = true
+        val originExpected = "origin"
+        val defaultProviderExpected = "com.test/com.test.TestProviderComponent"
+        val request = CreatePasswordRequest(
+            idExpected, passwordExpected, originExpected, defaultProviderExpected,
+            preferImmediatelyAvailableCredentialsExpected, isAutoSelectAllowedExpected
+        )
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val credentialData = getFinalCreateCredentialData(request, mContext)
+        val customRequestDataKey = "customRequestDataKey"
+        val customRequestDataValue = "customRequestDataValue"
+        credentialData.putString(customRequestDataKey, customRequestDataValue)
+        val candidateQueryData = request.candidateQueryData
+        val customCandidateQueryDataKey = "customRequestDataKey"
+        val customCandidateQueryDataValue = true
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue)
 
         val convertedRequest = createFrom(
-            request.type, getFinalCreateCredentialData(
-                request, mContext
-            ),
-            request.candidateQueryData, request.isSystemProviderRequired,
-            origin
+            request.type, credentialData, candidateQueryData, request.isSystemProviderRequired,
+            request.origin
         )
 
         assertThat(convertedRequest).isInstanceOf(
             CreatePasswordRequest::class.java
         )
         val convertedCreatePasswordRequest = convertedRequest as CreatePasswordRequest
-        assertThat(convertedCreatePasswordRequest.password).isEqualTo(request.password)
-        assertThat(convertedCreatePasswordRequest.id).isEqualTo(request.id)
-        assertThat(convertedCreatePasswordRequest.displayInfo.userDisplayName).isNull()
-        assertThat(convertedCreatePasswordRequest.displayInfo.userId).isEqualTo(idExpected)
-        assertThat(convertedCreatePasswordRequest.displayInfo.credentialTypeIcon?.resId)
+        assertThat(convertedCreatePasswordRequest.password).isEqualTo(passwordExpected)
+        assertThat(convertedCreatePasswordRequest.id).isEqualTo(idExpected)
+        assertThat(convertedCreatePasswordRequest.preferImmediatelyAvailableCredentials)
+            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        assertThat(convertedCreatePasswordRequest.origin).isEqualTo(originExpected)
+        assertThat(convertedCreatePasswordRequest.isAutoSelectAllowed)
+            .isEqualTo(isAutoSelectAllowedExpected)
+        val displayInfo = convertedCreatePasswordRequest.displayInfo
+        assertThat(displayInfo.userDisplayName).isNull()
+        assertThat(displayInfo.userId).isEqualTo(idExpected)
+        assertThat(displayInfo.credentialTypeIcon!!.resId)
             .isEqualTo(R.drawable.ic_password)
-        assertThat(convertedCreatePasswordRequest.origin).isEqualTo(origin)
+        assertThat(displayInfo.preferDefaultProvider).isEqualTo(defaultProviderExpected)
+        assertThat(convertedRequest.credentialData.getString(customRequestDataKey))
+            .isEqualTo(customRequestDataValue)
+        assertThat(convertedRequest.candidateQueryData.getBoolean(customCandidateQueryDataKey))
+            .isEqualTo(customCandidateQueryDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java
index 40bf6b6..a7de13b 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java
@@ -40,10 +40,18 @@
     @Test
     public void frameworkConversion_success() {
         CreatePasswordResponse response = new CreatePasswordResponse();
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle data = response.getData();
+        String customDataKey = "customRequestDataKey";
+        CharSequence customDataValue = "customRequestDataValue";
+        data.putCharSequence(customDataKey, customDataValue);
 
         CreateCredentialResponse convertedResponse =
-                CreateCredentialResponse.createFrom(response.getType(), response.getData());
+                CreateCredentialResponse.createFrom(response.getType(), data);
 
         assertThat(convertedResponse).isInstanceOf(CreatePasswordResponse.class);
+        assertThat(convertedResponse.getData().getCharSequence(customDataKey))
+                .isEqualTo(customDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt
index aef4a3c..4af918c 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt
@@ -39,9 +39,17 @@
     @Test
     fun frameworkConversion_success() {
         val response = CreatePasswordResponse()
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val data = response.data
+        val customDataKey = "customRequestDataKey"
+        val customDataValue: CharSequence = "customRequestDataValue"
+        data.putCharSequence(customDataKey, customDataValue)
 
-        val convertedResponse = createFrom(response.type, response.data)
+        val convertedResponse = createFrom(response.type, data)
 
         assertThat(convertedResponse).isInstanceOf(CreatePasswordResponse::class.java)
+        assertThat(convertedResponse.data.getCharSequence(customDataKey))
+            .isEqualTo(customDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
index d3af566..cb095bb 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
@@ -16,8 +16,8 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.CreateCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS;
 import static androidx.credentials.CreatePublicKeyCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED;
-import static androidx.credentials.CreatePublicKeyCredentialRequest.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS;
 import static androidx.credentials.CreatePublicKeyCredentialRequest.BUNDLE_KEY_REQUEST_JSON;
 import static androidx.credentials.internal.FrameworkImplHelper.getFinalCreateCredentialData;
 
@@ -60,10 +60,20 @@
     }
 
     @Test
+    public void constructor_invalidJson_throwsIllegalArgumentException() {
+        assertThrows("Expected empty Json to throw error",
+                IllegalArgumentException.class,
+                () -> new CreatePublicKeyCredentialRequest("invalid")
+        );
+    }
+
+    @Test
     public void constructor_jsonMissingUserName_throwsIllegalArgumentException() {
         assertThrows(
                 IllegalArgumentException.class,
-                () -> new CreatePublicKeyCredentialRequest("json")
+                () -> new CreatePublicKeyCredentialRequest(
+                        "{\"key\":{\"value\":{\"lol\":\"Value\"}}}"
+                )
         );
     }
 
@@ -77,8 +87,38 @@
 
     @Test
     public void constructor_success() {
-        new CreatePublicKeyCredentialRequest(
-                "{\"user\":{\"name\":{\"lol\":\"Value\"}}}");
+        new CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON);
+    }
+
+    @Test
+    public void constructor_defaultProviderVariant() {
+        byte[] clientDataHashExpected = "hash".getBytes();
+        String originExpected = "origin";
+        Boolean preferImmediatelyAvailableCredentialsExpected = true;
+        String defaultProviderExpected = "com.test/com.test.TestProviderComponent";
+        boolean isAutoSelectAllowedExpected = true;
+
+        CreatePublicKeyCredentialRequest request = new CreatePublicKeyCredentialRequest(
+                TEST_REQUEST_JSON, clientDataHashExpected,
+                preferImmediatelyAvailableCredentialsExpected, originExpected,
+                defaultProviderExpected, isAutoSelectAllowedExpected);
+
+        assertThat(request.getDisplayInfo().getPreferDefaultProvider())
+                .isEqualTo(defaultProviderExpected);
+        assertThat(request.getClientDataHash()).isEqualTo(clientDataHashExpected);
+        assertThat(request.getOrigin()).isEqualTo(originExpected);
+        assertThat(request.getRequestJson()).isEqualTo(TEST_REQUEST_JSON);
+        assertThat(request.preferImmediatelyAvailableCredentials())
+                .isEqualTo(preferImmediatelyAvailableCredentialsExpected);
+        assertThat(request.isAutoSelectAllowed()).isEqualTo(isAutoSelectAllowedExpected);
+    }
+
+    @Test
+    public void constructor_setsAutoSelectToFalseByDefault() {
+        CreatePublicKeyCredentialRequest createPublicKeyCredentialRequest =
+                new CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON);
+
+        assertThat(createPublicKeyCredentialRequest.isAutoSelectAllowed()).isFalse();
     }
 
     @Test
@@ -93,7 +133,7 @@
     @Test
     public void constructor_setPreferImmediatelyAvailableCredentialsToTrue() {
         boolean preferImmediatelyAvailableCredentialsExpected = true;
-        String clientDataHash = "hash";
+        byte[] clientDataHash = "hash".getBytes();
         CreatePublicKeyCredentialRequest createPublicKeyCredentialRequest =
                 new CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON,
                         clientDataHash,
@@ -119,38 +159,42 @@
     @Test
     public void getter_frameworkProperties_success() {
         String requestJsonExpected = TEST_REQUEST_JSON;
-        String clientDataHash = "hash";
-        boolean preferImmediatelyAvailableCredentialsExpected = false;
-        Bundle expectedData = new Bundle();
-        expectedData.putString(
+        byte[] clientDataHash = "hash".getBytes();
+        boolean preferImmediatelyAvailableCredentialsExpected = true;
+        boolean autoSelectExpected = true;
+        Bundle expectedCandidateQueryData = new Bundle();
+        expectedCandidateQueryData.putString(
                 PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
                 CreatePublicKeyCredentialRequest
                         .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST);
-        expectedData.putString(
+        expectedCandidateQueryData.putString(
                 BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
-        expectedData.putString(CreatePublicKeyCredentialRequest.BUNDLE_KEY_CLIENT_DATA_HASH,
+        expectedCandidateQueryData.putByteArray(
+                CreatePublicKeyCredentialRequest.BUNDLE_KEY_CLIENT_DATA_HASH,
                 clientDataHash);
-        expectedData.putBoolean(
+        expectedCandidateQueryData.putBoolean(
+                BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+                autoSelectExpected);
+        Bundle expectedCredentialData = expectedCandidateQueryData.deepCopy();
+        expectedCredentialData.putBoolean(
                 BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
                 preferImmediatelyAvailableCredentialsExpected);
-        expectedData.putBoolean(
-                BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
-                preferImmediatelyAvailableCredentialsExpected);
-        Bundle expectedQuery = TestUtilsKt.deepCopyBundle(expectedData);
-        expectedQuery.remove(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED);
 
         CreatePublicKeyCredentialRequest request = new CreatePublicKeyCredentialRequest(
-                requestJsonExpected, clientDataHash, preferImmediatelyAvailableCredentialsExpected);
+                requestJsonExpected, clientDataHash,
+                preferImmediatelyAvailableCredentialsExpected,
+                /*origin=*/ null, autoSelectExpected);
 
         assertThat(request.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
-        assertThat(TestUtilsKt.equals(request.getCandidateQueryData(), expectedQuery)).isTrue();
+        assertThat(TestUtilsKt.equals(request.getCandidateQueryData(), expectedCandidateQueryData))
+                .isTrue();
         assertThat(request.isSystemProviderRequired()).isFalse();
         Bundle credentialData = getFinalCreateCredentialData(
                 request, mContext);
         assertThat(credentialData.keySet())
-                .hasSize(expectedData.size() + /* added request info */ 1);
-        for (String key : expectedData.keySet()) {
-            assertThat(credentialData.get(key)).isEqualTo(credentialData.get(key));
+                .hasSize(expectedCredentialData.size() + /* added request info */ 1);
+        for (String key : expectedCredentialData.keySet()) {
+            assertThat(credentialData.get(key)).isEqualTo(expectedCredentialData.get(key));
         }
         Bundle displayInfoBundle =
                 credentialData.getBundle(
@@ -169,28 +213,49 @@
     @SdkSuppress(minSdkVersion = 28)
     @Test
     public void frameworkConversion_success() {
-        String clientDataHash = "hash";
-        CreatePublicKeyCredentialRequest request =
-                new CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON, clientDataHash, true);
+        byte[] clientDataHashExpected = "hash".getBytes();
+        String originExpected = "origin";
+        Boolean preferImmediatelyAvailableCredentialsExpected = true;
+        boolean isAutoSelectAllowedExpected = true;
+        CreatePublicKeyCredentialRequest request = new CreatePublicKeyCredentialRequest(
+                TEST_REQUEST_JSON, clientDataHashExpected,
+                preferImmediatelyAvailableCredentialsExpected, originExpected,
+                isAutoSelectAllowedExpected);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle credentialData = getFinalCreateCredentialData(
+                request, mContext);
+        String customRequestDataKey = "customRequestDataKey";
+        String customRequestDataValue = "customRequestDataValue";
+        credentialData.putString(customRequestDataKey, customRequestDataValue);
+        Bundle candidateQueryData = request.getCandidateQueryData();
+        String customCandidateQueryDataKey = "customRequestDataKey";
+        Boolean customCandidateQueryDataValue = true;
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue);
 
         CreateCredentialRequest convertedRequest = CreateCredentialRequest.createFrom(
-                request.getType(), getFinalCreateCredentialData(
-                        request, mContext),
-                request.getCandidateQueryData(), request.isSystemProviderRequired(),
-                request.getOrigin()
-        );
+                request.getType(), credentialData, candidateQueryData,
+                request.isSystemProviderRequired(), request.getOrigin());
 
         assertThat(convertedRequest).isInstanceOf(CreatePublicKeyCredentialRequest.class);
         CreatePublicKeyCredentialRequest convertedSubclassRequest =
                 (CreatePublicKeyCredentialRequest) convertedRequest;
         assertThat(convertedSubclassRequest.getRequestJson()).isEqualTo(request.getRequestJson());
+        assertThat(convertedSubclassRequest.getOrigin()).isEqualTo(originExpected);
+        assertThat(convertedSubclassRequest.getClientDataHash()).isEqualTo(clientDataHashExpected);
         assertThat(convertedSubclassRequest.preferImmediatelyAvailableCredentials())
-                .isEqualTo(request.preferImmediatelyAvailableCredentials());
+                .isEqualTo(preferImmediatelyAvailableCredentialsExpected);
+        assertThat(convertedSubclassRequest.isAutoSelectAllowed())
+                .isEqualTo(isAutoSelectAllowedExpected);
         CreateCredentialRequest.DisplayInfo displayInfo =
                 convertedRequest.getDisplayInfo();
         assertThat(displayInfo.getUserDisplayName()).isEqualTo(TEST_USER_DISPLAYNAME);
         assertThat(displayInfo.getUserId()).isEqualTo(TEST_USERNAME);
         assertThat(displayInfo.getCredentialTypeIcon().getResId())
                 .isEqualTo(R.drawable.ic_passkey);
+        assertThat(convertedRequest.getCredentialData().getString(customRequestDataKey))
+                .isEqualTo(customRequestDataValue);
+        assertThat(convertedRequest.getCandidateQueryData().getBoolean(customCandidateQueryDataKey))
+                .isEqualTo(customCandidateQueryDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
index 538da6a..e785fc3 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
@@ -19,8 +19,8 @@
 import android.graphics.drawable.Icon
 import android.os.Bundle
 import android.os.Parcelable
+import androidx.credentials.CreateCredentialRequest.Companion.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS
 import androidx.credentials.CreateCredentialRequest.Companion.createFrom
-import androidx.credentials.CreatePublicKeyCredentialRequest.Companion.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS
 import androidx.credentials.CreatePublicKeyCredentialRequest.Companion.BUNDLE_KEY_REQUEST_JSON
 import androidx.credentials.internal.FrameworkImplHelper.Companion.getFinalCreateCredentialData
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -54,10 +54,25 @@
     }
 
     @Test
+    fun constructor_invalidJson_throwsIllegalArgumentException() {
+        assertThrows(
+            "Expected empty Json to throw error",
+            IllegalArgumentException::class.java
+        ) { CreatePublicKeyCredentialRequest("invalid") }
+    }
+
+    @Test
     fun constructor_jsonMissingUserName_throwsIllegalArgumentException() {
         assertThrows(
             IllegalArgumentException::class.java
-        ) { CreatePublicKeyCredentialRequest("json") }
+        ) { CreatePublicKeyCredentialRequest("{\"hey\":{\"hi\":{\"hello\":\"hii\"}}}") }
+    }
+
+    @Test
+    fun constructor_setsAutoSelectToFalseByDefault() {
+        val createPublicKeyCredentialRequest = CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON)
+
+        assertThat(createPublicKeyCredentialRequest.isAutoSelectAllowed).isFalse()
     }
 
     @Test
@@ -74,13 +89,15 @@
     fun constructor_setPreferImmediatelyAvailableCredentialsToTrue() {
         val preferImmediatelyAvailableCredentialsExpected = true
         val origin = "origin"
-        val clientDataHash = "hash"
+        val clientDataHash = "hash".toByteArray()
+
         val createPublicKeyCredentialRequest = CreatePublicKeyCredentialRequest(
             TEST_REQUEST_JSON,
             clientDataHash,
             preferImmediatelyAvailableCredentialsExpected,
             origin
         )
+
         val preferImmediatelyAvailableCredentialsActual =
             createPublicKeyCredentialRequest.preferImmediatelyAvailableCredentials
         assertThat(preferImmediatelyAvailableCredentialsActual)
@@ -89,6 +106,30 @@
     }
 
     @Test
+    fun constructor_defaultProviderVariant() {
+        val clientDataHashExpected = "hash".toByteArray()
+        val originExpected = "origin"
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val defaultProviderExpected = "com.test/com.test.TestProviderComponent"
+        val isAutoSelectAllowedExpected = true
+
+        val request = CreatePublicKeyCredentialRequest(
+            TEST_REQUEST_JSON, clientDataHashExpected,
+            preferImmediatelyAvailableCredentialsExpected, originExpected,
+            defaultProviderExpected, isAutoSelectAllowedExpected,
+        )
+
+        assertThat(request.displayInfo.preferDefaultProvider)
+            .isEqualTo(defaultProviderExpected)
+        assertThat(request.clientDataHash).isEqualTo(clientDataHashExpected)
+        assertThat(request.origin).isEqualTo(originExpected)
+        assertThat(request.requestJson).isEqualTo(TEST_REQUEST_JSON)
+        assertThat(request.preferImmediatelyAvailableCredentials)
+            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        assertThat(request.isAutoSelectAllowed).isEqualTo(isAutoSelectAllowedExpected)
+    }
+
+    @Test
     fun getter_requestJson_success() {
         val testJsonExpected = "{\"user\":{\"name\":{\"lol\":\"Value\"}}}"
         val createPublicKeyCredentialReq = CreatePublicKeyCredentialRequest(testJsonExpected)
@@ -101,58 +142,53 @@
     @Test
     fun getter_frameworkProperties_success() {
         val requestJsonExpected = TEST_REQUEST_JSON
-        val preferImmediatelyAvailableCredentialsExpected = false
-        val expectedAutoSelect = true
-        val origin = "origin"
-        val clientDataHash = "hash"
-        val expectedData = Bundle()
-        expectedData.putString(
+        val clientDataHash = "hash".toByteArray()
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val autoSelectExpected = true
+        val expectedCandidateQueryData = Bundle()
+        expectedCandidateQueryData.putString(
             PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
             CreatePublicKeyCredentialRequest
                 .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST
         )
-        expectedData.putString(
+        expectedCandidateQueryData.putString(
             BUNDLE_KEY_REQUEST_JSON, requestJsonExpected
         )
-        expectedData.putString(CreatePublicKeyCredentialRequest.BUNDLE_KEY_CLIENT_DATA_HASH,
-            clientDataHash)
-        expectedData.putBoolean(
+        expectedCandidateQueryData.putByteArray(
+            CreatePublicKeyCredentialRequest.BUNDLE_KEY_CLIENT_DATA_HASH,
+            clientDataHash
+        )
+        expectedCandidateQueryData.putBoolean(
+            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
+            autoSelectExpected
+        )
+        val expectedCredentialData = expectedCandidateQueryData.deepCopy()
+        expectedCredentialData.putBoolean(
             BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
             preferImmediatelyAvailableCredentialsExpected
         )
-        expectedData.putBoolean(
-            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
-            expectedAutoSelect
-        )
-
-        val expectedCandidateQueryBundle = expectedData.deepCopy()
-        expectedCandidateQueryBundle.remove(
-            CreateCredentialRequest.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED
-        )
 
         val request = CreatePublicKeyCredentialRequest(
-            requestJsonExpected,
-            clientDataHash,
-            preferImmediatelyAvailableCredentialsExpected,
-            origin
+            requestJsonExpected, clientDataHash, preferImmediatelyAvailableCredentialsExpected,
+            origin = null, autoSelectExpected
         )
 
         assertThat(request.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
-        assertThat(equals(request.candidateQueryData, expectedCandidateQueryBundle)).isTrue()
+        assertThat(equals(request.candidateQueryData, expectedCandidateQueryData))
+            .isTrue()
         assertThat(request.isSystemProviderRequired).isFalse()
-        assertThat(request.origin).isEqualTo(origin)
         val credentialData = getFinalCreateCredentialData(
             request, mContext
         )
         assertThat(credentialData.keySet())
-            .hasSize(expectedData.size() + /* added request info */1)
-        for (key in expectedData.keySet()) {
-            assertThat(credentialData[key]).isEqualTo(credentialData[key])
+            .hasSize(expectedCredentialData.size() + /* added request info */1)
+        for (key in expectedCredentialData.keySet()) {
+            assertThat(credentialData[key]).isEqualTo(expectedCredentialData[key])
         }
         val displayInfoBundle = credentialData.getBundle(
             CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_REQUEST_DISPLAY_INFO
-        )!!
-        assertThat(displayInfoBundle.keySet()).hasSize(3)
+        )
+        assertThat(displayInfoBundle!!.keySet()).hasSize(3)
         assertThat(
             displayInfoBundle.getString(
                 CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_USER_ID
@@ -173,31 +209,52 @@
     @SdkSuppress(minSdkVersion = 28)
     @Test
     fun frameworkConversion_success() {
-        val origin = "origin"
-        val clientDataHash = "hash"
-        val request = CreatePublicKeyCredentialRequest(TEST_REQUEST_JSON, clientDataHash,
-            true, origin)
+        val clientDataHashExpected = "hash".toByteArray()
+        val originExpected = "origin"
+        val preferImmediatelyAvailableCredentialsExpected = true
+        val isAutoSelectAllowedExpected = true
+        val request = CreatePublicKeyCredentialRequest(
+            TEST_REQUEST_JSON, clientDataHashExpected,
+            preferImmediatelyAvailableCredentialsExpected, originExpected,
+            isAutoSelectAllowedExpected
+        )
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val credentialData = getFinalCreateCredentialData(request, mContext)
+        val customRequestDataKey = "customRequestDataKey"
+        val customRequestDataValue = "customRequestDataValue"
+        credentialData.putString(customRequestDataKey, customRequestDataValue)
+        val candidateQueryData = request.candidateQueryData
+        val customCandidateQueryDataKey = "customRequestDataKey"
+        val customCandidateQueryDataValue = true
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue)
 
         val convertedRequest = createFrom(
-            request.type, getFinalCreateCredentialData(
-                request, mContext
-            ),
-            request.candidateQueryData, request.isSystemProviderRequired,
+            request.type, credentialData, candidateQueryData, request.isSystemProviderRequired,
             request.origin
         )
 
         assertThat(convertedRequest).isInstanceOf(
             CreatePublicKeyCredentialRequest::class.java
         )
-        assertThat(convertedRequest?.origin).isEqualTo(origin)
         val convertedSubclassRequest = convertedRequest as CreatePublicKeyCredentialRequest
         assertThat(convertedSubclassRequest.requestJson).isEqualTo(request.requestJson)
+        assertThat(convertedSubclassRequest.origin).isEqualTo(originExpected)
+        assertThat(convertedSubclassRequest.clientDataHash).isEqualTo(clientDataHashExpected)
         assertThat(convertedSubclassRequest.preferImmediatelyAvailableCredentials)
-            .isEqualTo(request.preferImmediatelyAvailableCredentials)
-        val displayInfo = convertedRequest.displayInfo
+            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        assertThat(convertedSubclassRequest.isAutoSelectAllowed)
+            .isEqualTo(isAutoSelectAllowedExpected)
+        val displayInfo = convertedSubclassRequest.displayInfo
         assertThat(displayInfo.userDisplayName).isEqualTo(TEST_USER_DISPLAYNAME)
         assertThat(displayInfo.userId).isEqualTo(TEST_USERNAME)
-        assertThat(displayInfo.credentialTypeIcon?.resId)
+        assertThat(displayInfo.credentialTypeIcon!!.resId)
             .isEqualTo(R.drawable.ic_passkey)
+        assertThat(convertedRequest.credentialData.getString(customRequestDataKey))
+            .isEqualTo(customRequestDataValue)
+        assertThat(convertedRequest.candidateQueryData.getBoolean(customCandidateQueryDataKey))
+            .isEqualTo(customCandidateQueryDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
index 0ea0492..f1b2689 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
@@ -31,6 +31,7 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CreatePublicKeyCredentialResponseJavaTest {
+    private static final String TEST_RESPONSE_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
 
     @Test
     public void constructor_emptyJson_throwsIllegalArgumentException() {
@@ -50,7 +51,7 @@
 
     @Test
     public void constructor_success()  {
-        new CreatePublicKeyCredentialResponse("{\"hi\":1}");
+        new CreatePublicKeyCredentialResponse(TEST_RESPONSE_JSON);
     }
 
     @Test
@@ -80,15 +81,23 @@
     @Test
     public void frameworkConversion_success() {
         CreatePublicKeyCredentialResponse response =
-                new CreatePublicKeyCredentialResponse("responseJson");
+                new CreatePublicKeyCredentialResponse(TEST_RESPONSE_JSON);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle data = response.getData();
+        String customDataKey = "customRequestDataKey";
+        CharSequence customDataValue = "customRequestDataValue";
+        data.putCharSequence(customDataKey, customDataValue);
 
         CreateCredentialResponse convertedResponse =
-                CreateCredentialResponse.createFrom(response.getType(), response.getData());
+                CreateCredentialResponse.createFrom(response.getType(), data);
 
         assertThat(convertedResponse).isInstanceOf(CreatePublicKeyCredentialResponse.class);
         CreatePublicKeyCredentialResponse convertedSubclassResponse =
                 (CreatePublicKeyCredentialResponse) convertedResponse;
         assertThat(convertedSubclassResponse.getRegistrationResponseJson())
                 .isEqualTo(response.getRegistrationResponseJson());
+        assertThat(convertedResponse.getData().getCharSequence(customDataKey))
+                .isEqualTo(customDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
index 3773b39..9be5324 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
@@ -29,6 +29,10 @@
 @SmallTest
 class CreatePublicKeyCredentialResponseTest {
 
+    companion object Constant {
+        private const val TEST_RESPONSE_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+    }
+
     @Test
     fun constructor_emptyJson_throwsIllegalArgumentException() {
         Assert.assertThrows(
@@ -38,8 +42,16 @@
     }
 
     @Test
+    fun constructor_invalidJson_throwsIllegalArgumentException() {
+        Assert.assertThrows(
+            "Expected empty Json to throw error",
+            IllegalArgumentException::class.java
+        ) { CreatePublicKeyCredentialResponse("invalid") }
+    }
+
+    @Test
     fun constructor_success() {
-        CreatePublicKeyCredentialResponse("{\"hi\":1}")
+        CreatePublicKeyCredentialResponse(TEST_RESPONSE_JSON)
     }
 
     @Test
@@ -67,9 +79,17 @@
 
     @Test
     fun frameworkConversion_success() {
-        val response = CreatePublicKeyCredentialResponse("responseJson")
+        val response = CreatePublicKeyCredentialResponse(TEST_RESPONSE_JSON)
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val data = response.data
+        val customDataKey = "customRequestDataKey"
+        val customDataValue: CharSequence = "customRequestDataValue"
+        data.putCharSequence(customDataKey, customDataValue)
 
-        val convertedResponse = createFrom(response.type, response.data)
+        val convertedResponse = createFrom(response.type, data)
 
         assertThat(convertedResponse).isInstanceOf(
             CreatePublicKeyCredentialResponse::class.java
@@ -77,5 +97,7 @@
         val convertedSubclassResponse = convertedResponse as CreatePublicKeyCredentialResponse
         assertThat(convertedSubclassResponse.registrationResponseJson)
             .isEqualTo(response.registrationResponseJson)
+        assertThat(convertedResponse.data.getCharSequence(customDataKey))
+            .isEqualTo(customDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerJavaTest.java
index 85246a1..d69305d 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerJavaTest.java
@@ -25,14 +25,18 @@
 import android.os.Looper;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 import androidx.credentials.exceptions.ClearCredentialException;
 import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException;
 import androidx.credentials.exceptions.CreateCredentialException;
+import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException;
 import androidx.credentials.exceptions.CreateCredentialProviderConfigurationException;
 import androidx.credentials.exceptions.GetCredentialException;
 import androidx.credentials.exceptions.GetCredentialProviderConfigurationException;
+import androidx.credentials.exceptions.NoCredentialException;
 import androidx.test.core.app.ActivityScenario;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -46,6 +50,8 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@RequiresApi(34)
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
 public class CredentialManagerJavaTest {
 
     private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
@@ -68,8 +74,8 @@
                 ActivityScenario.launch(TestActivity.class);
         activityScenario.onActivity(activity -> {
             mCredentialManager.createCredentialAsync(
-                    new CreatePasswordRequest("test-user-id", "test-password"),
                     activity,
+                    new CreatePasswordRequest("test-user-id", "test-password"),
                     null,
                     Runnable::run,
                     new CredentialManagerCallback<CreateCredentialResponse,
@@ -81,20 +87,26 @@
                         }
 
                         @Override
-                        public void onResult(@NonNull CreateCredentialResponse result) {}
+                        public void onResult(@NonNull CreateCredentialResponse result) {
+                        }
                     });
         });
-
         latch.await(100L, TimeUnit.MILLISECONDS);
-        assertThat(loadedResult.get().getClass()).isEqualTo(
-                CreateCredentialProviderConfigurationException.class);
-        // TODO("Add manifest tests and possibly further separate these tests by API Level
-        //  - maybe a rule perhaps?")
+        if (loadedResult.get() == null) {
+            return; // A strange flow occurred where an exception wasn't propagated up
+        }
+        if (!isPostFrameworkApiLevel()) {
+            assertThat(loadedResult.get().getClass()).isEqualTo(
+                    CreateCredentialProviderConfigurationException.class);
+        } else {
+            assertThat(loadedResult.get().getClass()).isEqualTo(
+                    CreateCredentialNoCreateOptionException.class);
+        }
     }
 
-
     @Test
-    public void testGetCredentialAsyc_successCallbackThrows() throws InterruptedException {
+    public void testGetCredentialAsyc_requestBasedApi_successCallbackThrows()
+            throws InterruptedException {
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
@@ -102,29 +114,92 @@
         AtomicReference<GetCredentialException> loadedResult = new AtomicReference<>();
 
         mCredentialManager.getCredentialAsync(
+                new Activity(),
                 new GetCredentialRequest.Builder()
                         .addCredentialOption(new GetPasswordOption())
                         .build(),
-                new Activity(),
                 null,
                 Runnable::run,
                 new CredentialManagerCallback<GetCredentialResponse,
-                    GetCredentialException>() {
-                @Override
-                public void onError(@NonNull GetCredentialException e) {
-                    loadedResult.set(e);
-                    latch.countDown();
-                }
+                        GetCredentialException>() {
+                    @Override
+                    public void onError(@NonNull GetCredentialException e) {
+                        loadedResult.set(e);
+                        latch.countDown();
+                    }
 
-                @Override
-                public void onResult(@NonNull GetCredentialResponse result) {}
-            });
+                    @Override
+                    public void onResult(@NonNull GetCredentialResponse result) {
+                    }
+                });
 
         latch.await(100L, TimeUnit.MILLISECONDS);
-        assertThat(loadedResult.get().getClass()).isEqualTo(
-                GetCredentialProviderConfigurationException.class);
-        // TODO("Add manifest tests and possibly further separate these tests - maybe a rule
-        //  perhaps?")
+        if (loadedResult.get() == null) {
+            return; // A strange flow occurred where an exception wasn't propagated up
+        }
+        if (!isPostFrameworkApiLevel()) {
+            assertThat(loadedResult.get().getClass()).isEqualTo(
+                    GetCredentialProviderConfigurationException.class);
+        } else {
+            assertThat(loadedResult.get().getClass()).isEqualTo(
+                    NoCredentialException.class);
+        }
+    }
+
+    @Test
+    public void testPrepareGetCredentialAsyc_throwsUnimplementedError() throws Exception {
+        CountDownLatch latch1 = new CountDownLatch(1);
+        AtomicReference<PrepareGetCredentialResponse> prepareResult = new AtomicReference<>();
+
+        mCredentialManager.prepareGetCredentialAsync(
+                new GetCredentialRequest.Builder()
+                        .addCredentialOption(new GetPasswordOption())
+                        .build(),
+                null,
+                Runnable::run,
+                new CredentialManagerCallback<PrepareGetCredentialResponse,
+                        GetCredentialException>() {
+                    @Override
+                    public void onError(@NonNull GetCredentialException e) {}
+
+                    @Override
+                    public void onResult(@NonNull PrepareGetCredentialResponse result) {
+                        prepareResult.set(result);
+                        latch1.countDown();
+                    }
+                });
+        latch1.await(100L, TimeUnit.MILLISECONDS);
+        assertThat(prepareResult.get()).isNotNull();
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        CountDownLatch latch2 = new CountDownLatch(1);
+        AtomicReference<GetCredentialException> getResult = new AtomicReference<>();
+
+        ActivityScenario<TestActivity> activityScenario =
+                ActivityScenario.launch(TestActivity.class);
+        activityScenario.onActivity(activity -> {
+            mCredentialManager.getCredentialAsync(
+                    activity,
+                    prepareResult.get().getPendingGetCredentialHandle(),
+                    null,
+                    Runnable::run,
+                    new CredentialManagerCallback<GetCredentialResponse,
+                            GetCredentialException>() {
+                        @Override
+                        public void onError(@NonNull GetCredentialException e) {
+                            getResult.set(e);
+                            latch2.countDown();
+                        }
+
+                        @Override
+                        public void onResult(@NonNull GetCredentialResponse result) {}
+                    });
+        });
+
+        latch2.await(100L, TimeUnit.MILLISECONDS);
+        assertThat(getResult.get().getClass()).isEqualTo(NoCredentialException.class);
     }
 
     @Test
@@ -148,12 +223,12 @@
                     }
 
                     @Override
-                    public void onResult(@NonNull Void result) {}
+                    public void onResult(@NonNull Void result) {
+                    }
                 });
 
         latch.await(100L, TimeUnit.MILLISECONDS);
         assertThat(loadedResult.get().getClass()).isEqualTo(
                 ClearCredentialProviderConfigurationException.class);
-        // TODO(Add manifest tests and split this once postU is implemented for clearCreds")
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt
new file mode 100644
index 0000000..12e016d
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerPreUTest.kt
@@ -0,0 +1,185 @@
+/*
+* 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.credentials
+
+import android.app.Activity
+import android.os.Looper
+import androidx.annotation.RequiresApi
+import androidx.credentials.exceptions.ClearCredentialException
+import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException
+import androidx.credentials.exceptions.CreateCredentialProviderConfigurationException
+import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
+import androidx.credentials.exceptions.NoCredentialException
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.assertThrows
+import androidx.testutils.withActivity
+import androidx.testutils.withUse
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicReference
+import kotlinx.coroutines.runBlocking
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(16)
+@SdkSuppress(minSdkVersion = 16, maxSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+class CredentialManagerPreUTest {
+    private val context = InstrumentationRegistry.getInstrumentation().context
+
+    private lateinit var credentialManager: CredentialManager
+
+    @Before
+    fun setup() {
+        credentialManager = CredentialManager.create(context)
+    }
+
+    @Test
+    fun createCredential_throws() = runBlocking<Unit> {
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+        if (!isPostFrameworkApiLevel()) {
+            assertThrows<CreateCredentialProviderConfigurationException> {
+                credentialManager.createCredential(
+                    Activity(),
+                    CreatePasswordRequest("test-user-id", "test-password")
+                )
+            }
+        }
+    }
+
+    @Test
+    fun getCredential_requestBasedApi_throws() = runBlocking<Unit> {
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+        val request = GetCredentialRequest.Builder()
+            .addCredentialOption(GetPasswordOption())
+            .build()
+
+        withUse(ActivityScenario.launch(TestActivity::class.java)) {
+            withActivity {
+                runBlocking {
+                    if (!isPostFrameworkApiLevel()) {
+                        assertThrows<GetCredentialProviderConfigurationException> {
+                            credentialManager.getCredential(this@withActivity, request)
+                        }
+                    } else {
+                        assertThrows<NoCredentialException> {
+                            credentialManager.getCredential(this@withActivity, request)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
+    fun testClearCredentialSession_throws() = runBlocking<Unit> {
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+
+        if (!isPostFrameworkApiLevel()) {
+            assertThrows<ClearCredentialProviderConfigurationException> {
+                credentialManager.clearCredentialState(ClearCredentialStateRequest())
+            }
+        }
+    }
+
+    @Test
+    fun testCreateCredentialAsyc_successCallbackThrows() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+        val latch = CountDownLatch(1)
+        val loadedResult: AtomicReference<CreateCredentialException> = AtomicReference()
+        val activityScenario = ActivityScenario.launch(
+            TestActivity::class.java
+        )
+
+        activityScenario.onActivity { activity ->
+            credentialManager.createCredentialAsync(
+                activity,
+                CreatePasswordRequest("test-user-id", "test-password"),
+                null, Executor { obj: Runnable -> obj.run() },
+                object : CredentialManagerCallback<CreateCredentialResponse,
+                    CreateCredentialException> {
+                    override fun onResult(result: CreateCredentialResponse) {}
+                    override fun onError(e: CreateCredentialException) {
+                        loadedResult.set(e)
+                        latch.countDown()
+                    }
+                })
+        }
+
+        latch.await(100L, TimeUnit.MILLISECONDS)
+        if (loadedResult.get() == null) {
+            return // A strange flow occurred where an exception wasn't propagated up
+        }
+        if (!isPostFrameworkApiLevel()) {
+            assertThat(loadedResult.get().javaClass).isEqualTo(
+                CreateCredentialProviderConfigurationException::class.java
+            )
+        } else {
+            assertThat(loadedResult.get().javaClass).isEqualTo(
+                CreateCredentialNoCreateOptionException::class.java
+            )
+        }
+    }
+
+    @Test
+    fun testClearCredentialSessionAsync_throws() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+        if (isPostFrameworkApiLevel()) {
+            return // TODO(Support!)
+        }
+        val latch = CountDownLatch(1)
+        val loadedResult: AtomicReference<ClearCredentialException> = AtomicReference()
+
+        credentialManager.clearCredentialStateAsync(
+            ClearCredentialStateRequest(),
+            null, Executor { obj: Runnable -> obj.run() },
+            object : CredentialManagerCallback<Void?, ClearCredentialException> {
+                override fun onError(e: ClearCredentialException) {
+                    loadedResult.set(e)
+                    latch.countDown()
+                }
+
+                override fun onResult(result: Void?) {}
+            })
+
+        latch.await(100L, TimeUnit.MILLISECONDS)
+        assertThat(loadedResult.get().type).isEqualTo(
+            ClearCredentialProviderConfigurationException
+                .TYPE_CLEAR_CREDENTIAL_PROVIDER_CONFIGURATION_EXCEPTION
+        )
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerTest.kt
index 162d6df..6285dcc 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CredentialManagerTest.kt
@@ -18,17 +18,22 @@
 
 import android.app.Activity
 import android.os.Looper
+import androidx.annotation.RequiresApi
 import androidx.credentials.exceptions.ClearCredentialException
 import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException
 import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException
 import androidx.credentials.exceptions.CreateCredentialProviderConfigurationException
-import androidx.credentials.exceptions.GetCredentialException
 import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
+import androidx.credentials.exceptions.NoCredentialException
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import androidx.testutils.assertThrows
+import androidx.testutils.withActivity
+import androidx.testutils.withUse
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.Executor
@@ -41,6 +46,8 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
+@RequiresApi(16)
+@SdkSuppress(minSdkVersion = 16)
 class CredentialManagerTest {
     private val context = InstrumentationRegistry.getInstrumentation().context
 
@@ -59,8 +66,8 @@
         if (!isPostFrameworkApiLevel()) {
             assertThrows<CreateCredentialProviderConfigurationException> {
                 credentialManager.createCredential(
-                    CreatePasswordRequest("test-user-id", "test-password"),
-                    Activity()
+                    Activity(),
+                    CreatePasswordRequest("test-user-id", "test-password")
                 )
             }
         }
@@ -69,7 +76,7 @@
     }
 
     @Test
-    fun getCredential_throws() = runBlocking<Unit> {
+    fun getCredential_requestBasedApi_throws() = runBlocking<Unit> {
         if (Looper.myLooper() == null) {
             Looper.prepare()
         }
@@ -77,9 +84,19 @@
             .addCredentialOption(GetPasswordOption())
             .build()
 
-        if (!isPostFrameworkApiLevel()) {
-            assertThrows<GetCredentialProviderConfigurationException> {
-                credentialManager.getCredential(request, Activity())
+        withUse(ActivityScenario.launch(TestActivity::class.java)) {
+            withActivity {
+                runBlocking {
+                    if (!isPostFrameworkApiLevel()) {
+                        assertThrows<GetCredentialProviderConfigurationException> {
+                            credentialManager.getCredential(this@withActivity, request)
+                        }
+                    } else {
+                        assertThrows<NoCredentialException> {
+                            credentialManager.getCredential(this@withActivity, request)
+                        }
+                    }
+                }
             }
         }
         // TODO("Add manifest tests and possibly further separate these tests by API Level
@@ -87,6 +104,31 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+    fun testPrepareGetCredential_throwsUnimplementedError() = runBlocking<Unit> {
+        val prepareGetCredentialResponse = credentialManager.prepareGetCredential(
+            GetCredentialRequest(listOf(GetPasswordOption()))
+        )
+
+        if (Looper.myLooper() == null) {
+            Looper.prepare()
+        }
+
+        withUse(ActivityScenario.launch(TestActivity::class.java)) {
+            withActivity {
+                runBlocking {
+                    assertThrows<NoCredentialException> {
+                        credentialManager.getCredential(
+                            this@withActivity,
+                            prepareGetCredentialResponse.pendingGetCredentialHandle
+                        )
+                    }
+                }
+            }
+        }
+    }
+
+    @Test
     fun testClearCredentialSession_throws() = runBlocking<Unit> {
         if (Looper.myLooper() == null) {
             Looper.prepare()
@@ -114,8 +156,8 @@
 
         activityScenario.onActivity { activity ->
             credentialManager.createCredentialAsync(
-                CreatePasswordRequest("test-user-id", "test-password"),
                 activity,
+                CreatePasswordRequest("test-user-id", "test-password"),
                 null, Executor { obj: Runnable -> obj.run() },
                 object : CredentialManagerCallback<CreateCredentialResponse,
                     CreateCredentialException> {
@@ -128,51 +170,23 @@
         }
 
         latch.await(100L, TimeUnit.MILLISECONDS)
+        if (loadedResult.get() == null) {
+            return // A strange flow occurred where an exception wasn't propagated up
+        }
         if (!isPostFrameworkApiLevel()) {
             assertThat(loadedResult.get().javaClass).isEqualTo(
                 CreateCredentialProviderConfigurationException::class.java
             )
+        } else {
+            assertThat(loadedResult.get().javaClass).isEqualTo(
+                CreateCredentialNoCreateOptionException::class.java
+            )
         }
         // TODO("Add manifest tests and possibly further separate these tests by API Level
         //  - maybe a rule perhaps?")
     }
 
     @Test
-    fun testGetCredentialAsyc_successCallbackThrows() {
-        if (Looper.myLooper() == null) {
-            Looper.prepare()
-        }
-        val latch = CountDownLatch(1)
-        val loadedResult: AtomicReference<GetCredentialException> = AtomicReference()
-
-        credentialManager.getCredentialAsync(
-            request = GetCredentialRequest.Builder()
-                .addCredentialOption(GetPasswordOption())
-                .build(),
-            activity = Activity(),
-            cancellationSignal = null,
-            executor = Runnable::run,
-            callback = object : CredentialManagerCallback<GetCredentialResponse,
-                GetCredentialException> {
-                override fun onResult(result: GetCredentialResponse) {}
-                override fun onError(e: GetCredentialException) {
-                    loadedResult.set(e)
-                    latch.countDown()
-                }
-            }
-        )
-
-        latch.await(100L, TimeUnit.MILLISECONDS)
-        if (!isPostFrameworkApiLevel()) {
-            assertThat(loadedResult.get().javaClass).isEqualTo(
-                GetCredentialProviderConfigurationException::class.java
-            )
-        }
-        // TODO("Add manifest tests and possibly further separate these tests - maybe a rule
-        //  perhaps?")
-    }
-
-    @Test
     fun testClearCredentialSessionAsync_throws() {
         if (Looper.myLooper() == null) {
             Looper.prepare()
@@ -191,13 +205,15 @@
                     loadedResult.set(e)
                     latch.countDown()
                 }
+
                 override fun onResult(result: Void?) {}
             })
 
         latch.await(100L, TimeUnit.MILLISECONDS)
         assertThat(loadedResult.get().type).isEqualTo(
             ClearCredentialProviderConfigurationException
-            .TYPE_CLEAR_CREDENTIAL_PROVIDER_CONFIGURATION_EXCEPTION)
+                .TYPE_CLEAR_CREDENTIAL_PROVIDER_CONFIGURATION_EXCEPTION
+        )
         // TODO(Add manifest tests and split this once postU is implemented for clearCreds")
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestJavaTest.java
index e8bea47..4232a1b 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestJavaTest.java
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertThrows;
 
+import android.content.ComponentName;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -31,18 +33,18 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class GetCredentialRequestJavaTest {
+    private static final String TEST_JSON = "{\"user\":{\"name\":{\"lol\":\"Value\"}}}";
     @Test
     public void constructor_emptyCredentialOptions_throws() {
         assertThrows(IllegalArgumentException.class,
                 () -> new GetCredentialRequest(new ArrayList<>()));
-
     }
 
     @Test
     public void constructor() {
         ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
         expectedCredentialOptions.add(new GetPasswordOption());
-        expectedCredentialOptions.add(new GetPublicKeyCredentialOption("json"));
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
 
         GetCredentialRequest request = new GetCredentialRequest(expectedCredentialOptions);
 
@@ -51,6 +53,38 @@
             assertThat(request.getCredentialOptions().get(i)).isEqualTo(
                     expectedCredentialOptions.get(i));
         }
+        assertThat(request.getPreferIdentityDocUi()).isFalse();
+        assertThat(request.preferImmediatelyAvailableCredentials()).isFalse();
+        assertThat(request.getPreferUiBrandingComponentName()).isNull();
+    }
+
+    @Test
+    public void constructor_nonDefaultPreferUiBrandingComponentName() {
+        ArrayList<CredentialOption> options = new ArrayList<>();
+        options.add(new GetPasswordOption());
+        ComponentName expectedComponentName = new ComponentName("test pkg", "test cls");
+
+        GetCredentialRequest request = new GetCredentialRequest(
+                options, /*origin=*/ null, /*preferIdentityDocUi=*/false, expectedComponentName);
+
+        assertThat(request.getCredentialOptions().get(0).isAutoSelectAllowed()).isFalse();
+        assertThat(request.getPreferUiBrandingComponentName()).isEqualTo(expectedComponentName);
+    }
+
+    @Test
+    public void constructor_nonDefaultPreferImmediatelyAvailableCredentials() {
+        ArrayList<CredentialOption> options = new ArrayList<>();
+        options.add(new GetPasswordOption());
+        boolean expectedPreferImmediatelyAvailableCredentials = true;
+
+        GetCredentialRequest request = new GetCredentialRequest(
+                options, /*origin=*/ null, /*preferIdentityDocUi=*/false,
+                /*preferUiBrandingComponentName=*/ null,
+                expectedPreferImmediatelyAvailableCredentials);
+
+        assertThat(request.getCredentialOptions().get(0).isAutoSelectAllowed()).isFalse();
+        assertThat(request.preferImmediatelyAvailableCredentials())
+                .isEqualTo(expectedPreferImmediatelyAvailableCredentials);
     }
 
     @Test
@@ -61,13 +95,14 @@
         GetCredentialRequest request = new GetCredentialRequest(options);
 
         assertThat(request.getCredentialOptions().get(0).isAutoSelectAllowed()).isFalse();
+        assertThat(request.getPreferIdentityDocUi()).isFalse();
     }
 
     @Test
     public void builder_addCredentialOption() {
         ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
         expectedCredentialOptions.add(new GetPasswordOption());
-        expectedCredentialOptions.add(new GetPublicKeyCredentialOption("json"));
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
 
         GetCredentialRequest request = new GetCredentialRequest.Builder()
                 .addCredentialOption(expectedCredentialOptions.get(0))
@@ -85,7 +120,7 @@
     public void builder_setCredentialOptions() {
         ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
         expectedCredentialOptions.add(new GetPasswordOption());
-        expectedCredentialOptions.add(new GetPublicKeyCredentialOption("json"));
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
 
         GetCredentialRequest request = new GetCredentialRequest.Builder()
                 .setCredentialOptions(expectedCredentialOptions)
@@ -96,6 +131,70 @@
             assertThat(request.getCredentialOptions().get(i)).isEqualTo(
                     expectedCredentialOptions.get(i));
         }
+        assertThat(request.getPreferIdentityDocUi()).isFalse();
+        assertThat(request.preferImmediatelyAvailableCredentials()).isFalse();
+        assertThat(request.getPreferUiBrandingComponentName()).isNull();
+    }
+
+    @Test
+    public void builder_setPreferIdentityDocUi() {
+        ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
+        expectedCredentialOptions.add(new GetPasswordOption());
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
+
+        GetCredentialRequest request = new GetCredentialRequest.Builder()
+                .setCredentialOptions(expectedCredentialOptions)
+                .setPreferIdentityDocUi(true)
+                .build();
+
+        assertThat(request.getCredentialOptions()).hasSize(expectedCredentialOptions.size());
+        for (int i = 0; i < expectedCredentialOptions.size(); i++) {
+            assertThat(request.getCredentialOptions().get(i)).isEqualTo(
+                    expectedCredentialOptions.get(i));
+        }
+        assertThat(request.getPreferIdentityDocUi()).isTrue();
+    }
+
+    @Test
+    public void builder_setPreferImmediatelyAvailableCredentials() {
+        ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
+        expectedCredentialOptions.add(new GetPasswordOption());
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
+        boolean expectedPreferImmediatelyAvailableCredentials = true;
+
+        GetCredentialRequest request = new GetCredentialRequest.Builder()
+                .setCredentialOptions(expectedCredentialOptions)
+                .setPreferImmediatelyAvailableCredentials(
+                        expectedPreferImmediatelyAvailableCredentials)
+                .build();
+
+        assertThat(request.getCredentialOptions()).hasSize(expectedCredentialOptions.size());
+        for (int i = 0; i < expectedCredentialOptions.size(); i++) {
+            assertThat(request.getCredentialOptions().get(i)).isEqualTo(
+                    expectedCredentialOptions.get(i));
+        }
+        assertThat(request.preferImmediatelyAvailableCredentials())
+                .isEqualTo(expectedPreferImmediatelyAvailableCredentials);
+    }
+
+    @Test
+    public void builder_setPreferUiBrandingComponentName() {
+        ArrayList<CredentialOption> expectedCredentialOptions = new ArrayList<>();
+        expectedCredentialOptions.add(new GetPasswordOption());
+        expectedCredentialOptions.add(new GetPublicKeyCredentialOption(TEST_JSON));
+        ComponentName expectedComponentName = new ComponentName("test pkg", "test cls");
+
+        GetCredentialRequest request = new GetCredentialRequest.Builder()
+                .setCredentialOptions(expectedCredentialOptions)
+                .setPreferUiBrandingComponentName(expectedComponentName)
+                .build();
+
+        assertThat(request.getCredentialOptions()).hasSize(expectedCredentialOptions.size());
+        for (int i = 0; i < expectedCredentialOptions.size(); i++) {
+            assertThat(request.getCredentialOptions().get(i)).isEqualTo(
+                    expectedCredentialOptions.get(i));
+        }
+        assertThat(request.getPreferUiBrandingComponentName()).isEqualTo(expectedComponentName);
     }
 
     @Test
@@ -106,4 +205,30 @@
 
         assertThat(request.getCredentialOptions().get(0).isAutoSelectAllowed()).isFalse();
     }
+
+    @Test
+    public void frameworkConversion() {
+        ArrayList<CredentialOption> options = new ArrayList<>();
+        options.add(new GetPasswordOption());
+        boolean expectedPreferImmediatelyAvailableCredentials = true;
+        ComponentName expectedComponentName = new ComponentName("test pkg", "test cls");
+        boolean expectedPreferIdentityDocUi = true;
+        String expectedOrigin = "origin";
+        GetCredentialRequest request = new GetCredentialRequest(options, expectedOrigin,
+                expectedPreferIdentityDocUi, expectedComponentName,
+                expectedPreferImmediatelyAvailableCredentials);
+
+
+        GetCredentialRequest convertedRequest = GetCredentialRequest.createFrom(
+                options, request.getOrigin(), GetCredentialRequest.toRequestDataBundle(request)
+        );
+
+        assertThat(convertedRequest.getOrigin()).isEqualTo(expectedOrigin);
+        assertThat(convertedRequest.getPreferIdentityDocUi()).isEqualTo(
+                expectedPreferIdentityDocUi);
+        assertThat(convertedRequest.getPreferUiBrandingComponentName()).isEqualTo(
+                expectedComponentName);
+        assertThat(convertedRequest.preferImmediatelyAvailableCredentials()).isEqualTo(
+                expectedPreferImmediatelyAvailableCredentials);
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
index 1f477d4..ca3baf6 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
+import androidx.credentials.GetCredentialRequest.Companion.createFrom
+import androidx.credentials.GetCredentialRequest.Companion.toRequestDataBundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -26,6 +29,9 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class GetCredentialRequestTest {
+    companion object Constant {
+        private const val TEST_JSON = "{\"user\":{\"name\":{\"lol\":\"Value\"}}}"
+    }
 
     @Test
     fun constructor_emptyCredentialOptions_throws() {
@@ -38,7 +44,7 @@
     fun constructor() {
         val expectedCredentialOptions = ArrayList<CredentialOption>()
         expectedCredentialOptions.add(GetPasswordOption())
-        expectedCredentialOptions.add(GetPublicKeyCredentialOption("json"))
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
         val origin = "origin"
 
         val request = GetCredentialRequest(
@@ -53,6 +59,9 @@
             )
         }
         assertThat(request.origin).isEqualTo(origin)
+        assertThat(request.preferIdentityDocUi).isFalse()
+        assertThat(request.preferImmediatelyAvailableCredentials).isFalse()
+        assertThat(request.preferUiBrandingComponentName).isNull()
     }
 
     @Test
@@ -65,13 +74,70 @@
 
         assertThat(request.credentialOptions[0].isAutoSelectAllowed).isFalse()
         assertThat(request.origin).isEqualTo(origin)
+        assertThat(request.preferIdentityDocUi).isFalse()
+    }
+
+    @Test
+    fun constructor_nonDefaultPreferUiBrandingComponentName() {
+        val options = java.util.ArrayList<CredentialOption>()
+        options.add(GetPasswordOption())
+        val expectedComponentName = ComponentName("test pkg", "test cls")
+
+        val request = GetCredentialRequest(
+            options, /*origin=*/null, /*preferIdentityDocUi=*/false, expectedComponentName
+        )
+
+        assertThat(request.credentialOptions[0].isAutoSelectAllowed).isFalse()
+        assertThat(request.preferUiBrandingComponentName).isEqualTo(expectedComponentName)
+    }
+
+    @Test
+    fun constructor_nonDefaultPreferImmediatelyAvailableCredentials() {
+        val options = java.util.ArrayList<CredentialOption>()
+        options.add(GetPasswordOption())
+        val expectedPreferImmediatelyAvailableCredentials = true
+
+        val request = GetCredentialRequest(
+            options,
+            origin = null,
+            preferIdentityDocUi = false,
+            preferUiBrandingComponentName = null,
+            expectedPreferImmediatelyAvailableCredentials
+        )
+
+        assertThat(request.credentialOptions[0].isAutoSelectAllowed).isFalse()
+        assertThat(request.preferImmediatelyAvailableCredentials)
+            .isEqualTo(expectedPreferImmediatelyAvailableCredentials)
+    }
+
+    @Test
+    fun builder_setPreferImmediatelyAvailableCredentials() {
+        val expectedCredentialOptions = java.util.ArrayList<CredentialOption>()
+        expectedCredentialOptions.add(GetPasswordOption())
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
+        val expectedPreferImmediatelyAvailableCredentials = true
+
+        val request = GetCredentialRequest.Builder()
+            .setCredentialOptions(expectedCredentialOptions)
+            .setPreferImmediatelyAvailableCredentials(
+                expectedPreferImmediatelyAvailableCredentials
+            ).build()
+
+        assertThat(request.credentialOptions).hasSize(expectedCredentialOptions.size)
+        for (i in expectedCredentialOptions.indices) {
+            assertThat(request.credentialOptions[i]).isEqualTo(
+                expectedCredentialOptions[i]
+            )
+        }
+        assertThat(request.preferImmediatelyAvailableCredentials)
+            .isEqualTo(expectedPreferImmediatelyAvailableCredentials)
     }
 
     @Test
     fun builder_addCredentialOption() {
         val expectedCredentialOptions = ArrayList<CredentialOption>()
         expectedCredentialOptions.add(GetPasswordOption())
-        expectedCredentialOptions.add(GetPublicKeyCredentialOption("json"))
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
 
         val request = GetCredentialRequest.Builder()
             .addCredentialOption(expectedCredentialOptions[0])
@@ -90,7 +156,7 @@
     fun builder_setCredentialOptions() {
         val expectedCredentialOptions = ArrayList<CredentialOption>()
         expectedCredentialOptions.add(GetPasswordOption())
-        expectedCredentialOptions.add(GetPublicKeyCredentialOption("json"))
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
 
         val request = GetCredentialRequest.Builder()
             .setCredentialOptions(expectedCredentialOptions)
@@ -102,9 +168,52 @@
                 expectedCredentialOptions[i]
             )
         }
+        assertThat(request.preferIdentityDocUi).isFalse()
+        assertThat(request.preferImmediatelyAvailableCredentials).isFalse()
+        assertThat(request.preferUiBrandingComponentName).isNull()
     }
 
     @Test
+    fun builder_setPreferIdentityDocUis() {
+        val expectedCredentialOptions = ArrayList<CredentialOption>()
+        expectedCredentialOptions.add(GetPasswordOption())
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
+
+        val request = GetCredentialRequest.Builder()
+            .setCredentialOptions(expectedCredentialOptions)
+            .setPreferIdentityDocUi(true)
+            .build()
+
+        assertThat(request.credentialOptions).hasSize(expectedCredentialOptions.size)
+        for (i in expectedCredentialOptions.indices) {
+            assertThat(request.credentialOptions[i]).isEqualTo(
+                expectedCredentialOptions[i]
+            )
+        }
+        assertThat(request.preferIdentityDocUi).isTrue()
+    }
+
+    @Test
+    fun builder_setPreferUiBrandingComponentName() {
+        val expectedCredentialOptions = java.util.ArrayList<CredentialOption>()
+        expectedCredentialOptions.add(GetPasswordOption())
+        expectedCredentialOptions.add(GetPublicKeyCredentialOption(TEST_JSON))
+        val expectedComponentName = ComponentName("test pkg", "test cls")
+
+        val request = GetCredentialRequest.Builder()
+            .setCredentialOptions(expectedCredentialOptions)
+            .setPreferUiBrandingComponentName(expectedComponentName)
+            .build()
+
+        assertThat(request.credentialOptions).hasSize(expectedCredentialOptions.size)
+        for (i in expectedCredentialOptions.indices) {
+            assertThat(request.credentialOptions[i]).isEqualTo(
+                expectedCredentialOptions[i]
+            )
+        }
+        assertThat(request.preferUiBrandingComponentName).isEqualTo(expectedComponentName)
+    }
+    @Test
     fun builder_defaultAutoSelect() {
         val request = GetCredentialRequest.Builder()
             .addCredentialOption(GetPasswordOption())
@@ -112,4 +221,34 @@
 
         assertThat(request.credentialOptions[0].isAutoSelectAllowed).isFalse()
     }
+
+    @Test
+    fun frameworkConversion() {
+        val options = java.util.ArrayList<CredentialOption>()
+        options.add(GetPasswordOption())
+        val expectedPreferImmediatelyAvailableCredentials = true
+        val expectedComponentName = ComponentName("test pkg", "test cls")
+        val expectedPreferIdentityDocUi = true
+        val expectedOrigin = "origin"
+        val request = GetCredentialRequest(
+            options, expectedOrigin,
+            expectedPreferIdentityDocUi, expectedComponentName,
+            expectedPreferImmediatelyAvailableCredentials
+        )
+
+        val convertedRequest = createFrom(
+            options, request.origin, toRequestDataBundle(request)
+        )
+
+        assertThat(convertedRequest.origin).isEqualTo(expectedOrigin)
+        assertThat(convertedRequest.preferIdentityDocUi).isEqualTo(
+            expectedPreferIdentityDocUi
+        )
+        assertThat(convertedRequest.preferUiBrandingComponentName).isEqualTo(
+            expectedComponentName
+        )
+        assertThat(convertedRequest.preferImmediatelyAvailableCredentials).isEqualTo(
+            expectedPreferImmediatelyAvailableCredentials
+        )
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionJavaTest.java
index 4d6de2d..b2c0494 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionJavaTest.java
@@ -20,14 +20,19 @@
 
 import static org.junit.Assert.assertThrows;
 
+import android.content.ComponentName;
 import android.os.Bundle;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Set;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class GetCustomCredentialOptionJavaTest {
@@ -74,12 +79,17 @@
         expectedCandidateQueryDataBundle.putBoolean("key", true);
         boolean expectedSystemProvider = true;
         boolean expectedAutoSelectAllowed = false;
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
 
         GetCustomCredentialOption option = new GetCustomCredentialOption(expectedType,
                 expectedBundle,
                 expectedCandidateQueryDataBundle,
                 expectedSystemProvider,
-                expectedAutoSelectAllowed);
+                expectedAutoSelectAllowed,
+                expectedAllowedProviders);
 
         assertThat(option.getType()).isEqualTo(expectedType);
         assertThat(TestUtilsKt.equals(option.getRequestData(), expectedBundle)).isTrue();
@@ -87,5 +97,43 @@
                 expectedCandidateQueryDataBundle)).isTrue();
         assertThat(option.isAutoSelectAllowed()).isEqualTo(expectedAutoSelectAllowed);
         assertThat(option.isSystemProviderRequired()).isEqualTo(expectedSystemProvider);
+        assertThat(option.getAllowedProviders())
+                .containsAtLeastElementsIn(expectedAllowedProviders);
+    }
+
+    @Test
+    public void frameworkConversion_success() {
+        String expectedType = "TYPE";
+        Bundle expectedBundle = new Bundle();
+        expectedBundle.putString("Test", "Test");
+        Bundle expectedCandidateQueryDataBundle = new Bundle();
+        expectedCandidateQueryDataBundle.putBoolean("key", true);
+        boolean expectedSystemProvider = true;
+        boolean expectedAutoSelectAllowed = false;
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+        GetCustomCredentialOption option = new GetCustomCredentialOption(expectedType,
+                expectedBundle,
+                expectedCandidateQueryDataBundle,
+                expectedSystemProvider,
+                expectedAutoSelectAllowed,
+                expectedAllowedProviders);
+
+        CredentialOption convertedOption = CredentialOption.createFrom(
+                option.getType(), option.getRequestData(), option.getCandidateQueryData(),
+                option.isSystemProviderRequired(), option.getAllowedProviders());
+
+        assertThat(convertedOption).isInstanceOf(GetCustomCredentialOption.class);
+        GetCustomCredentialOption actualOption = (GetCustomCredentialOption) convertedOption;
+        assertThat(actualOption.getType()).isEqualTo(expectedType);
+        assertThat(TestUtilsKt.equals(actualOption.getRequestData(), expectedBundle)).isTrue();
+        assertThat(TestUtilsKt.equals(actualOption.getCandidateQueryData(),
+                expectedCandidateQueryDataBundle)).isTrue();
+        assertThat(actualOption.isAutoSelectAllowed()).isEqualTo(expectedAutoSelectAllowed);
+        assertThat(actualOption.isSystemProviderRequired()).isEqualTo(expectedSystemProvider);
+        assertThat(actualOption.getAllowedProviders())
+                .containsAtLeastElementsIn(expectedAllowedProviders);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionTest.kt
index 4910a54..8a3c0828 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCustomCredentialOptionTest.kt
@@ -16,7 +16,9 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
+import androidx.credentials.CredentialOption.Companion.createFrom
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -56,15 +58,20 @@
         expectedBundle.putString("Test", "Test")
         val expectedCandidateQueryDataBundle = Bundle()
         expectedCandidateQueryDataBundle.putBoolean("key", true)
-        val expectedAutoSelectAllowed = false
+        val expectedAutoSelectAllowed = true
         val expectedSystemProvider = true
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
 
         val option = GetCustomCredentialOption(
             expectedType,
             expectedBundle,
             expectedCandidateQueryDataBundle,
             expectedSystemProvider,
-            expectedAutoSelectAllowed
+            expectedAutoSelectAllowed,
+            expectedAllowedProviders
         )
 
         assertThat(option.type).isEqualTo(expectedType)
@@ -75,6 +82,52 @@
                 expectedCandidateQueryDataBundle
             )
         ).isTrue()
+        assertThat(option.isAutoSelectAllowed).isEqualTo(expectedAutoSelectAllowed)
         assertThat(option.isSystemProviderRequired).isEqualTo(expectedSystemProvider)
+        assertThat(option.allowedProviders)
+            .containsAtLeastElementsIn(expectedAllowedProviders)
+    }
+
+    @Test
+    fun frameworkConversion_success() {
+        val expectedType = "TYPE"
+        val expectedBundle = Bundle()
+        expectedBundle.putString("Test", "Test")
+        val expectedCandidateQueryDataBundle = Bundle()
+        expectedCandidateQueryDataBundle.putBoolean("key", true)
+        val expectedSystemProvider = true
+        val expectedAutoSelectAllowed = false
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val option = GetCustomCredentialOption(
+            expectedType,
+            expectedBundle,
+            expectedCandidateQueryDataBundle,
+            expectedSystemProvider,
+            expectedAutoSelectAllowed,
+            expectedAllowedProviders
+        )
+
+        val convertedOption = createFrom(
+            option.type, option.requestData, option.candidateQueryData,
+            option.isSystemProviderRequired, option.allowedProviders
+        )
+
+        assertThat(convertedOption).isInstanceOf(GetCustomCredentialOption::class.java)
+        val actualOption = convertedOption as GetCustomCredentialOption
+        assertThat(actualOption.type).isEqualTo(expectedType)
+        assertThat(equals(actualOption.requestData, expectedBundle)).isTrue()
+        assertThat(
+            equals(
+                actualOption.candidateQueryData,
+                expectedCandidateQueryDataBundle
+            )
+        ).isTrue()
+        assertThat(actualOption.isAutoSelectAllowed).isEqualTo(expectedAutoSelectAllowed)
+        assertThat(actualOption.isSystemProviderRequired).isEqualTo(expectedSystemProvider)
+        assertThat(actualOption.allowedProviders)
+            .containsAtLeastElementsIn(expectedAllowedProviders)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java
index b988bb3..3e54f1b 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java
@@ -18,38 +18,114 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.ComponentName;
 import android.os.Bundle;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Set;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class GetPasswordOptionJavaTest {
     @Test
-    public void getter_frameworkProperties() {
+    public void emptyConstructor_success() {
         GetPasswordOption option = new GetPasswordOption();
-        Bundle expectedRequestDataBundle = new Bundle();
-        expectedRequestDataBundle.putBoolean(GetPasswordOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
-                false);
+
+        assertThat(option.isAutoSelectAllowed()).isFalse();
+        assertThat(option.getAllowedUserIds()).isEmpty();
+        assertThat(option.getAllowedProviders()).isEmpty();
+    }
+
+    @Test
+    public void construction_setOptionalValues_success() {
+        boolean expectedIsAutoSelectAllowed = true;
+        Set<String> expectedAllowedUserIds = ImmutableSet.of("id1", "id2", "id3");
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+
+        GetPasswordOption option = new GetPasswordOption(
+                expectedAllowedUserIds, expectedIsAutoSelectAllowed,
+                expectedAllowedProviders);
+
+        assertThat(option.isAutoSelectAllowed()).isEqualTo(expectedIsAutoSelectAllowed);
+        assertThat(option.getAllowedUserIds()).containsExactlyElementsIn(expectedAllowedUserIds);
+        assertThat(option.getAllowedProviders())
+                .containsExactlyElementsIn(expectedAllowedProviders);
+    }
+
+    @Test
+    public void getter_frameworkProperties() {
+        Set<String> expectedAllowedUserIds = ImmutableSet.of("id1", "id2", "id3");
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+        boolean expectedIsAutoSelectAllowed = true;
+
+        GetPasswordOption option = new GetPasswordOption(expectedAllowedUserIds,
+                expectedIsAutoSelectAllowed, expectedAllowedProviders);
 
         assertThat(option.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
-        assertThat(TestUtilsKt.equals(option.getRequestData(), expectedRequestDataBundle)).isTrue();
-        assertThat(TestUtilsKt.equals(option.getCandidateQueryData(), Bundle.EMPTY)).isTrue();
+        assertThat(option.getRequestData().getBoolean(
+                CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)).isTrue();
+        assertThat(option.getRequestData().getStringArrayList(
+                GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS))
+                .containsExactlyElementsIn(expectedAllowedUserIds);
+        assertThat(option.getCandidateQueryData().getBoolean(
+                CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)).isTrue();
+        assertThat(option.getCandidateQueryData().getStringArrayList(
+                GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS))
+                .containsExactlyElementsIn(expectedAllowedUserIds);
         assertThat(option.isSystemProviderRequired()).isFalse();
+        assertThat(option.getAllowedProviders())
+                .containsExactlyElementsIn(expectedAllowedProviders);
     }
 
     @Test
     public void frameworkConversion_success() {
-        GetPasswordOption option = new GetPasswordOption();
+        boolean expectedIsAutoSelectAllowed = true;
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+        Set<String> expectedAllowedUserIds = ImmutableSet.of("id1", "id2", "id3");
+        GetPasswordOption option = new GetPasswordOption(expectedAllowedUserIds,
+                expectedIsAutoSelectAllowed, expectedAllowedProviders);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle requestData = option.getRequestData();
+        String customRequestDataKey = "customRequestDataKey";
+        String customRequestDataValue = "customRequestDataValue";
+        requestData.putString(customRequestDataKey, customRequestDataValue);
+        Bundle candidateQueryData = option.getCandidateQueryData();
+        String customCandidateQueryDataKey = "customRequestDataKey";
+        Boolean customCandidateQueryDataValue = true;
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue);
+
 
         CredentialOption convertedOption = CredentialOption.createFrom(
-                option.getType(), option.getRequestData(), option.getCandidateQueryData(),
-                option.isSystemProviderRequired());
+                option.getType(), requestData, candidateQueryData,
+                option.isSystemProviderRequired(), option.getAllowedProviders());
 
         assertThat(convertedOption).isInstanceOf(GetPasswordOption.class);
+        GetPasswordOption getPasswordOption = (GetPasswordOption) convertedOption;
+        assertThat(getPasswordOption.isAutoSelectAllowed()).isEqualTo(expectedIsAutoSelectAllowed);
+        assertThat(getPasswordOption.getAllowedProviders())
+                .containsExactlyElementsIn(expectedAllowedProviders);
+        assertThat(getPasswordOption.getAllowedUserIds())
+                .containsExactlyElementsIn(expectedAllowedUserIds);
+        assertThat(convertedOption.getRequestData().getString(customRequestDataKey))
+                .isEqualTo(customRequestDataValue);
+        assertThat(convertedOption.getCandidateQueryData().getBoolean(customCandidateQueryDataKey))
+                .isEqualTo(customCandidateQueryDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt
index 2a8c6d7..0f2d4f3 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt
@@ -16,10 +16,12 @@
 
 package androidx.credentials
 
-import android.os.Bundle
+import android.content.ComponentName
 import androidx.credentials.CredentialOption.Companion.createFrom
+import androidx.credentials.GetPasswordOption.Companion.BUNDLE_KEY_ALLOWED_USER_IDS
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.google.common.collect.ImmutableSet
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -28,31 +30,105 @@
 @SmallTest
 class GetPasswordOptionTest {
     @Test
-    fun getter_frameworkProperties() {
+    fun emptyConstructor_success() {
         val option = GetPasswordOption()
-        val expectedRequestDataBundle = Bundle()
-        expectedRequestDataBundle.putBoolean(
-            CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
-            false
+
+        assertThat(option.isAutoSelectAllowed).isFalse()
+        assertThat(option.allowedProviders).isEmpty()
+        assertThat(option.allowedUserIds).isEmpty()
+    }
+
+    @Test
+    fun construction_setOptionalValues_success() {
+        val expectedIsAutoSelectAllowed = true
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val expectedAllowedUserIds: Set<String> = setOf("id1", "id2", "id3")
+
+        val option = GetPasswordOption(
+            allowedUserIds = expectedAllowedUserIds,
+            isAutoSelectAllowed = expectedIsAutoSelectAllowed,
+            allowedProviders = expectedAllowedProviders,
+        )
+
+        assertThat(option.isAutoSelectAllowed).isEqualTo(expectedIsAutoSelectAllowed)
+        assertThat(option.allowedProviders)
+            .containsExactlyElementsIn(expectedAllowedProviders)
+        assertThat(option.allowedUserIds)
+            .containsExactlyElementsIn(expectedAllowedUserIds)
+    }
+
+    @Test
+    fun getter_frameworkProperties() {
+        val expectedAllowedUserIds: Set<String> = setOf("id1", "id2", "id3")
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val expectedIsAutoSelectAllowed = true
+
+        val option = GetPasswordOption(
+            allowedUserIds = expectedAllowedUserIds,
+            isAutoSelectAllowed = expectedIsAutoSelectAllowed,
+            allowedProviders = expectedAllowedProviders,
         )
 
         assertThat(option.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
-        assertThat(equals(option.requestData, expectedRequestDataBundle)).isTrue()
-        assertThat(equals(option.candidateQueryData, Bundle.EMPTY)).isTrue()
+        assertThat(option.requestData.getBoolean(
+            CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)).isTrue()
+        assertThat(option.requestData.getStringArrayList(
+            BUNDLE_KEY_ALLOWED_USER_IDS)).containsExactlyElementsIn(expectedAllowedUserIds)
+        assertThat(option.candidateQueryData.getBoolean(
+            CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)).isTrue()
+        assertThat(option.candidateQueryData.getStringArrayList(
+            BUNDLE_KEY_ALLOWED_USER_IDS)).containsExactlyElementsIn(expectedAllowedUserIds)
         assertThat(option.isSystemProviderRequired).isFalse()
+        assertThat(option.allowedProviders)
+            .containsExactlyElementsIn(expectedAllowedProviders)
     }
 
     @Test
     fun frameworkConversion_success() {
-        val option = GetPasswordOption()
+        val expectedIsAutoSelectAllowed = true
+        val expectedAllowedProviders: Set<ComponentName> = ImmutableSet.of(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val expectedAllowedUserIds: Set<String> = ImmutableSet.of("id1", "id2", "id3")
+        val option = GetPasswordOption(
+            expectedAllowedUserIds,
+            expectedIsAutoSelectAllowed, expectedAllowedProviders
+        )
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val requestData = option.requestData
+        val customRequestDataKey = "customRequestDataKey"
+        val customRequestDataValue = "customRequestDataValue"
+        requestData.putString(customRequestDataKey, customRequestDataValue)
+        val candidateQueryData = option.candidateQueryData
+        val customCandidateQueryDataKey = "customRequestDataKey"
+        val customCandidateQueryDataValue = true
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue)
 
         val convertedOption = createFrom(
-            option.type,
-            option.requestData,
-            option.candidateQueryData,
-            option.isSystemProviderRequired
+            option.type, requestData, candidateQueryData,
+            option.isSystemProviderRequired, option.allowedProviders
         )
 
         assertThat(convertedOption).isInstanceOf(GetPasswordOption::class.java)
+        val getPasswordOption = convertedOption as GetPasswordOption
+        assertThat(getPasswordOption.isAutoSelectAllowed).isEqualTo(expectedIsAutoSelectAllowed)
+        assertThat(getPasswordOption.allowedProviders)
+            .containsExactlyElementsIn(expectedAllowedProviders)
+        assertThat(getPasswordOption.allowedUserIds)
+            .containsExactlyElementsIn(expectedAllowedUserIds)
+        assertThat(convertedOption.requestData.getString(customRequestDataKey))
+            .isEqualTo(customRequestDataValue)
+        assertThat(convertedOption.candidateQueryData.getBoolean(customCandidateQueryDataKey))
+            .isEqualTo(customCandidateQueryDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
index da4e145..18290f8 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
@@ -17,25 +17,31 @@
 package androidx.credentials;
 
 import static androidx.credentials.CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED;
-import static androidx.credentials.GetPublicKeyCredentialOption.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS;
 import static androidx.credentials.GetPublicKeyCredentialOption.BUNDLE_KEY_REQUEST_JSON;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
+import android.content.ComponentName;
 import android.os.Bundle;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Set;
+
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class GetPublicKeyCredentialOptionJavaTest {
+    private static final String TEST_REQUEST_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+
 
     @Test
     public void constructor_emptyJson_throwsIllegalArgumentException() {
@@ -55,31 +61,7 @@
 
     @Test
     public void constructor_success() {
-        new GetPublicKeyCredentialOption(
-                "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}");
-    }
-
-    @Test
-    public void constructor_setPreferImmediatelyAvailableCredentialsToFalseByDefault() {
-        GetPublicKeyCredentialOption getPublicKeyCredentialOpt =
-                new GetPublicKeyCredentialOption(
-                        "JSON");
-        boolean preferImmediatelyAvailableCredentialsActual =
-                getPublicKeyCredentialOpt.preferImmediatelyAvailableCredentials();
-        assertThat(preferImmediatelyAvailableCredentialsActual).isFalse();
-    }
-
-    @Test
-    public void constructor_setPreferImmediatelyAvailableCredentialsToTrue() {
-        boolean preferImmediatelyAvailableCredentialsExpected = true;
-        String clientDataHash = "hash";
-        GetPublicKeyCredentialOption getPublicKeyCredentialOpt =
-                new GetPublicKeyCredentialOption(
-                        "JSON", clientDataHash, preferImmediatelyAvailableCredentialsExpected);
-        boolean preferImmediatelyAvailableCredentialsActual =
-                getPublicKeyCredentialOpt.preferImmediatelyAvailableCredentials();
-        assertThat(preferImmediatelyAvailableCredentialsActual).isEqualTo(
-                preferImmediatelyAvailableCredentialsExpected);
+        new GetPublicKeyCredentialOption(TEST_REQUEST_JSON);
     }
 
     @Test
@@ -93,47 +75,66 @@
 
     @Test
     public void getter_frameworkProperties_success() {
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
         String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
-        boolean preferImmediatelyAvailableCredentialsExpected = false;
         boolean expectedIsAutoSelect = true;
-        String clientDataHash = "hash";
+        byte[] clientDataHash = "hash".getBytes();
         Bundle expectedData = new Bundle();
         expectedData.putString(
                 PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
                 GetPublicKeyCredentialOption.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION);
         expectedData.putString(BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
-        expectedData.putString(GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
+        expectedData.putByteArray(GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
                 clientDataHash);
-        expectedData.putBoolean(
-                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentialsExpected);
         expectedData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, expectedIsAutoSelect);
 
         GetPublicKeyCredentialOption option = new GetPublicKeyCredentialOption(
-                requestJsonExpected, clientDataHash, preferImmediatelyAvailableCredentialsExpected);
+                requestJsonExpected, clientDataHash, expectedAllowedProviders);
 
         assertThat(option.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
         assertThat(TestUtilsKt.equals(option.getRequestData(), expectedData)).isTrue();
-        expectedData.remove(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED);
         assertThat(TestUtilsKt.equals(option.getCandidateQueryData(), expectedData)).isTrue();
         assertThat(option.isSystemProviderRequired()).isFalse();
+        assertThat(option.getAllowedProviders())
+                .containsAtLeastElementsIn(expectedAllowedProviders);
     }
 
     @Test
     public void frameworkConversion_success() {
-        String clientDataHash = "hash";
-        GetPublicKeyCredentialOption option =
-                new GetPublicKeyCredentialOption("json", clientDataHash, true);
+        byte[] clientDataHash = "hash".getBytes();
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+        GetPublicKeyCredentialOption option = new GetPublicKeyCredentialOption(
+                TEST_REQUEST_JSON, clientDataHash, expectedAllowedProviders);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle requestData = option.getRequestData();
+        String customRequestDataKey = "customRequestDataKey";
+        String customRequestDataValue = "customRequestDataValue";
+        requestData.putString(customRequestDataKey, customRequestDataValue);
+        Bundle candidateQueryData = option.getCandidateQueryData();
+        String customCandidateQueryDataKey = "customRequestDataKey";
+        Boolean customCandidateQueryDataValue = true;
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue);
 
         CredentialOption convertedOption = CredentialOption.createFrom(
-                option.getType(), option.getRequestData(),
-                option.getCandidateQueryData(), option.isSystemProviderRequired());
+                option.getType(), requestData, candidateQueryData,
+                option.isSystemProviderRequired(), option.getAllowedProviders());
 
         assertThat(convertedOption).isInstanceOf(GetPublicKeyCredentialOption.class);
         GetPublicKeyCredentialOption convertedSubclassOption =
                 (GetPublicKeyCredentialOption) convertedOption;
         assertThat(convertedSubclassOption.getRequestJson()).isEqualTo(option.getRequestJson());
-        assertThat(convertedSubclassOption.preferImmediatelyAvailableCredentials()).isEqualTo(
-                option.preferImmediatelyAvailableCredentials());
+        assertThat(convertedSubclassOption.getAllowedProviders())
+                .containsExactlyElementsIn(expectedAllowedProviders);
+        assertThat(convertedOption.getRequestData().getString(customRequestDataKey))
+                .isEqualTo(customRequestDataValue);
+        assertThat(convertedOption.getCandidateQueryData().getBoolean(customCandidateQueryDataKey))
+                .isEqualTo(customCandidateQueryDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
index a4648fa..8775bd9 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
@@ -16,10 +16,12 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
 import androidx.credentials.CredentialOption.Companion.createFrom
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.google.common.collect.ImmutableSet
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert
 import org.junit.Test
@@ -28,6 +30,9 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class GetPublicKeyCredentialOptionTest {
+    companion object Constant {
+        private const val TEST_REQUEST_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+    }
 
     @Test
     fun constructor_emptyJson_throwsIllegalArgumentException() {
@@ -39,32 +44,7 @@
 
     @Test
     fun constructor_success() {
-        GetPublicKeyCredentialOption(
-            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
-        )
-    }
-
-    @Test
-    fun constructor_setPreferImmediatelyAvailableCredentialsToFalseByDefault() {
-        val getPublicKeyCredentialOpt = GetPublicKeyCredentialOption(
-            "JSON"
-        )
-        val preferImmediatelyAvailableCredentialsActual =
-            getPublicKeyCredentialOpt.preferImmediatelyAvailableCredentials
-        assertThat(preferImmediatelyAvailableCredentialsActual).isFalse()
-    }
-
-    @Test
-    fun constructor_setPreferImmediatelyAvailableCredentialsTrue() {
-        val preferImmediatelyAvailableCredentialsExpected = true
-        val clientDataHash = "hash"
-        val getPublicKeyCredentialOpt = GetPublicKeyCredentialOption(
-            "JSON", clientDataHash, preferImmediatelyAvailableCredentialsExpected
-        )
-        val preferImmediatelyAvailableCredentialsActual =
-            getPublicKeyCredentialOpt.preferImmediatelyAvailableCredentials
-        assertThat(preferImmediatelyAvailableCredentialsActual)
-            .isEqualTo(preferImmediatelyAvailableCredentialsExpected)
+        GetPublicKeyCredentialOption(TEST_REQUEST_JSON)
     }
 
     @Test
@@ -78,9 +58,12 @@
     @Test
     fun getter_frameworkProperties_success() {
         val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
-        val preferImmediatelyAvailableCredentialsExpected = false
         val expectedAutoSelectAllowed = true
-        val clientDataHash = "hash"
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val clientDataHash = "hash".toByteArray()
         val expectedData = Bundle()
         expectedData.putString(
             PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
@@ -90,39 +73,51 @@
             GetPublicKeyCredentialOption.BUNDLE_KEY_REQUEST_JSON,
             requestJsonExpected
         )
-        expectedData.putString(GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
+        expectedData.putByteArray(GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
             clientDataHash)
         expectedData.putBoolean(
-            GetPublicKeyCredentialOption.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-            preferImmediatelyAvailableCredentialsExpected
-        )
-        expectedData.putBoolean(
             CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED,
             expectedAutoSelectAllowed
         )
 
         val option = GetPublicKeyCredentialOption(
-            requestJsonExpected, clientDataHash, preferImmediatelyAvailableCredentialsExpected
+            requestJsonExpected, clientDataHash, expectedAllowedProviders
         )
 
         assertThat(option.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
         assertThat(equals(option.requestData, expectedData)).isTrue()
-        expectedData.remove(CredentialOption.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)
         assertThat(equals(option.candidateQueryData, expectedData)).isTrue()
         assertThat(option.isSystemProviderRequired).isFalse()
         assertThat(option.isAutoSelectAllowed).isTrue()
+        assertThat(option.allowedProviders).containsAtLeastElementsIn(expectedAllowedProviders)
     }
 
     @Test
     fun frameworkConversion_success() {
-        val clientDataHash = "hash"
-        val option = GetPublicKeyCredentialOption("json", clientDataHash, true)
+        val clientDataHash = "hash".toByteArray()
+        val expectedAllowedProviders: Set<ComponentName> = ImmutableSet.of(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+        val option = GetPublicKeyCredentialOption(
+            TEST_REQUEST_JSON, clientDataHash, expectedAllowedProviders
+        )
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val requestData = option.requestData
+        val customRequestDataKey = "customRequestDataKey"
+        val customRequestDataValue = "customRequestDataValue"
+        requestData.putString(customRequestDataKey, customRequestDataValue)
+        val candidateQueryData = option.candidateQueryData
+        val customCandidateQueryDataKey = "customRequestDataKey"
+        val customCandidateQueryDataValue = true
+        candidateQueryData.putBoolean(customCandidateQueryDataKey, customCandidateQueryDataValue)
 
         val convertedOption = createFrom(
-            option.type,
-            option.requestData,
-            option.candidateQueryData,
-            option.isSystemProviderRequired
+            option.type, requestData, candidateQueryData,
+            option.isSystemProviderRequired, option.allowedProviders
         )
 
         assertThat(convertedOption).isInstanceOf(
@@ -130,7 +125,11 @@
         )
         val convertedSubclassOption = convertedOption as GetPublicKeyCredentialOption
         assertThat(convertedSubclassOption.requestJson).isEqualTo(option.requestJson)
-        assertThat(convertedSubclassOption.preferImmediatelyAvailableCredentials)
-            .isEqualTo(option.preferImmediatelyAvailableCredentials)
+        assertThat(convertedSubclassOption.allowedProviders)
+            .containsExactlyElementsIn(expectedAllowedProviders)
+        assertThat(convertedOption.requestData.getString(customRequestDataKey))
+            .isEqualTo(customRequestDataValue)
+        assertThat(convertedOption.candidateQueryData.getBoolean(customCandidateQueryDataKey))
+            .isEqualTo(customCandidateQueryDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java
index 659dd33..51ecfa3 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java
@@ -31,6 +31,13 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PasswordCredentialJavaTest {
+
+    @Test
+    public void typeConstant() {
+        assertThat(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+                .isEqualTo("android.credentials.TYPE_PASSWORD_CREDENTIAL");
+    }
+
     @Test
     public void constructor_nullId_throws() {
         assertThrows(
@@ -86,13 +93,21 @@
     @Test
     public void frameworkConversion_success() {
         PasswordCredential credential = new PasswordCredential("id", "password");
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle data = credential.getData();
+        String customDataKey = "customRequestDataKey";
+        CharSequence customDataValue = "customRequestDataValue";
+        data.putCharSequence(customDataKey, customDataValue);
 
         Credential convertedCredential = Credential.createFrom(
-                credential.getType(), credential.getData());
+                credential.getType(), data);
 
         assertThat(convertedCredential).isInstanceOf(PasswordCredential.class);
         PasswordCredential convertedSubclassCredential = (PasswordCredential) convertedCredential;
         assertThat(convertedSubclassCredential.getPassword()).isEqualTo(credential.getPassword());
         assertThat(convertedSubclassCredential.getId()).isEqualTo(credential.getId());
+        assertThat(convertedCredential.getData().getCharSequence(customDataKey))
+                .isEqualTo(customDataValue);
     }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt
index 2c3f59d..e361e8f 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt
@@ -28,6 +28,13 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class PasswordCredentialTest {
+
+    @Test
+    fun typeConstant() {
+        assertThat(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+            .isEqualTo("android.credentials.TYPE_PASSWORD_CREDENTIAL")
+    }
+
     @Test
     fun constructor_emptyPassword_throws() {
         assertThrows<IllegalArgumentException> {
@@ -66,14 +73,26 @@
     @Test
     fun frameworkConversion_success() {
         val credential = PasswordCredential("id", "password")
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val data = credential.data
+        val customDataKey = "customRequestDataKey"
+        val customDataValue: CharSequence = "customRequestDataValue"
+        data.putCharSequence(customDataKey, customDataValue)
 
         val convertedCredential = createFrom(
-            credential.type, credential.data
+            credential.type, data
         )
 
-        assertThat(convertedCredential).isInstanceOf(PasswordCredential::class.java)
+        assertThat(convertedCredential).isInstanceOf(
+            PasswordCredential::class.java
+        )
         val convertedSubclassCredential = convertedCredential as PasswordCredential
         assertThat(convertedSubclassCredential.password).isEqualTo(credential.password)
         assertThat(convertedSubclassCredential.id).isEqualTo(credential.id)
+        assertThat(convertedCredential.data.getCharSequence(customDataKey))
+            .isEqualTo(customDataValue)
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
index 3a63354..ad01121 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
@@ -34,6 +34,13 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PublicKeyCredentialJavaTest {
+    private static final String TEST_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+
+    @Test
+    public void typeConstant() {
+        assertThat(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+                .isEqualTo("androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL");
+    }
 
     @Test
     public void constructor_emptyJson_throwsIllegalArgumentException() {
@@ -53,8 +60,7 @@
 
     @Test
     public void constructor_success() {
-        new PublicKeyCredential(
-                "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}");
+        new PublicKeyCredential(TEST_JSON);
     }
 
     @Test
@@ -81,15 +87,23 @@
 
     @Test
     public void frameworkConversion_success() {
-        PublicKeyCredential credential = new PublicKeyCredential("json");
+        PublicKeyCredential credential = new PublicKeyCredential(TEST_JSON);
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        Bundle data = credential.getData();
+        String customDataKey = "customRequestDataKey";
+        CharSequence customDataValue = "customRequestDataValue";
+        data.putCharSequence(customDataKey, customDataValue);
 
         Credential convertedCredential = Credential.createFrom(
-                credential.getType(), credential.getData());
+                credential.getType(), data);
 
         assertThat(convertedCredential).isInstanceOf(PublicKeyCredential.class);
         PublicKeyCredential convertedSubclassCredential = (PublicKeyCredential) convertedCredential;
         assertThat(convertedSubclassCredential.getAuthenticationResponseJson())
                 .isEqualTo(credential.getAuthenticationResponseJson());
+        assertThat(convertedCredential.getData().getCharSequence(customDataKey))
+                .isEqualTo(customDataValue);
     }
 
     @Test
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
index d701cae..08fb335 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
@@ -32,6 +32,16 @@
 @SmallTest
 class PublicKeyCredentialTest {
 
+    companion object Constant {
+        private const val TEST_JSON = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+    }
+
+    @Test
+    fun typeConstant() {
+        assertThat(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+            .isEqualTo("androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL")
+    }
+
     @Test
     fun constructor_emptyJson_throwsIllegalArgumentException() {
         Assert.assertThrows(
@@ -41,10 +51,16 @@
     }
 
     @Test
+    fun constructor_invalidJson_throwsIllegalArgumentException() {
+        Assert.assertThrows(
+            "Expected invalid Json to throw IllegalArgumentException",
+            IllegalArgumentException::class.java
+        ) { PublicKeyCredential("invalid") }
+    }
+
+    @Test
     fun constructor_success() {
-        PublicKeyCredential(
-            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
-        )
+        PublicKeyCredential(TEST_JSON)
     }
 
     @Test
@@ -73,16 +89,26 @@
 
     @Test
     fun frameworkConversion_success() {
-        val credential = PublicKeyCredential("json")
+        val credential = PublicKeyCredential(TEST_JSON)
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        // Add additional data to the request data and candidate query data to make sure
+        // they persist after the conversion
+        val data = credential.data
+        val customDataKey = "customRequestDataKey"
+        val customDataValue: CharSequence = "customRequestDataValue"
+        data.putCharSequence(customDataKey, customDataValue)
 
         val convertedCredential = createFrom(
-            credential.type, credential.data
+            credential.type, data
         )
 
         assertThat(convertedCredential).isInstanceOf(PublicKeyCredential::class.java)
         val convertedSubclassCredential = convertedCredential as PublicKeyCredential
         assertThat(convertedSubclassCredential.authenticationResponseJson)
             .isEqualTo(credential.authenticationResponseJson)
+        assertThat(convertedCredential.data.getCharSequence(customDataKey))
+            .isEqualTo(customDataValue)
     }
 
     @Test
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt
index 440f3db..4428cc5 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt
@@ -16,8 +16,12 @@
 
 package androidx.credentials
 
+import android.graphics.drawable.Icon
 import android.os.Build
 import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.CallingAppInfo
 
 /** True if the two Bundles contain the same elements, and false otherwise. */
 @Suppress("DEPRECATION")
@@ -68,7 +72,15 @@
 /** True if the device running the test is post framework api level,
  * false if pre framework api level. */
 fun isPostFrameworkApiLevel(): Boolean {
-    return !((Build.VERSION.SDK_INT <= MAX_CRED_MAN_PRE_FRAMEWORK_API_LEVEL) &&
-        !(Build.VERSION.SDK_INT == MAX_CRED_MAN_PRE_FRAMEWORK_API_LEVEL &&
-            Build.VERSION.PREVIEW_SDK_INT > 0))
+    return BuildCompat.isAtLeastU()
+}
+
+@RequiresApi(Build.VERSION_CODES.P)
+fun equals(a: Icon, b: Icon): Boolean {
+    return a.type == b.type && a.resId == b.resId
+}
+
+@RequiresApi(34)
+fun equals(a: CallingAppInfo, b: CallingAppInfo): Boolean {
+    return a.packageName == b.packageName && a.origin == b.origin
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionJavaTest.java
new file mode 100644
index 0000000..2694726
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionJavaTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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.credentials.internal;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class FrameworkClassParsingExceptionJavaTest {
+
+    @Test
+    public void constructor_success() {
+        new FrameworkClassParsingException();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionTest.kt
new file mode 100644
index 0000000..8485d8c
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/internal/FrameworkClassParsingExceptionTest.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.credentials.internal
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+  @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+  @RunWith(AndroidJUnit4::class)
+  @SmallTest
+  class FrameworkClassParsingExceptionTest {
+
+      @Test
+      fun constructor_success() {
+          FrameworkClassParsingException()
+      }
+  }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseJavaTest.java
new file mode 100644
index 0000000..5373fb5
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseJavaTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.credentials.provider;
+
+import static androidx.credentials.provider.ui.UiUtils.constructCreateEntryWithSimpleParams;
+import static androidx.credentials.provider.ui.UiUtils.constructRemoteEntry;
+import static androidx.credentials.provider.ui.UiUtils.constructRemoteEntryDefault;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import androidx.core.os.BuildCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginCreateCredentialResponseJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginCreateCredentialResponse(
+                Arrays.asList(constructCreateEntryWithSimpleParams("AccountName",
+                        "Desc")),
+                null
+        );
+    }
+
+    @Test
+    public void builder_createEntriesOnly_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginCreateCredentialResponse.Builder().setCreateEntries(
+                Arrays.asList(constructCreateEntryWithSimpleParams("AccountName",
+                        "Desc"))
+        ).build();
+    }
+
+    @Test
+    public void builder_remoteEntryOnly_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginCreateCredentialResponse.Builder().setRemoteEntry(
+                constructRemoteEntry()
+        ).build();
+    }
+
+    @Test
+    public void constructor_nullList_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginCreateCredentialResponse(
+                        null, null)
+        );
+    }
+
+    @Test
+    public void buildConstruct_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginCreateCredentialResponse.Builder().setCreateEntries(
+                Arrays.asList(constructCreateEntryWithSimpleParams("AccountName",
+                        "Desc"))).build();
+    }
+
+    @Test
+    public void buildConstruct_nullList_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginCreateCredentialResponse.Builder().setCreateEntries(null).build()
+        );
+    }
+
+    @Test
+    public void getter_createEntry() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedAccountName = "AccountName";
+        String expectedDescription = "Desc";
+
+        BeginCreateCredentialResponse response = new BeginCreateCredentialResponse(
+                Collections.singletonList(constructCreateEntryWithSimpleParams(expectedAccountName,
+                        expectedDescription)), null);
+        String actualAccountName = response.getCreateEntries().get(0).getAccountName().toString();
+        String actualDescription = response.getCreateEntries().get(0).getDescription().toString();
+
+        assertThat(actualAccountName).isEqualTo(expectedAccountName);
+        assertThat(actualDescription).isEqualTo(expectedDescription);
+    }
+
+    @Test
+    public void getter_remoteEntry_null() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        RemoteEntry expectedRemoteEntry = null;
+        BeginCreateCredentialResponse response = new BeginCreateCredentialResponse(
+                Arrays.asList(constructCreateEntryWithSimpleParams("AccountName",
+                        "Desc")),
+                expectedRemoteEntry
+        );
+        RemoteEntry actualRemoteEntry = response.getRemoteEntry();
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry);
+    }
+
+    @Test
+    public void getter_remoteEntry_nonNull() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry expectedRemoteEntry = constructRemoteEntryDefault();
+
+        BeginCreateCredentialResponse response = new BeginCreateCredentialResponse(
+                Arrays.asList(constructCreateEntryWithSimpleParams("AccountName",
+                        "Desc")),
+                expectedRemoteEntry
+        );
+        RemoteEntry actualRemoteEntry = response.getRemoteEntry();
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseTest.kt
new file mode 100644
index 0000000..675a6c9
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCredentialResponseTest.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.credentials.provider
+
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.ui.UiUtils.Companion.constructCreateEntryWithSimpleParams
+import androidx.credentials.provider.ui.UiUtils.Companion.constructRemoteEntryDefault
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class BeginCreateCredentialResponseTest {
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        BeginCreateCredentialResponse(
+            createEntries = listOf(
+                constructCreateEntryWithSimpleParams(
+                    "AccountName",
+                    "Desc"
+                )
+            ),
+            remoteEntry = constructRemoteEntryDefault()
+        )
+    }
+
+    @Test
+    fun constructor_createEntriesOnly() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        BeginCreateCredentialResponse(
+            createEntries = listOf(
+                constructCreateEntryWithSimpleParams(
+                    "AccountName",
+                    "Desc"
+                )
+            )
+        )
+    }
+
+    @Test
+    fun constructor_remoteEntryOnly() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        BeginCreateCredentialResponse(
+            remoteEntry = constructRemoteEntryDefault()
+        )
+    }
+
+    @Test
+    fun getter_createEntry() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedAccountName = "AccountName"
+        val expectedDescription = "Desc"
+        val expectedSize = 1
+
+        val beginCreateCredentialResponse = BeginCreateCredentialResponse(
+            listOf(
+                constructCreateEntryWithSimpleParams(
+                    expectedAccountName,
+                    expectedDescription
+                )
+            ), null
+        )
+        val actualAccountName = beginCreateCredentialResponse.createEntries[0].accountName
+        val actualDescription = beginCreateCredentialResponse.createEntries[0].description
+
+        assertThat(beginCreateCredentialResponse.createEntries.size).isEqualTo(expectedSize)
+        assertThat(actualAccountName).isEqualTo(expectedAccountName)
+        assertThat(actualDescription).isEqualTo(expectedDescription)
+    }
+
+    @Test
+    fun getter_remoteEntry_null() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val expectedRemoteEntry: RemoteEntry? = null
+        val beginCreateCredentialResponse = BeginCreateCredentialResponse(
+            listOf(
+                constructCreateEntryWithSimpleParams(
+                    "AccountName",
+                    "Desc"
+                )
+            ),
+            expectedRemoteEntry
+        )
+        val actualRemoteEntry = beginCreateCredentialResponse.remoteEntry
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry)
+    }
+
+    @Test
+    fun getter_remoteEntry_nonNull() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedRemoteEntry: RemoteEntry = constructRemoteEntryDefault()
+
+        val beginCreateCredentialResponse = BeginCreateCredentialResponse(
+            listOf(
+                constructCreateEntryWithSimpleParams(
+                    "AccountName",
+                    "Desc"
+                )
+            ),
+            expectedRemoteEntry
+        )
+        val actualRemoteEntry = beginCreateCredentialResponse.remoteEntry
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestJavaTest.java
new file mode 100644
index 0000000..77dbc37
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestJavaTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.pm.SigningInfo;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginCreateCustomCredentialRequestJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginCreateCustomCredentialRequest("type", Bundle.EMPTY, null);
+    }
+
+    @Test
+    public void constructor_nullTypeBundle_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        // TODO(b/275416815) - parameterize to account for all individually
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginCreateCustomCredentialRequest(null, null,
+                        new CallingAppInfo(
+                        "package", new SigningInfo()))
+        );
+    }
+
+    @Test
+    public void constructor_emptyType_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected empty type to throw IAE",
+                IllegalArgumentException.class,
+                () -> new BeginCreateCustomCredentialRequest("", Bundle.EMPTY,
+                        new CallingAppInfo(
+                                "package", new SigningInfo()))
+        );
+    }
+
+    @Test
+    public void getter_type() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedType = "ironman";
+
+        BeginCreateCustomCredentialRequest beginCreateCustomCredentialRequest =
+                new BeginCreateCustomCredentialRequest(expectedType, Bundle.EMPTY, null);
+        String actualType = beginCreateCustomCredentialRequest.getType();
+
+        assertThat(actualType).isEqualTo(expectedType);
+    }
+
+    @Test
+    public void getter_bundle() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedKey = "query";
+        String expectedValue = "data";
+        Bundle expectedBundle = new Bundle();
+        expectedBundle.putString(expectedKey, expectedValue);
+
+        BeginCreateCustomCredentialRequest beginCreateCustomCredentialRequest =
+                new BeginCreateCustomCredentialRequest("type", expectedBundle, null);
+        Bundle actualBundle = beginCreateCustomCredentialRequest.getCandidateQueryData();
+
+        assertThat(actualBundle.getString(expectedKey)).isEqualTo(expectedValue);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestTest.kt
new file mode 100644
index 0000000..81ce420
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreateCustomCredentialRequestTest.kt
@@ -0,0 +1,87 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class BeginCreateCustomCredentialRequestTest {
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginCreateCustomCredentialRequest("type", Bundle.EMPTY, null)
+    }
+
+    @Test
+    fun constructor_emptyType_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty type to throw IAE",
+            IllegalArgumentException::class.java
+        ) {
+            BeginCreateCustomCredentialRequest(
+                "", Bundle.EMPTY,
+                CallingAppInfo(
+                    "package", SigningInfo()
+                )
+            )
+        }
+    }
+
+    @Test
+    fun getter_type() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedType = "ironman"
+        val beginCreateCustomCredentialRequest =
+            BeginCreateCustomCredentialRequest(expectedType, Bundle.EMPTY, null)
+        val actualType = beginCreateCustomCredentialRequest.type
+        assertThat(actualType).isEqualTo(expectedType)
+    }
+
+    @Test
+    fun getter_bundle() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedKey = "query"
+        val expectedValue = "data"
+        val expectedBundle = Bundle()
+        expectedBundle.putString(expectedKey, expectedValue)
+        val beginCreateCustomCredentialRequest =
+            BeginCreateCustomCredentialRequest("type", expectedBundle, null)
+        val actualBundle = beginCreateCustomCredentialRequest.candidateQueryData
+        assertThat(actualBundle.getString(expectedKey)).isEqualTo(expectedValue)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestJavaTest.java
new file mode 100644
index 0000000..b8c7790
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestJavaTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.SigningInfo;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.TestUtilsKt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginCreatePasswordRequestJavaTest {
+    @Test
+    public void constructor_success() {
+        if (BuildCompat.isAtLeastU()) {
+            new BeginCreatePasswordCredentialRequest(
+                    new CallingAppInfo("sample_package_name",
+                            new SigningInfo()),
+                    new Bundle());
+        }
+    }
+
+    @Test
+    public void getter_callingAppInfo() {
+        if (BuildCompat.isAtLeastU()) {
+            Bundle expectedCandidateQueryBundle = new Bundle();
+            expectedCandidateQueryBundle.putString("key", "value");
+            String expectedPackageName = "sample_package_name";
+            SigningInfo expectedSigningInfo = new SigningInfo();
+            CallingAppInfo expectedCallingAppInfo = new CallingAppInfo(expectedPackageName,
+                    expectedSigningInfo);
+
+            BeginCreatePasswordCredentialRequest request =
+                    new BeginCreatePasswordCredentialRequest(expectedCallingAppInfo,
+                            expectedCandidateQueryBundle);
+
+            assertThat(request.getCallingAppInfo().getPackageName()).isEqualTo(expectedPackageName);
+            assertThat(request.getCallingAppInfo().getSigningInfo()).isEqualTo(expectedSigningInfo);
+            TestUtilsKt.equals(request.getCandidateQueryData(), expectedCandidateQueryBundle);
+        }
+    }
+
+    // TODO ("Add framework conversion, createFrom tests")
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestTest.kt
new file mode 100644
index 0000000..e0810b5
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePasswordRequestTest.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.content.pm.SigningInfo
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.credentials.equals
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(34)
+class BeginCreatePasswordRequestTest {
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginCreatePasswordCredentialRequest(
+            CallingAppInfo(
+                "sample_package_name",
+                SigningInfo()
+            ),
+            Bundle()
+        )
+    }
+
+    @Test
+    fun getter_callingAppInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val expectedCandidateQueryBundle = Bundle()
+        expectedCandidateQueryBundle.putString("key", "value")
+        val expectedPackageName = "sample_package_name"
+        val expectedSigningInfo = SigningInfo()
+        val expectedCallingAppInfo = CallingAppInfo(
+            expectedPackageName,
+            expectedSigningInfo
+        )
+
+        val request = BeginCreatePasswordCredentialRequest(
+            expectedCallingAppInfo, expectedCandidateQueryBundle)
+
+        equals(request.candidateQueryData, expectedCandidateQueryBundle)
+        assertThat(request.callingAppInfo?.packageName).isEqualTo(expectedPackageName)
+        assertThat(request.callingAppInfo?.signingInfo).isEqualTo(expectedSigningInfo)
+    }
+
+    // TODO ("Add framework conversion, createFrom tests")
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestJavaTest.java
new file mode 100644
index 0000000..29259d8
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestJavaTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.pm.SigningInfo;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginCreatePublicKeyCredentialRequestJavaTest {
+    @Test
+    public void constructor_emptyJson_throwsIllegalArgumentException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected empty Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginCreatePublicKeyCredentialRequest(
+                            "",
+                            new CallingAppInfo(
+                                    "sample_package_name", new SigningInfo()),
+                            new Bundle()
+                    )
+            );
+        }
+    }
+
+    @Test
+    public void constructor_invalidJson_throwsIllegalArgumentException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected invalid Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginCreatePublicKeyCredentialRequest(
+                            "invalid",
+                            new CallingAppInfo(
+                                    "sample_package_name", new SigningInfo()),
+                            new Bundle()
+                    )
+            );
+        }
+    }
+
+    @Test
+    public void constructor_nullJson_throwsNullPointerException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected null Json to throw NPE",
+                    NullPointerException.class,
+                    () -> new BeginCreatePublicKeyCredentialRequest(
+                            null,
+                            new CallingAppInfo("sample_package_name",
+                                    new SigningInfo()),
+                            new Bundle()
+                    )
+            );
+        }
+    }
+
+    @Test
+    public void constructor_success() {
+        if (BuildCompat.isAtLeastU()) {
+            new BeginCreatePublicKeyCredentialRequest(
+                    "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+                    new CallingAppInfo(
+                            "sample_package_name", new SigningInfo()
+                    ),
+                    new Bundle()
+            );
+        }
+    }
+
+    @Test
+    public void constructorWithClientDataHash_success() {
+        if (BuildCompat.isAtLeastU()) {
+            new BeginCreatePublicKeyCredentialRequest(
+                    "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+                    new CallingAppInfo(
+                            "sample_package_name", new SigningInfo()
+                    ),
+                    new Bundle(),
+                    "client_data_hash".getBytes()
+            );
+        }
+    }
+
+    @Test
+    public void getter_requestJson_success() {
+        if (BuildCompat.isAtLeastU()) {
+            String testJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+
+            BeginCreatePublicKeyCredentialRequest
+                    createPublicKeyCredentialReq = new BeginCreatePublicKeyCredentialRequest(
+                    testJsonExpected,
+                    new CallingAppInfo(
+                            "sample_package_name", new SigningInfo()),
+                    new Bundle()
+            );
+
+            String testJsonActual = createPublicKeyCredentialReq.getRequestJson();
+            assertThat(testJsonActual).isEqualTo(testJsonExpected);
+            assertThat(createPublicKeyCredentialReq.getClientDataHash()).isNull();
+
+        }
+    }
+
+    @Test
+    public void getter_clientDataHash_success() {
+        if (BuildCompat.isAtLeastU()) {
+            String testClientDataHashExpected = "client_data_hash";
+            BeginCreatePublicKeyCredentialRequest createPublicKeyCredentialReq =
+                    new BeginCreatePublicKeyCredentialRequest(
+                            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+                            new CallingAppInfo("sample_package_name",
+                                    new SigningInfo()),
+                            new Bundle(),
+                            testClientDataHashExpected.getBytes());
+
+            assertThat(createPublicKeyCredentialReq.getClientDataHash())
+                    .isEqualTo(testClientDataHashExpected.getBytes());
+        }
+    }
+    // TODO ("Add framework conversion, createFrom & preferImmediatelyAvailable tests")
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestTest.kt
new file mode 100644
index 0000000..14a2143
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequestTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.content.pm.SigningInfo
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(34)
+class BeginCreatePublicKeyCredentialRequestTest {
+    @Test
+    fun constructor_emptyJson_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty Json to throw error",
+            IllegalArgumentException::class.java
+        ) {
+            BeginCreatePublicKeyCredentialRequest(
+                "",
+                CallingAppInfo(
+                    "sample_package_name",
+                    SigningInfo()
+                ),
+                Bundle()
+            )
+        }
+    }
+
+    @Test
+    fun constructor_invalidJson_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected invalid Json to throw error",
+            IllegalArgumentException::class.java
+        ) {
+            BeginCreatePublicKeyCredentialRequest(
+                "invalid",
+                CallingAppInfo(
+                    "sample_package_name",
+                    SigningInfo()
+                ),
+                Bundle()
+            )
+        }
+    }
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginCreatePublicKeyCredentialRequest(
+            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+            CallingAppInfo(
+                "sample_package_name", SigningInfo()
+            ),
+            Bundle()
+        )
+    }
+
+    @Test
+    fun constructorWithClientDataHash_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginCreatePublicKeyCredentialRequest(
+            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+            CallingAppInfo(
+                "sample_package_name", SigningInfo()
+            ),
+            Bundle(),
+            "client_data_hash".toByteArray()
+        )
+    }
+
+    @Test
+    fun getter_requestJson_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val testJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+
+        val createPublicKeyCredentialReq = BeginCreatePublicKeyCredentialRequest(
+            testJsonExpected,
+            CallingAppInfo(
+                "sample_package_name", SigningInfo()
+            ),
+            Bundle()
+        )
+
+        val testJsonActual = createPublicKeyCredentialReq.requestJson
+        assertThat(testJsonActual).isEqualTo(testJsonExpected)
+        assertThat(createPublicKeyCredentialReq.clientDataHash).isNull()
+    }
+
+    @Test
+    fun getter_clientDataHash_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val testClientDataHashExpected = "client_data_hash".toByteArray()
+        val createPublicKeyCredentialReq = BeginCreatePublicKeyCredentialRequest(
+            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+            CallingAppInfo(
+                "sample_package_name", SigningInfo()
+            ),
+            Bundle(),
+            testClientDataHashExpected
+        )
+
+        val testClientDataHashActual = createPublicKeyCredentialReq.clientDataHash
+        assertThat(testClientDataHashActual).isEqualTo(testClientDataHashExpected)
+    }
+    // TODO ("Add framework conversion, createFrom & preferImmediatelyAvailable tests")
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestJavaTest.java
new file mode 100644
index 0000000..b91f15a
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestJavaTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.pm.SigningInfo;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginGetCredentialRequestJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginGetCredentialRequest(Collections.emptyList(), null);
+    }
+
+    @Test
+    public void constructor_nullList_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginGetCredentialRequest(null,
+                        new CallingAppInfo("tom.cruise.security",
+                                new SigningInfo()))
+        );
+    }
+
+    @Test
+    public void getter_beginGetCredentialOptions() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedKey = "query";
+        String expectedValue = "data";
+        Bundle expectedBundle = new Bundle();
+        expectedBundle.putString(expectedKey, expectedValue);
+        String expectedId = "key";
+        String expectedType = "mach-10";
+        int expectedBeginGetCredentialOptionsSize = 1;
+
+        BeginGetCredentialRequest beginGetCredentialRequest =
+                new BeginGetCredentialRequest(Collections.singletonList(
+                        new BeginGetCustomCredentialOption(expectedId, expectedType,
+                                expectedBundle)),
+                        null);
+        List<BeginGetCredentialOption> actualBeginGetCredentialOptionList =
+                beginGetCredentialRequest.getBeginGetCredentialOptions();
+        int actualBeginGetCredentialOptionsSize = actualBeginGetCredentialOptionList.size();
+        assertThat(actualBeginGetCredentialOptionsSize)
+                .isEqualTo(expectedBeginGetCredentialOptionsSize);
+        String actualBundleValue =
+                actualBeginGetCredentialOptionList.get(0).getCandidateQueryData()
+                        .getString(expectedKey);
+        String actualId = actualBeginGetCredentialOptionList.get(0).getId();
+        String actualType = actualBeginGetCredentialOptionList.get(0).getType();
+
+        assertThat(actualBundleValue).isEqualTo(expectedValue);
+        assertThat(actualId).isEqualTo(expectedId);
+        assertThat(actualType).isEqualTo(expectedType);
+    }
+
+    @Test
+    public void getter_nullCallingAppInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CallingAppInfo expectedCallingAppInfo = null;
+
+        BeginGetCredentialRequest beginGetCredentialRequest =
+                new BeginGetCredentialRequest(Collections.emptyList(),
+                        expectedCallingAppInfo);
+        CallingAppInfo actualCallingAppInfo = beginGetCredentialRequest.getCallingAppInfo();
+
+        assertThat(actualCallingAppInfo).isEqualTo(expectedCallingAppInfo);
+    }
+
+    @Test
+    public void getter_nonNullCallingAppInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedPackageName = "john.wick.four.credentials";
+        CallingAppInfo expectedCallingAppInfo = new CallingAppInfo(expectedPackageName,
+                new SigningInfo());
+
+        BeginGetCredentialRequest beginGetCredentialRequest =
+                new BeginGetCredentialRequest(Collections.emptyList(),
+                        expectedCallingAppInfo);
+        CallingAppInfo actualCallingAppInfo = beginGetCredentialRequest.getCallingAppInfo();
+        String actualPackageName = actualCallingAppInfo.getPackageName();
+
+        assertThat(actualPackageName).isEqualTo(expectedPackageName);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestTest.kt
new file mode 100644
index 0000000..3ccd7b3
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialRequestTest.kt
@@ -0,0 +1,103 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class BeginGetCredentialRequestTest {
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginGetCredentialRequest(emptyList(), null)
+    }
+
+    @Test
+    fun getter_beginGetCredentialOptions() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedKey = "query"
+        val expectedValue = "data"
+        val expectedBundle = Bundle()
+        expectedBundle.putString(expectedKey, expectedValue)
+        val expectedId = "key"
+        val expectedType = "mach-10"
+        val expectedBeginGetCredentialOptionsSize = 1
+
+        val beginGetCredentialRequest = BeginGetCredentialRequest(
+            listOf(
+                BeginGetCustomCredentialOption(expectedId, expectedType, expectedBundle)
+            ),
+            null
+        )
+        val actualBeginGetCredentialOptionList = beginGetCredentialRequest.beginGetCredentialOptions
+        val actualBeginGetCredentialOptionsSize = actualBeginGetCredentialOptionList.size
+        assertThat(actualBeginGetCredentialOptionsSize)
+            .isEqualTo(expectedBeginGetCredentialOptionsSize)
+        val actualBundleValue = actualBeginGetCredentialOptionList[0].candidateQueryData
+            .getString(expectedKey)
+        val actualId = actualBeginGetCredentialOptionList[0].id
+        val actualType = actualBeginGetCredentialOptionList[0].type
+
+        assertThat(actualBundleValue).isEqualTo(expectedValue)
+        assertThat(actualId).isEqualTo(expectedId)
+        assertThat(actualType).isEqualTo(expectedType)
+    }
+
+    @Test
+    fun getter_nullCallingAppInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedCallingAppInfo: CallingAppInfo? = null
+
+        val beginGetCredentialRequest = BeginGetCredentialRequest(
+            emptyList(),
+            expectedCallingAppInfo
+        )
+        val actualCallingAppInfo = beginGetCredentialRequest.callingAppInfo
+
+        assertThat(actualCallingAppInfo).isEqualTo(expectedCallingAppInfo)
+    }
+
+    @Test
+    fun getter_nonNullCallingAppInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedPackageName = "john.wick.four.credentials"
+        val expectedCallingAppInfo = CallingAppInfo(
+            expectedPackageName,
+            SigningInfo()
+        )
+
+        val beginGetCredentialRequest = BeginGetCredentialRequest(
+            emptyList(),
+            expectedCallingAppInfo
+        )
+        val actualCallingAppInfo = beginGetCredentialRequest.callingAppInfo
+        val actualPackageName = actualCallingAppInfo!!.packageName
+
+        assertThat(actualPackageName).isEqualTo(expectedPackageName)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseJavaTest.java
new file mode 100644
index 0000000..8be08e4
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseJavaTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.credentials.provider;
+
+import static androidx.credentials.provider.ui.UiUtils.constructActionEntry;
+import static androidx.credentials.provider.ui.UiUtils.constructAuthenticationActionEntry;
+import static androidx.credentials.provider.ui.UiUtils.constructPasswordCredentialEntryDefault;
+import static androidx.credentials.provider.ui.UiUtils.constructRemoteEntryDefault;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.PasswordCredential;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginGetCredentialResponseJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginGetCredentialResponse();
+    }
+
+    // TODO(b/275416815) - parameterize to account for all individually
+    @Test
+    public void constructor_nullList_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginGetCredentialResponse(
+                        null, null, null, constructRemoteEntryDefault())
+        );
+    }
+
+    @Test
+    public void buildConstruct_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new BeginGetCredentialResponse.Builder().build();
+    }
+
+    @Test
+    public void buildConstruct_nullList_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new BeginGetCredentialResponse.Builder().setCredentialEntries(null)
+                        .setActions(null).setAuthenticationActions(null).build()
+        );
+    }
+
+    @Test
+    public void getter_credentialEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        int expectedSize = 1;
+        String expectedType = PasswordCredential.TYPE_PASSWORD_CREDENTIAL;
+        String expectedUsername = "f35";
+
+        BeginGetCredentialResponse response = new BeginGetCredentialResponse(
+                Collections.singletonList(constructPasswordCredentialEntryDefault(
+                        expectedUsername)), Collections.emptyList(), Collections.emptyList(),
+                null);
+        int actualSize = response.getCredentialEntries().size();
+        String actualType = response.getCredentialEntries().get(0).getType();
+        String actualUsername = ((PasswordCredentialEntry) response.getCredentialEntries().get(0))
+                .getUsername().toString();
+
+        assertThat(actualSize).isEqualTo(expectedSize);
+        assertThat(actualType).isEqualTo(expectedType);
+        assertThat(actualUsername).isEqualTo(expectedUsername);
+    }
+
+    @Test
+    public void getter_actionEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        int expectedSize = 1;
+        String expectedTitle = "boeing";
+        String expectedSubtitle = "737max";
+
+        BeginGetCredentialResponse response = new BeginGetCredentialResponse(
+                Collections.emptyList(),
+                Collections.singletonList(constructActionEntry(expectedTitle, expectedSubtitle)),
+                Collections.emptyList(), null);
+        int actualSize = response.getActions().size();
+        String actualTitle = response.getActions().get(0).getTitle().toString();
+        String actualSubtitle = response.getActions().get(0).getSubtitle().toString();
+
+        assertThat(actualSize).isEqualTo(expectedSize);
+        assertThat(actualTitle).isEqualTo(expectedTitle);
+        assertThat(actualSubtitle).isEqualTo(expectedSubtitle);
+    }
+
+    @Test
+    public void getter_authActionEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        int expectedSize = 1;
+        String expectedTitle = "boeing";
+
+        BeginGetCredentialResponse response = new BeginGetCredentialResponse(
+                Collections.emptyList(),
+                Collections.emptyList(),
+                Collections.singletonList(constructAuthenticationActionEntry(expectedTitle)), null);
+        int actualSize = response.getAuthenticationActions().size();
+        String actualTitle = response.getAuthenticationActions().get(0).getTitle().toString();
+
+        assertThat(actualSize).isEqualTo(expectedSize);
+        assertThat(actualTitle).isEqualTo(expectedTitle);
+    }
+
+    @Test
+    public void getter_remoteEntry_null() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry expectedRemoteEntry = null;
+
+        BeginGetCredentialResponse response = new BeginGetCredentialResponse(
+                Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
+                expectedRemoteEntry
+        );
+        RemoteEntry actualRemoteEntry = response.getRemoteEntry();
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry);
+    }
+
+    @Test
+    public void getter_remoteEntry_nonNull() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry expectedRemoteEntry = constructRemoteEntryDefault();
+
+        BeginGetCredentialResponse response = new BeginGetCredentialResponse(
+                Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
+                expectedRemoteEntry
+        );
+        RemoteEntry actualRemoteEntry = response.getRemoteEntry();
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseTest.kt
new file mode 100644
index 0000000..c985c92
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCredentialResponseTest.kt
@@ -0,0 +1,154 @@
+/*
+ * 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.credentials.provider
+
+import androidx.core.os.BuildCompat
+import androidx.credentials.PasswordCredential
+import androidx.credentials.provider.ui.UiUtils.Companion.constructActionEntry
+import androidx.credentials.provider.ui.UiUtils.Companion.constructAuthenticationActionEntry
+import androidx.credentials.provider.ui.UiUtils.Companion.constructPasswordCredentialEntryDefault
+import androidx.credentials.provider.ui.UiUtils.Companion.constructRemoteEntryDefault
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class BeginGetCredentialResponseTest {
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        BeginGetCredentialResponse()
+    }
+
+    @Test
+    fun buildConstruct_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        BeginGetCredentialResponse.Builder().build()
+    }
+
+    @Test
+    fun getter_credentialEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedSize = 1
+        val expectedType = PasswordCredential.TYPE_PASSWORD_CREDENTIAL
+        val expectedUsername = "f35"
+
+        val response = BeginGetCredentialResponse(
+            listOf(
+                constructPasswordCredentialEntryDefault(
+                    expectedUsername
+                )
+            )
+        )
+        val actualSize = response.credentialEntries.size
+        val actualType = response.credentialEntries[0].type
+        val actualUsername = (response.credentialEntries[0] as PasswordCredentialEntry)
+            .username.toString()
+
+        assertThat(actualSize).isEqualTo(expectedSize)
+        assertThat(actualType).isEqualTo(expectedType)
+        assertThat(actualUsername).isEqualTo(expectedUsername)
+    }
+
+    @Test
+    fun getter_actionEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedSize = 1
+        val expectedTitle = "boeing"
+        val expectedSubtitle = "737max"
+
+        val response = BeginGetCredentialResponse(
+            emptyList(),
+            listOf(constructActionEntry(expectedTitle, expectedSubtitle))
+        )
+        val actualSize = response.actions.size
+        val actualTitle = response.actions[0].title.toString()
+        val actualSubtitle = response.actions[0].subtitle.toString()
+
+        assertThat(actualSize).isEqualTo(expectedSize)
+        assertThat(actualTitle).isEqualTo(expectedTitle)
+        assertThat(actualSubtitle).isEqualTo(expectedSubtitle)
+    }
+
+    @Test
+    fun getter_authActionEntries() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedSize = 1
+        val expectedTitle = "boeing"
+
+        val response = BeginGetCredentialResponse(
+            emptyList(), emptyList(), listOf(
+                constructAuthenticationActionEntry(expectedTitle)
+            )
+        )
+        val actualSize = response.authenticationActions.size
+        val actualTitle = response.authenticationActions[0].title.toString()
+
+        assertThat(actualSize).isEqualTo(expectedSize)
+        assertThat(actualTitle).isEqualTo(expectedTitle)
+    }
+
+    @Test
+    fun getter_remoteEntry_null() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val expectedRemoteEntry: RemoteEntry? = null
+        val response = BeginGetCredentialResponse(
+            emptyList(), emptyList(), emptyList(),
+            expectedRemoteEntry
+        )
+        val actualRemoteEntry = response.remoteEntry
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry)
+    }
+
+    @Test
+    fun getter_remoteEntry_nonNull() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val expectedRemoteEntry = constructRemoteEntryDefault()
+        val response = BeginGetCredentialResponse(
+            emptyList(), emptyList(), emptyList(),
+            expectedRemoteEntry
+        )
+        val actualRemoteEntry = response.remoteEntry
+
+        assertThat(actualRemoteEntry).isEqualTo(expectedRemoteEntry)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionJavaTest.java
new file mode 100644
index 0000000..1394cac
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionJavaTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.TestUtilsKt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginGetCustomCredentialOptionJavaTest {
+    @Test
+    public void constructor_success() {
+        if (BuildCompat.isAtLeastU()) {
+            Bundle expectedBundle = new Bundle();
+            expectedBundle.putString("random", "random_value");
+            String expectedType = "type";
+            String expectedId = "id";
+
+            BeginGetCustomCredentialOption option = new BeginGetCustomCredentialOption(
+                    expectedId, expectedType, expectedBundle);
+
+            assertThat(option.getType()).isEqualTo(expectedType);
+            assertThat(option.getId()).isEqualTo(expectedId);
+            assertThat(TestUtilsKt.equals(option.getCandidateQueryData(), expectedBundle)).isTrue();
+        }
+    }
+
+    @Test
+    public void constructor_emptyType_throwsIAE() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected empty Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginGetCustomCredentialOption(
+                            "id",
+                            "",
+                            new Bundle()
+                    )
+            );
+        }
+    }
+
+    @Test
+    public void constructor_emptyId_throwsIAE() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected empty Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginGetCustomCredentialOption(
+                            "",
+                            "type",
+                            new Bundle()
+                    )
+            );
+        }
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionTest.kt
new file mode 100644
index 0000000..f659b8c
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetCustomCredentialOptionTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.credentials.equals
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class BeginGetCustomCredentialOptionTest {
+    @Test
+    fun constructor_success() {
+        if (BuildCompat.isAtLeastU()) {
+            val expectedBundle = Bundle()
+            expectedBundle.putString("random", "random_value")
+            val expectedType = "type"
+            val expectedId = "id"
+            val option = BeginGetCustomCredentialOption(
+                expectedId, expectedType, expectedBundle
+            )
+            Truth.assertThat(option.type).isEqualTo(expectedType)
+            Truth.assertThat(option.id).isEqualTo(expectedId)
+            Truth.assertThat(equals(option.candidateQueryData, expectedBundle)).isTrue()
+        }
+    }
+
+    @Test
+    fun constructor_emptyType_throwsIAE() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows(
+                "Expected empty Json to throw error",
+                IllegalArgumentException::class.java
+            ) {
+                BeginGetCustomCredentialOption(
+                    "id",
+                    "",
+                    Bundle()
+                )
+            }
+        }
+    }
+
+    @Test
+    fun constructor_emptyId_throwsIAE() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows(
+                "Expected empty Json to throw error",
+                IllegalArgumentException::class.java
+            ) {
+                BeginGetCustomCredentialOption(
+                    "",
+                    "type",
+                    Bundle()
+                )
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionJavaTest.java
new file mode 100644
index 0000000..f73d7a0
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionJavaTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.GetPasswordOption;
+import androidx.credentials.PasswordCredential;
+import androidx.credentials.TestUtilsKt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginGetPasswordOptionJavaTest {
+    private static final String BUNDLE_ID_KEY =
+            "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY";
+    private static final String BUNDLE_ID = "id";
+    @Test
+    public void getter_frameworkProperties() {
+        if (BuildCompat.isAtLeastU()) {
+            Set<String> expectedAllowedUserIds = ImmutableSet.of("id1", "id2", "id3");
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS,
+                    new ArrayList<>(expectedAllowedUserIds));
+
+            BeginGetPasswordOption option = new BeginGetPasswordOption(expectedAllowedUserIds,
+                    bundle, BUNDLE_ID);
+
+            bundle.putString(BUNDLE_ID_KEY, BUNDLE_ID);
+            assertThat(option.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+            assertThat(TestUtilsKt.equals(option.getCandidateQueryData(), bundle)).isTrue();
+            assertThat(option.getAllowedUserIds())
+                    .containsExactlyElementsIn(expectedAllowedUserIds);
+        }
+    }
+
+    // TODO ("Add framework conversion, createFrom tests")
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionTest.kt
new file mode 100644
index 0000000..1fd619e
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPasswordOptionTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.credentials.GetPasswordOption
+import androidx.credentials.PasswordCredential
+import androidx.credentials.equals
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(34)
+class BeginGetPasswordOptionTest {
+    companion object {
+        private const val BUNDLE_ID_KEY =
+            "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY"
+        private const val BUNDLE_ID = "id"
+    }
+    @Test
+    fun getter_frameworkProperties() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedAllowedUserIds: Set<String> = setOf("id1", "id2", "id3")
+        val bundle = Bundle()
+        bundle.putStringArrayList(
+            GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS,
+            ArrayList(expectedAllowedUserIds)
+        )
+
+        val option = BeginGetPasswordOption(expectedAllowedUserIds, bundle, BUNDLE_ID)
+
+        bundle.putString(BUNDLE_ID_KEY, BUNDLE_ID)
+        assertThat(option.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        assertThat(equals(option.candidateQueryData, bundle)).isTrue()
+        assertThat(option.allowedUserIds).containsExactlyElementsIn(expectedAllowedUserIds)
+    }
+
+    // TODO ("Add framework conversion, createFrom tests")
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionJavaTest.java
new file mode 100644
index 0000000..f4f8a21
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionJavaTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider;
+
+import static androidx.credentials.GetPublicKeyCredentialOption.BUNDLE_KEY_REQUEST_JSON;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.GetPublicKeyCredentialOption;
+import androidx.credentials.PublicKeyCredential;
+import androidx.credentials.TestUtilsKt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class BeginGetPublicKeyCredentialOptionJavaTest {
+    private static final String BUNDLE_ID_KEY =
+            "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY";
+    private static final String BUNDLE_ID = "id";
+    @Test
+    public void constructor_emptyJson_throwsIllegalArgumentException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected empty Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginGetPublicKeyCredentialOption(
+                            new Bundle(), "", "")
+            );
+        }
+    }
+
+    @Test
+    public void constructor_invalidJson_throwsIllegalArgumentException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected invalid Json to throw error",
+                    IllegalArgumentException.class,
+                    () -> new BeginGetPublicKeyCredentialOption(
+                            new Bundle(), "", "invalid")
+            );
+        }
+    }
+
+    @Test
+    public void constructor_nullJson_throwsNullPointerException() {
+        if (BuildCompat.isAtLeastU()) {
+            assertThrows("Expected null Json to throw NPE",
+                    NullPointerException.class,
+                    () -> new BeginGetPublicKeyCredentialOption(
+                            new Bundle(), BUNDLE_ID, null)
+            );
+        }
+    }
+
+    @Test
+    public void constructor_success() {
+        if (BuildCompat.isAtLeastU()) {
+            new BeginGetPublicKeyCredentialOption(
+                    new Bundle(), BUNDLE_ID,
+                    "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}");
+        }
+    }
+
+    @Test
+    public void constructorWithClientDataHash_success() {
+        if (BuildCompat.isAtLeastU()) {
+            new BeginGetPublicKeyCredentialOption(
+                    new Bundle(), BUNDLE_ID,
+                    "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+                    "client_data_hash".getBytes());
+        }
+    }
+
+    @Test
+    public void getter_requestJson_success() {
+        if (BuildCompat.isAtLeastU()) {
+            String testJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+
+            BeginGetPublicKeyCredentialOption getPublicKeyCredentialOpt =
+                    new BeginGetPublicKeyCredentialOption(
+                            new Bundle(), BUNDLE_ID, testJsonExpected);
+
+            String testJsonActual = getPublicKeyCredentialOpt.getRequestJson();
+            assertThat(testJsonActual).isEqualTo(testJsonExpected);
+        }
+    }
+
+    @Test
+    public void getter_clientDataHash_success() {
+        if (BuildCompat.isAtLeastU()) {
+            byte[] testClientDataHashExpected = "client_data_hash".getBytes();
+
+            BeginGetPublicKeyCredentialOption beginGetPublicKeyCredentialOpt =
+                    new BeginGetPublicKeyCredentialOption(
+                            new Bundle(), BUNDLE_ID,
+                            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+                            testClientDataHashExpected);
+
+            byte[] testClientDataHashActual = beginGetPublicKeyCredentialOpt.getClientDataHash();
+            assertThat(testClientDataHashActual).isEqualTo(testClientDataHashExpected);
+        }
+    }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        if (BuildCompat.isAtLeastU()) {
+            String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+            byte[] clientDataHash = "client_data_hash".getBytes();
+            Bundle expectedData = new Bundle();
+            expectedData.putString(
+                    PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
+                    GetPublicKeyCredentialOption
+                            .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION);
+            expectedData.putString(BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
+            expectedData.putByteArray(GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
+                    clientDataHash);
+
+            BeginGetPublicKeyCredentialOption option = new BeginGetPublicKeyCredentialOption(
+                    expectedData, BUNDLE_ID, requestJsonExpected, clientDataHash);
+
+            expectedData.putString(BUNDLE_ID_KEY, BUNDLE_ID);
+            assertThat(option.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+            assertThat(TestUtilsKt.equals(option.getCandidateQueryData(), expectedData)).isTrue();
+        }
+    }
+    // TODO ("Add framework conversion, createFrom tests")
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionTest.kt
new file mode 100644
index 0000000..54f6fa4
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOptionTest.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.credentials.GetPublicKeyCredentialOption
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.equals
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(34)
+class BeginGetPublicKeyCredentialOptionTest {
+    companion object {
+        private const val BUNDLE_ID_KEY =
+            "android.service.credentials.BeginGetCredentialOption.BUNDLE_ID_KEY"
+        private const val BUNDLE_ID = "id"
+    }
+    @Test
+    fun constructor_emptyJson_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty Json to throw error",
+            IllegalArgumentException::class.java
+        ) {
+            BeginGetPublicKeyCredentialOption(Bundle(), "", "")
+        }
+    }
+
+    @Test
+    fun constructor_invalidJson_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected invalid Json to throw error",
+            IllegalArgumentException::class.java
+        ) {
+            BeginGetPublicKeyCredentialOption(Bundle(), "", "invalid")
+        }
+    }
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        BeginGetPublicKeyCredentialOption(
+            Bundle(), BUNDLE_ID, "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}",
+            "client_data_hash".toByteArray()
+        )
+    }
+
+    @Test
+    fun getter_clientDataHash_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val testClientDataHashExpected = "client_data_hash".toByteArray()
+
+        val beginGetPublicKeyCredentialOpt = BeginGetPublicKeyCredentialOption(
+            Bundle(), BUNDLE_ID,
+            "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}", testClientDataHashExpected
+        )
+
+        val testClientDataHashActual = beginGetPublicKeyCredentialOpt.clientDataHash
+        assertThat(testClientDataHashActual).isEqualTo(testClientDataHashExpected)
+    }
+
+    @Test
+    fun getter_requestJson_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val testJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+
+        val getPublicKeyCredentialOpt = BeginGetPublicKeyCredentialOption(
+            Bundle(), BUNDLE_ID, testJsonExpected
+        )
+
+        val testJsonActual = getPublicKeyCredentialOpt.requestJson
+        assertThat(testJsonActual).isEqualTo(testJsonExpected)
+    }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val clientDataHash = "client_data_hash".toByteArray()
+        val expectedData = Bundle()
+        expectedData.putString(
+            PublicKeyCredential.BUNDLE_KEY_SUBTYPE,
+            GetPublicKeyCredentialOption.BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION)
+        expectedData.putString(
+            GetPublicKeyCredentialOption.BUNDLE_KEY_REQUEST_JSON,
+            requestJsonExpected)
+        expectedData.putByteArray(
+            GetPublicKeyCredentialOption.BUNDLE_KEY_CLIENT_DATA_HASH,
+            clientDataHash)
+
+        val option = BeginGetPublicKeyCredentialOption(expectedData, BUNDLE_ID, requestJsonExpected)
+
+        expectedData.putString(BUNDLE_ID_KEY, BUNDLE_ID)
+        assertThat(option.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(option.candidateQueryData, expectedData)).isTrue()
+    }
+
+    // TODO ("Add framework conversion, createFrom tests")
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoJavaTest.java
new file mode 100644
index 0000000..be8bd0f
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoJavaTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.credentials.provider;
+
+import android.content.pm.SigningInfo;
+
+import androidx.core.os.BuildCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class CallingAppInfoJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new CallingAppInfo("name", new SigningInfo());
+    }
+
+    @Test
+    public void constructor_success_withOrigin() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new CallingAppInfo("name", new SigningInfo(), "origin");
+    }
+
+    @Test
+    public void constructor_fail_emptyPackageName() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Assert.assertThrows(
+                "Expected exception from no package name",
+                IllegalArgumentException.class,
+                () -> {
+                    new CallingAppInfo("", new SigningInfo(), "origin");
+                });
+    }
+
+    @Test
+    public void constructor_fail_nullPackageName() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Assert.assertThrows(
+                "Expected exception from null package name",
+                NullPointerException.class,
+                () -> {
+                    new CallingAppInfo(null, new SigningInfo(), "origin");
+                });
+    }
+
+    @Test
+    public void constructor_fail_nullSigningInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Assert.assertThrows(
+                "Expected exception from null signing info",
+                NullPointerException.class,
+                () -> {
+                    new CallingAppInfo("package", null, "origin");
+                });
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoTest.kt
new file mode 100644
index 0000000..bbd22fe
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/CallingAppInfoTest.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+import androidx.core.os.BuildCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+ @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+ @RunWith(AndroidJUnit4::class)
+ @SmallTest
+ class CallingAppInfoTest {
+
+     @Test
+     fun constructor_success() {
+         if (!BuildCompat.isAtLeastU()) {
+             return
+         }
+
+         CallingAppInfo("name", SigningInfo())
+     }
+
+     @Test
+     fun constructor_success_withOrigin() {
+         if (!BuildCompat.isAtLeastU()) {
+             return
+         }
+
+         CallingAppInfo("name", SigningInfo(), "origin")
+     }
+
+     @Test
+     fun constructor_fail_emptyPackageName() {
+         if (!BuildCompat.isAtLeastU()) {
+             return
+         }
+
+         Assert.assertThrows(
+            "Expected exception from no package name",
+            IllegalArgumentException::class.java
+        ) {
+            CallingAppInfo("", SigningInfo(), "origin")
+        }
+     }
+ }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerJavaTest.java
new file mode 100644
index 0000000..6490d0e
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerJavaTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Intent;
+
+import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
+import androidx.credentials.CreatePasswordResponse;
+import androidx.credentials.GetCredentialResponse;
+import androidx.credentials.PasswordCredential;
+import androidx.credentials.exceptions.CreateCredentialInterruptedException;
+import androidx.credentials.exceptions.GetCredentialInterruptedException;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RequiresApi(34)
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class PendingIntentHandlerJavaTest {
+    private static final Intent BLANK_INTENT = new Intent();
+
+    @Test
+    public void test_setGetCreateCredentialException() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Intent intent = new Intent();
+
+        CreateCredentialInterruptedException initialException =
+                new CreateCredentialInterruptedException("message");
+
+        PendingIntentHandler.setCreateCredentialException(intent, initialException);
+
+        android.credentials.CreateCredentialException finalException =
+                IntentHandlerConverters.getCreateCredentialException(intent);
+        assertThat(finalException).isNotNull();
+        assertThat(finalException.getMessage()).isEqualTo(initialException.getMessage());
+    }
+
+    @Test
+    public void test_setGetCreateCredentialException_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThat(
+                        IntentHandlerConverters.getCreateCredentialException(
+                                BLANK_INTENT))
+                .isNull();
+    }
+
+    @Test
+    public void test_credentialException() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Intent intent = new Intent();
+        GetCredentialInterruptedException initialException =
+                new GetCredentialInterruptedException("message");
+
+        PendingIntentHandler.setGetCredentialException(intent, initialException);
+
+        android.credentials.GetCredentialException finalException =
+                IntentHandlerConverters.getGetCredentialException(intent);
+        assertThat(finalException).isNotNull();
+        assertThat(finalException).isEqualTo(initialException);
+    }
+
+    @Test
+    public void test_credentialException_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThat(IntentHandlerConverters.getGetCredentialException(BLANK_INTENT))
+                .isNull();
+    }
+
+    @Test
+    public void test_beginGetResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Intent intent = new Intent();
+        BeginGetCredentialResponse initialResponse =
+                new BeginGetCredentialResponse.Builder().build();
+
+        PendingIntentHandler.setBeginGetCredentialResponse(intent, initialResponse);
+
+        BeginGetCredentialResponse finalResponse =
+                IntentHandlerConverters.getBeginGetResponse(intent);
+        assertThat(finalResponse).isNotNull();
+        assertThat(finalResponse).isEqualTo(initialResponse);
+    }
+
+    @Test
+    public void test_beginGetResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThat(IntentHandlerConverters.getBeginGetResponse(BLANK_INTENT))
+                .isNull();
+    }
+
+    @Test
+    public void test_credentialResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Intent intent = new Intent();
+        PasswordCredential credential = new PasswordCredential("a", "b");
+        GetCredentialResponse initialResponse = new GetCredentialResponse(credential);
+
+        PendingIntentHandler.setGetCredentialResponse(intent, initialResponse);
+
+        android.credentials.GetCredentialResponse finalResponse =
+                IntentHandlerConverters.getGetCredentialResponse(intent);
+        assertThat(finalResponse).isNotNull();
+        assertThat(finalResponse).isEqualTo(initialResponse);
+    }
+
+    @Test
+    public void test_credentialResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThat(IntentHandlerConverters.getGetCredentialResponse(BLANK_INTENT))
+                .isNull();
+    }
+
+    @Test
+    public void test_createCredentialCredentialResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        Intent intent = new Intent();
+        CreatePasswordResponse initialResponse = new CreatePasswordResponse();
+
+        PendingIntentHandler.setCreateCredentialResponse(intent, initialResponse);
+
+        android.credentials.CreateCredentialResponse finalResponse =
+                IntentHandlerConverters.getCreateCredentialCredentialResponse(
+                        intent);
+        assertThat(finalResponse).isNotNull();
+        assertThat(finalResponse).isEqualTo(initialResponse);
+    }
+
+    @Test
+    public void test_createCredentialCredentialResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThat(
+                        IntentHandlerConverters
+                                .getCreateCredentialCredentialResponse(BLANK_INTENT))
+                .isNull();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerTest.kt
new file mode 100644
index 0000000..f14c8e0
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/PendingIntentHandlerTest.kt
@@ -0,0 +1,170 @@
+/*
+ * 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.credentials.provider
+
+import android.content.Intent
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.credentials.CreatePasswordResponse
+import androidx.credentials.GetCredentialResponse
+import androidx.credentials.PasswordCredential
+import androidx.credentials.equals
+import androidx.credentials.exceptions.CreateCredentialInterruptedException
+import androidx.credentials.exceptions.GetCredentialInterruptedException
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@RequiresApi(34)
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+class PendingIntentHandlerTest {
+    @Test
+    fun test_createCredentialException() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val initialException = CreateCredentialInterruptedException("message")
+
+        PendingIntentHandler.setCreateCredentialException(intent, initialException)
+
+        val finalException = intent.getCreateCredentialException()
+        assertThat(finalException).isNotNull()
+        assertThat(finalException).isEqualTo(initialException)
+    }
+
+    @Test()
+    fun test_createCredentialException_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        assertThat(intent.getCreateCredentialException()).isNull()
+    }
+
+    @Test
+    fun test_credentialException() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val initialException = GetCredentialInterruptedException("message")
+
+        PendingIntentHandler.setGetCredentialException(intent, initialException)
+
+        val finalException = intent.getGetCredentialException()
+        assertThat(finalException).isNotNull()
+        assertThat(finalException).isEqualTo(initialException)
+    }
+
+    @Test
+    fun test_credentialException_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        assertThat(intent.getGetCredentialException()).isNull()
+    }
+
+    @Test
+    fun test_beginGetResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val initialResponse = BeginGetCredentialResponse.Builder().build()
+
+        PendingIntentHandler.setBeginGetCredentialResponse(intent, initialResponse)
+
+        val finalResponse = intent.getBeginGetResponse()
+        assertThat(finalResponse).isNotNull()
+        assertThat(finalResponse).isEqualTo(initialResponse)
+    }
+
+    @Test
+    fun test_beginGetResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        assertThat(intent.getBeginGetResponse()).isNull()
+    }
+
+    @Test
+    fun test_credentialResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val credential = PasswordCredential("a", "b")
+        val initialResponse = GetCredentialResponse(credential)
+
+        PendingIntentHandler.setGetCredentialResponse(intent, initialResponse)
+
+        val finalResponse = intent.getGetCredentialResponse()
+        assertThat(finalResponse).isNotNull()
+        assertThat(finalResponse).isEqualTo(initialResponse)
+    }
+
+    @Test
+    fun test_credentialResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        assertThat(intent.getGetCredentialResponse()).isNull()
+    }
+
+    @Test
+    fun test_createCredentialCredentialResponse() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val initialResponse = CreatePasswordResponse()
+
+        PendingIntentHandler.setCreateCredentialResponse(intent, initialResponse)
+
+        val finalResponse = intent.getCreateCredentialCredentialResponse()
+        assertThat(finalResponse).isNotNull()
+        assertThat(finalResponse).isEqualTo(initialResponse)
+    }
+
+    @Test
+    fun test_createCredentialCredentialResponse_throwsWhenEmptyIntent() {
+        if (BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val intent = Intent()
+        val r = intent.getCreateCredentialCredentialResponse()
+        assertThat(r).isNull()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestJavaTest.java
new file mode 100644
index 0000000..ea7e5bf
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestJavaTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.pm.SigningInfo;
+
+import androidx.credentials.TestUtilsKt;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ProviderClearCredentialStateRequestJavaTest {
+
+    @Test
+    public void testConstructor_success() {
+        CallingAppInfo callingAppInfo = new CallingAppInfo(
+                "package", new SigningInfo());
+
+        ProviderClearCredentialStateRequest request = new
+                ProviderClearCredentialStateRequest(callingAppInfo);
+
+        assertThat(TestUtilsKt.equals(request.getCallingAppInfo(), callingAppInfo))
+                .isTrue();
+    }
+
+    @Test
+    public void testConstructor_nullCallingAppInfo_throwsNPE() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new ProviderClearCredentialStateRequest(null)
+        );
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestTest.kt
new file mode 100644
index 0000000..d5b9a6a
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderClearCredentialStateRequestTest.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+import androidx.annotation.RequiresApi
+import androidx.credentials.equals
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ProviderClearCredentialStateRequestTest {
+
+    @RequiresApi(34)
+    @Test
+    fun testConstructor_success() {
+        val callingAppInfo = CallingAppInfo("sample_package_name", SigningInfo())
+
+        val request = ProviderClearCredentialStateRequest(callingAppInfo)
+
+        assertThat(equals(callingAppInfo, request.callingAppInfo)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestJavaTest.java
new file mode 100644
index 0000000..b8b4cbe
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestJavaTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.credentials.provider;
+
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.pm.SigningInfo;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.CreatePasswordRequest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ProviderCreateCredentialRequestJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        CreatePasswordRequest request = new CreatePasswordRequest("id", "password");
+
+        new ProviderCreateCredentialRequest(request, new CallingAppInfo("name", new SigningInfo()));
+    }
+
+    @Test
+    public void constructor_nullInputs_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows(
+                "Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new ProviderCreateCredentialRequest(null, null));
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestTest.kt
new file mode 100644
index 0000000..075e5cb
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderCreateCredentialRequestTest.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+import androidx.core.os.BuildCompat
+import androidx.credentials.CreatePasswordRequest
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+ @SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+ @RunWith(AndroidJUnit4::class)
+ @SmallTest
+ class ProviderCreateCredentialRequestTest {
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        val request = CreatePasswordRequest("id", "password")
+
+        ProviderCreateCredentialRequest(
+                request,
+                CallingAppInfo("name",
+                SigningInfo()))
+    }
+ }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestJavaTest.java
new file mode 100644
index 0000000..e0172a2
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestJavaTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.credentials.provider;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.content.pm.SigningInfo;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.CredentialOption;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.collect.ImmutableSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ProviderGetCredentialRequestJavaTest {
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        new ProviderGetCredentialRequest(
+                Collections.singletonList(CredentialOption.createFrom("type", new Bundle(),
+                        new Bundle(), true, ImmutableSet.of())),
+                new CallingAppInfo("name",
+                new SigningInfo()));
+    }
+
+    @Test
+    public void constructor_nullInputs_throws() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+
+        assertThrows("Expected null list to throw NPE",
+                NullPointerException.class,
+                () -> new ProviderGetCredentialRequest(null, null)
+        );
+    }
+
+    @Test
+    public void getter_credentialOptions() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedType = "BoeingCred";
+        String expectedQueryKey = "PilotName";
+        String expectedQueryValue = "PilotPassword";
+        Bundle expectedCandidateQueryData = new Bundle();
+        expectedCandidateQueryData.putString(expectedQueryKey, expectedQueryValue);
+        String expectedRequestKey = "PlaneKey";
+        String expectedRequestValue = "PlaneInfo";
+        Bundle expectedRequestData = new Bundle();
+        expectedRequestData.putString(expectedRequestKey, expectedRequestValue);
+        boolean expectedRequireSystemProvider = true;
+        Set<ComponentName> expectedAllowedProviders = ImmutableSet.of(
+                new ComponentName("pkg", "cls"),
+                new ComponentName("pkg2", "cls2")
+        );
+
+        ProviderGetCredentialRequest providerGetCredentialRequest =
+                new ProviderGetCredentialRequest(
+                        Collections.singletonList(CredentialOption.createFrom(expectedType,
+                                expectedRequestData,
+                                expectedCandidateQueryData,
+                                expectedRequireSystemProvider,
+                                expectedAllowedProviders)),
+                        new CallingAppInfo("name",
+                                new SigningInfo()));
+        List<CredentialOption> actualCredentialOptionsList =
+                providerGetCredentialRequest.getCredentialOptions();
+        assertThat(actualCredentialOptionsList.size()).isEqualTo(1);
+        String actualType = actualCredentialOptionsList.get(0).getType();
+        String actualRequestValue =
+                actualCredentialOptionsList.get(0).getRequestData().getString(expectedRequestKey);
+        String actualQueryValue =
+                actualCredentialOptionsList.get(0).getCandidateQueryData()
+                        .getString(expectedQueryKey);
+        boolean actualRequireSystemProvider =
+                actualCredentialOptionsList.get(0).isSystemProviderRequired();
+
+        assertThat(actualType).isEqualTo(expectedType);
+        assertThat(actualRequestValue).isEqualTo(expectedRequestValue);
+        assertThat(actualQueryValue).isEqualTo(expectedQueryValue);
+        assertThat(actualRequireSystemProvider).isEqualTo(expectedRequireSystemProvider);
+        assertThat(actualCredentialOptionsList.get(0).getAllowedProviders())
+                .containsAtLeastElementsIn(expectedAllowedProviders);
+    }
+
+    @Test
+    public void getter_signingInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        String expectedPackageName = "cool.security.package";
+
+        ProviderGetCredentialRequest providerGetCredentialRequest =
+                new ProviderGetCredentialRequest(
+                        Collections.singletonList(CredentialOption.createFrom("type", new Bundle(),
+                                new Bundle(), true, ImmutableSet.of())),
+                        new CallingAppInfo(expectedPackageName,
+                        new SigningInfo()));
+        String actualPackageName =
+                providerGetCredentialRequest.getCallingAppInfo().getPackageName();
+
+        assertThat(actualPackageName).isEqualTo(expectedPackageName);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestTest.kt
new file mode 100644
index 0000000..a3f21fe
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ProviderGetCredentialRequestTest.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.credentials.provider
+
+import android.content.ComponentName
+import android.content.pm.SigningInfo
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.credentials.CredentialOption.Companion.createFrom
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ProviderGetCredentialRequestTest {
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+
+        ProviderGetCredentialRequest(
+            listOf(
+                createFrom(
+                    "type", Bundle(),
+                    Bundle(), true,
+                    emptySet()
+                )
+            ), CallingAppInfo(
+                "name",
+                SigningInfo()
+            )
+        )
+    }
+
+    // TODO(b/275416815) - Test createFrom()
+
+    @Test
+    fun getter_credentialOptions() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedType = "BoeingCred"
+        val expectedQueryKey = "PilotName"
+        val expectedQueryValue = "PilotPassword"
+        val expectedCandidateQueryData = Bundle()
+        expectedCandidateQueryData.putString(expectedQueryKey, expectedQueryValue)
+        val expectedRequestKey = "PlaneKey"
+        val expectedRequestValue = "PlaneInfo"
+        val expectedRequestData = Bundle()
+        expectedRequestData.putString(expectedRequestKey, expectedRequestValue)
+        val expectedRequireSystemProvider = true
+        val expectedAllowedProviders: Set<ComponentName> = setOf(
+            ComponentName("pkg", "cls"),
+            ComponentName("pkg2", "cls2")
+        )
+
+        val providerGetCredentialRequest = ProviderGetCredentialRequest(
+            listOf(
+                createFrom(
+                    expectedType,
+                    expectedRequestData,
+                    expectedCandidateQueryData,
+                    expectedRequireSystemProvider,
+                    expectedAllowedProviders
+                )
+            ),
+            CallingAppInfo(
+                "name",
+                SigningInfo()
+            )
+        )
+        val actualCredentialOptionsList = providerGetCredentialRequest.credentialOptions
+        assertThat(actualCredentialOptionsList.size).isEqualTo(1)
+        val actualType = actualCredentialOptionsList[0].type
+        val actualRequestValue =
+            actualCredentialOptionsList[0].requestData.getString(expectedRequestKey)
+        val actualQueryValue = actualCredentialOptionsList[0].candidateQueryData
+            .getString(expectedQueryKey)
+        val actualRequireSystemProvider = actualCredentialOptionsList[0].isSystemProviderRequired
+
+        assertThat(actualType).isEqualTo(expectedType)
+        assertThat(actualRequestValue).isEqualTo(expectedRequestValue)
+        assertThat(actualQueryValue).isEqualTo(expectedQueryValue)
+        assertThat(actualRequireSystemProvider).isEqualTo(expectedRequireSystemProvider)
+        assertThat(actualCredentialOptionsList[0].allowedProviders)
+            .containsAtLeastElementsIn(expectedAllowedProviders)
+    }
+
+    @Test
+    fun getter_signingInfo() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val expectedPackageName = "cool.security.package"
+
+        val providerGetCredentialRequest = ProviderGetCredentialRequest(
+            listOf(
+                createFrom(
+                    "type", Bundle(),
+                    Bundle(), true, emptySet()
+                )
+            ), CallingAppInfo(
+                expectedPackageName,
+                SigningInfo()
+            )
+        )
+        val actualPackageName = providerGetCredentialRequest.callingAppInfo.packageName
+
+        assertThat(actualPackageName).isEqualTo(expectedPackageName)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionJavaTest.java
new file mode 100644
index 0000000..d0bc879
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionJavaTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.app.slice.Slice;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.provider.Action;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class ActionJavaTest {
+    private static final CharSequence TITLE = "title";
+    private static final CharSequence SUBTITLE = "subtitle";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        Action action = new Action(TITLE, mPendingIntent, SUBTITLE);
+
+        assertNotNull(action);
+        assertThat(TITLE.equals(action.getTitle()));
+        assertThat(SUBTITLE.equals(action.getSubtitle()));
+        assertThat(mPendingIntent == action.getPendingIntent());
+    }
+
+    @Test
+    public void constructor_nullTitle_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null title to throw NPE",
+                NullPointerException.class,
+                () -> new Action(null, mPendingIntent, SUBTITLE));
+    }
+
+    @Test
+    public void constructor_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null title to throw NPE",
+                NullPointerException.class,
+                () -> new Action(TITLE, null, SUBTITLE));
+    }
+
+    @Test
+    public void constructor_emptyTitle_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty title to throw IllegalArgumentException",
+                IllegalArgumentException.class,
+                () -> new Action("", mPendingIntent, SUBTITLE));
+    }
+
+    @Test
+    public void fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        Action originalAction = new Action(TITLE, mPendingIntent, SUBTITLE);
+        Slice slice = Action.toSlice(originalAction);
+
+        Action fromSlice = Action.fromSlice(slice);
+
+        assertNotNull(fromSlice);
+        assertThat(fromSlice.getTitle()).isEqualTo(TITLE);
+        assertThat(fromSlice.getSubtitle()).isEqualTo(SUBTITLE);
+        assertThat(fromSlice.getPendingIntent()).isEqualTo(mPendingIntent);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionTest.kt
new file mode 100644
index 0000000..c075468
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/ActionTest.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.Action.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Assert.assertNotNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+class ActionTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE)
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val action = Action(TITLE, mPendingIntent, SUBTITLE)
+        val slice = Action.toSlice(action)
+
+        assertNotNull(action)
+        assertNotNull(slice)
+        assertThat(TITLE == action.title)
+        assertThat(SUBTITLE == action.subtitle)
+        assertThat(mPendingIntent === action.pendingIntent)
+    }
+
+    @Test
+    fun constructor_emptyTitle_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty title to throw IllegalArgumentException",
+            IllegalArgumentException::class.java
+        ) { Action("", mPendingIntent, SUBTITLE) }
+    }
+
+    @Test
+    fun fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalAction = Action(TITLE, mPendingIntent, SUBTITLE)
+        val slice = Action.toSlice(originalAction)
+
+        val fromSlice = fromSlice(slice)
+
+        assertNotNull(fromSlice)
+        fromSlice?.let {
+            assertThat(fromSlice.title).isEqualTo(TITLE)
+            assertThat(fromSlice.subtitle).isEqualTo(SUBTITLE)
+            assertThat(fromSlice.pendingIntent).isEqualTo(mPendingIntent)
+        }
+    }
+
+    companion object {
+        private val TITLE: CharSequence = "title"
+        private val SUBTITLE: CharSequence = "subtitle"
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionJavaTest.java
new file mode 100644
index 0000000..e1c6a5d
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionJavaTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.app.slice.Slice;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.provider.AuthenticationAction;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class AuthenticationActionJavaTest {
+    private static final CharSequence TITLE = "title";
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent, PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        AuthenticationAction action = new AuthenticationAction(TITLE, mPendingIntent);
+
+        assertThat(mPendingIntent == action.getPendingIntent());
+    }
+
+    @Test
+    public void build_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        AuthenticationAction action =
+                new AuthenticationAction.Builder(TITLE, mPendingIntent).build();
+
+        assertThat(mPendingIntent == action.getPendingIntent());
+    }
+
+    @Test
+    public void constructor_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new AuthenticationAction(TITLE, null));
+    }
+
+    @Test
+    public void constructor_emptyTitle_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty title to throw IAE",
+                IllegalArgumentException.class,
+                () -> new AuthenticationAction("", mPendingIntent));
+    }
+
+    @Test
+    public void fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        AuthenticationAction originalAction = new AuthenticationAction(TITLE, mPendingIntent);
+        Slice slice = AuthenticationAction.toSlice(originalAction);
+
+        AuthenticationAction fromSlice = AuthenticationAction.fromSlice(slice);
+
+        assertNotNull(fromSlice);
+        assertThat(fromSlice.getPendingIntent()).isEqualTo(mPendingIntent);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionTest.kt
new file mode 100644
index 0000000..a4377fe
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/AuthenticationActionTest.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.AuthenticationAction.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
+import org.junit.Assert.assertNotNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+class AuthenticationActionTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE)
+
+    @Test
+    fun build_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val action = AuthenticationAction.Builder(TITLE, mPendingIntent).build()
+
+        assertThat(mPendingIntent).isEqualTo(action.pendingIntent)
+    }
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val action = AuthenticationAction(TITLE, mPendingIntent)
+
+        assertThat(mPendingIntent).isEqualTo(action.pendingIntent)
+    }
+
+    @Test
+    fun constructor_emptyTitle_throwsIllegalArgumentException() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty title to throw IAE",
+            IllegalArgumentException::class.java
+        ) { AuthenticationAction("", mPendingIntent) }
+    }
+
+    @Test
+    fun fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalAction = AuthenticationAction(TITLE, mPendingIntent)
+        val slice = AuthenticationAction.toSlice(originalAction)
+
+        val fromSlice = fromSlice(slice)
+
+        assertNotNull(fromSlice)
+        fromSlice?.let {
+            assertNotNull(fromSlice.pendingIntent)
+            assertThat(fromSlice.pendingIntent).isEqualTo(mPendingIntent)
+        }
+    }
+
+    companion object {
+        private val TITLE: CharSequence = "title"
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryJavaTest.java
new file mode 100644
index 0000000..f2992da
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryJavaTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.provider.CreateEntry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class CreateEntryJavaTest {
+    private static final CharSequence ACCOUNT_NAME = "account_name";
+    private static final int PASSWORD_COUNT = 10;
+    private static final int PUBLIC_KEY_CREDENTIAL_COUNT = 10;
+    private static final int TOTAL_COUNT = 10;
+
+    private static final Long LAST_USED_TIME = 10L;
+    private static final Icon ICON = Icon.createWithBitmap(Bitmap.createBitmap(
+            100, 100, Bitmap.Config.ARGB_8888));
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void constructor_requiredParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CreateEntry entry = constructEntryWithRequiredParams();
+
+        assertNotNull(entry);
+        assertEntryWithRequiredParams(entry);
+        assertNull(entry.getIcon());
+        assertNull(entry.getLastUsedTime());
+        assertNull(entry.getPasswordCredentialCount());
+        assertNull(entry.getPublicKeyCredentialCount());
+        assertNull(entry.getTotalCredentialCount());
+    }
+
+    @Test
+    public void constructor_allParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CreateEntry entry = constructEntryWithAllParams();
+
+        assertNotNull(entry);
+        assertEntryWithAllParams(entry);
+    }
+
+    @Test
+    public void constructor_nullAccountName_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null title to throw NPE",
+                NullPointerException.class,
+                () -> new CreateEntry.Builder(
+                        null, mPendingIntent).build());
+    }
+
+    @Test
+    public void constructor_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new CreateEntry.Builder(ACCOUNT_NAME, null).build());
+    }
+
+    @Test
+    public void constructor_emptyAccountName_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty account name to throw NPE",
+                IllegalArgumentException.class,
+                () -> new CreateEntry.Builder("", mPendingIntent).build());
+    }
+
+    @Test
+    public void fromSlice_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CreateEntry originalEntry = constructEntryWithRequiredParams();
+
+        CreateEntry entry = CreateEntry.fromSlice(
+                CreateEntry.toSlice(originalEntry));
+
+        assertNotNull(entry);
+        assertEntryWithRequiredParams(entry);
+    }
+
+    @Test
+    public void fromSlice_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CreateEntry originalEntry = constructEntryWithAllParams();
+
+        CreateEntry entry = CreateEntry.fromSlice(
+                CreateEntry.toSlice(originalEntry));
+
+        assertNotNull(entry);
+        assertEntryWithAllParams(entry);
+    }
+
+    private CreateEntry constructEntryWithRequiredParams() {
+        return new CreateEntry.Builder(ACCOUNT_NAME, mPendingIntent).build();
+    }
+
+    private void assertEntryWithRequiredParams(CreateEntry entry) {
+        assertThat(ACCOUNT_NAME.equals(entry.getAccountName()));
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    private CreateEntry constructEntryWithAllParams() {
+        return new CreateEntry.Builder(
+                ACCOUNT_NAME,
+                mPendingIntent)
+                .setIcon(ICON)
+                .setLastUsedTime(Instant.ofEpochMilli(LAST_USED_TIME))
+                .setPasswordCredentialCount(PASSWORD_COUNT)
+                .setPublicKeyCredentialCount(PUBLIC_KEY_CREDENTIAL_COUNT)
+                .setTotalCredentialCount(TOTAL_COUNT)
+                .build();
+    }
+
+    private void assertEntryWithAllParams(CreateEntry entry) {
+        assertThat(ACCOUNT_NAME).isEqualTo(entry.getAccountName());
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+        assertThat(ICON).isEqualTo(entry.getIcon());
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.getLastUsedTime());
+        assertThat(PASSWORD_COUNT).isEqualTo(entry.getPasswordCredentialCount());
+        assertThat(PUBLIC_KEY_CREDENTIAL_COUNT).isEqualTo(entry.getPublicKeyCredentialCount());
+        assertThat(TOTAL_COUNT).isEqualTo(entry.getTotalCredentialCount());
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryTest.kt
new file mode 100644
index 0000000..13417bd
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CreateEntryTest.kt
@@ -0,0 +1,202 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.CreateEntry.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth
+import java.time.Instant
+import org.junit.Assert
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class CreateEntryTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(
+        mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE
+    )
+
+    @Test
+    fun constructor_success_autoSelectDefaultFalse() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParams()
+
+        assertNotNull(entry)
+        assertEntryWithRequiredParams(entry)
+        assertNull(entry.icon)
+        assertNull(entry.lastUsedTime)
+        assertNull(entry.getPasswordCredentialCount())
+        assertNull(entry.getPublicKeyCredentialCount())
+        assertNull(entry.getTotalCredentialCount())
+        assertFalse(entry.isAutoSelectAllowed)
+    }
+
+    @Test
+    fun constructor_requiredParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParams()
+
+        assertNotNull(entry)
+        assertEntryWithRequiredParams(entry)
+        assertNull(entry.icon)
+        assertNull(entry.lastUsedTime)
+        assertNull(entry.getPasswordCredentialCount())
+        assertNull(entry.getPublicKeyCredentialCount())
+        assertNull(entry.getTotalCredentialCount())
+    }
+
+    @Test
+    fun constructor_allParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithAllParams()
+
+        assertNotNull(entry)
+        assertEntryWithAllParams(entry)
+    }
+
+    @Test
+    fun constructor_emptyAccountName_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        Assert.assertThrows(
+            "Expected empty account name to throw NPE",
+            IllegalArgumentException::class.java
+        ) {
+            CreateEntry(
+                "", mPendingIntent
+            )
+        }
+    }
+
+    @Test
+    fun fromSlice_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructEntryWithRequiredParams()
+
+        val entry = fromSlice(CreateEntry.toSlice(originalEntry))
+
+        assertNotNull(entry)
+        entry?.let {
+            assertEntryWithRequiredParams(entry)
+        }
+    }
+
+    @Test
+    fun fromSlice_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructEntryWithAllParams()
+
+        val entry = fromSlice(CreateEntry.toSlice(originalEntry))
+
+        assertNotNull(entry)
+        entry?.let {
+            assertEntryWithAllParams(entry)
+        }
+    }
+
+    private fun constructEntryWithRequiredParams(): CreateEntry {
+        return CreateEntry(
+            ACCOUNT_NAME,
+            mPendingIntent
+        )
+    }
+
+    private fun assertEntryWithRequiredParams(entry: CreateEntry) {
+        Truth.assertThat(ACCOUNT_NAME == entry.accountName)
+        Truth.assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    private fun constructEntryWithAllParams(): CreateEntry {
+        return CreateEntry(
+            ACCOUNT_NAME,
+            mPendingIntent,
+            DESCRIPTION,
+            Instant.ofEpochMilli(LAST_USED_TIME),
+            ICON,
+            PASSWORD_COUNT,
+            PUBLIC_KEY_CREDENTIAL_COUNT,
+            TOTAL_COUNT,
+            AUTO_SELECT_BIT
+        )
+    }
+
+    private fun assertEntryWithAllParams(entry: CreateEntry) {
+        Truth.assertThat(ACCOUNT_NAME).isEqualTo(
+            entry.accountName
+        )
+        Truth.assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+        Truth.assertThat(ICON).isEqualTo(
+            entry.icon
+        )
+        Truth.assertThat(LAST_USED_TIME).isEqualTo(
+            entry.lastUsedTime?.toEpochMilli()
+        )
+        Truth.assertThat(PASSWORD_COUNT).isEqualTo(
+            entry.getPasswordCredentialCount()
+        )
+        Truth.assertThat(PUBLIC_KEY_CREDENTIAL_COUNT).isEqualTo(
+            entry.getPublicKeyCredentialCount()
+        )
+        Truth.assertThat(TOTAL_COUNT).isEqualTo(
+            entry.getTotalCredentialCount()
+        )
+        Truth.assertThat(AUTO_SELECT_BIT).isTrue()
+    }
+
+    companion object {
+        private val ACCOUNT_NAME: CharSequence = "account_name"
+        private const val DESCRIPTION = "description"
+        private const val PASSWORD_COUNT = 10
+        private const val PUBLIC_KEY_CREDENTIAL_COUNT = 10
+        private const val TOTAL_COUNT = 10
+        private const val AUTO_SELECT_BIT = true
+        private const val LAST_USED_TIME = 10L
+        private val ICON = Icon.createWithBitmap(
+            Bitmap.createBitmap(
+                100, 100, Bitmap.Config.ARGB_8888
+            )
+        )
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryJavaTest.java
new file mode 100644
index 0000000..41bba92
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryJavaTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.R;
+import androidx.credentials.TestUtilsKt;
+import androidx.credentials.provider.BeginGetCredentialOption;
+import androidx.credentials.provider.BeginGetCustomCredentialOption;
+import androidx.credentials.provider.CustomCredentialEntry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class CustomCredentialEntryJavaTest {
+    private static final CharSequence TITLE = "title";
+    private static final CharSequence SUBTITLE = "subtitle";
+
+    private static final String TYPE = "custom_type";
+    private static final CharSequence TYPE_DISPLAY_NAME = "Password";
+    private static final Long LAST_USED_TIME = 10L;
+    private static final Icon ICON = Icon.createWithBitmap(Bitmap.createBitmap(
+            100, 100, Bitmap.Config.ARGB_8888));
+    private static final boolean IS_AUTO_SELECT_ALLOWED = true;
+    private final BeginGetCredentialOption mBeginCredentialOption =
+            new BeginGetCustomCredentialOption(
+            "id", "custom", new Bundle());
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void build_requiredParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CustomCredentialEntry entry = constructEntryWithRequiredParams();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertEntryWithRequiredParams(entry);
+    }
+
+    @Test
+    public void build_allParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CustomCredentialEntry entry = constructEntryWithAllParams();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertEntryWithAllParams(entry);
+    }
+
+    @Test
+    public void build_nullTitle_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null title to throw NPE",
+                NullPointerException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        mContext, TYPE, null, mPendingIntent, mBeginCredentialOption
+                ));
+    }
+
+    @Test
+    public void build_nullContext_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null title to throw NPE",
+                NullPointerException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        null, TYPE, TITLE, mPendingIntent, mBeginCredentialOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        mContext, TYPE, TITLE, null, mBeginCredentialOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullBeginOption_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null option to throw NPE",
+                NullPointerException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        mContext, TYPE, TITLE, mPendingIntent, null
+                ).build());
+    }
+
+    @Test
+    public void build_emptyTitle_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty title to throw IAE",
+                IllegalArgumentException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        mContext, TYPE, "", mPendingIntent, mBeginCredentialOption
+                ).build());
+    }
+
+    @Test
+    public void build_emptyType_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty type to throw NPE",
+                IllegalArgumentException.class,
+                () -> new CustomCredentialEntry.Builder(
+                        mContext, "", TITLE, mPendingIntent, mBeginCredentialOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CustomCredentialEntry entry = constructEntryWithRequiredParams();
+
+        assertThat(TestUtilsKt.equals(entry.getIcon(),
+                Icon.createWithResource(mContext, R.drawable.ic_other_sign_in))).isTrue();
+    }
+
+    @Test
+    public void fromSlice_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CustomCredentialEntry originalEntry = constructEntryWithRequiredParams();
+
+        CustomCredentialEntry entry = CustomCredentialEntry.fromSlice(
+                originalEntry.getSlice());
+
+        assertNotNull(entry);
+        assertEntryWithRequiredParamsFromSlice(entry);
+    }
+
+    @Test
+    public void fromSlice_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        CustomCredentialEntry originalEntry = constructEntryWithAllParams();
+
+        CustomCredentialEntry entry = CustomCredentialEntry.fromSlice(
+                originalEntry.getSlice());
+
+        assertNotNull(entry);
+        assertEntryWithAllParamsFromSlice(entry);
+    }
+
+    private CustomCredentialEntry constructEntryWithRequiredParams() {
+        return new CustomCredentialEntry.Builder(
+                mContext,
+                TYPE,
+                TITLE,
+                mPendingIntent,
+                mBeginCredentialOption
+        ).build();
+    }
+
+    private CustomCredentialEntry constructEntryWithAllParams() {
+        return new CustomCredentialEntry.Builder(
+                mContext,
+                TYPE,
+                TITLE,
+                mPendingIntent,
+                mBeginCredentialOption)
+                .setIcon(ICON)
+                .setLastUsedTime(Instant.ofEpochMilli(LAST_USED_TIME))
+                .setAutoSelectAllowed(IS_AUTO_SELECT_ALLOWED)
+                .setTypeDisplayName(TYPE_DISPLAY_NAME)
+                .build();
+    }
+
+    private void assertEntryWithRequiredParams(CustomCredentialEntry entry) {
+        assertThat(TITLE.equals(entry.getTitle()));
+        assertThat(TYPE.equals(entry.getType()));
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    private void assertEntryWithRequiredParamsFromSlice(CustomCredentialEntry entry) {
+        assertThat(TITLE.equals(entry.getTitle()));
+        assertThat(TYPE.equals(entry.getType()));
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    private void assertEntryWithAllParams(CustomCredentialEntry entry) {
+        assertThat(TITLE.equals(entry.getTitle()));
+        assertThat(TYPE.equals(entry.getType()));
+        assertThat(SUBTITLE.equals(entry.getSubtitle()));
+        assertThat(TYPE_DISPLAY_NAME.equals(entry.getTypeDisplayName()));
+        assertThat(ICON).isEqualTo(entry.getIcon());
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.getLastUsedTime());
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed());
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+        // TODO: Assert BeginOption
+    }
+
+    private void assertEntryWithAllParamsFromSlice(CustomCredentialEntry entry) {
+        assertThat(TITLE.equals(entry.getTitle()));
+        assertThat(TYPE.equals(entry.getType()));
+        assertThat(SUBTITLE.equals(entry.getSubtitle()));
+        assertThat(TYPE_DISPLAY_NAME.equals(entry.getTypeDisplayName()));
+        assertThat(ICON).isEqualTo(entry.getIcon());
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.getLastUsedTime());
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed());
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+        // TODO: Assert BeginOption
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryTest.kt
new file mode 100644
index 0000000..80a9a2c1
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/CustomCredentialEntryTest.kt
@@ -0,0 +1,237 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.credentials.R
+import androidx.credentials.equals
+import androidx.credentials.provider.BeginGetCredentialOption
+import androidx.credentials.provider.BeginGetCustomCredentialOption
+import androidx.credentials.provider.CustomCredentialEntry
+import androidx.credentials.provider.CustomCredentialEntry.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.time.Instant
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class CustomCredentialEntryTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE)
+    @Test
+    fun constructor_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParams()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertEntryWithRequiredParams(entry)
+    }
+
+    @Test
+    fun constructor_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithAllParams()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertEntryWithAllParams(entry)
+    }
+
+    @Test
+    fun constructor_allParameters_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry: CustomCredentialEntry = constructEntryWithAllParams()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertEntryWithAllParams(entry)
+    }
+
+    @Test
+    fun constructor_emptyTitle_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        assertThrows(
+            "Expected empty title to throw NPE",
+            IllegalArgumentException::class.java
+        ) {
+            CustomCredentialEntry(
+                mContext, TITLE, mPendingIntent, BeginGetCustomCredentialOption(
+                    "id", "", Bundle.EMPTY
+                )
+            )
+        }
+    }
+
+    @Test
+    fun constructor_emptyType_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        assertThrows(
+            "Expected empty type to throw NPE",
+            IllegalArgumentException::class.java
+        ) {
+            CustomCredentialEntry(
+                mContext, TITLE, mPendingIntent, BeginGetCustomCredentialOption(
+                    "id", "", Bundle.EMPTY)
+            )
+        }
+    }
+
+    @Test
+    fun constructor_nullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParams()
+
+        assertThat(
+            equals(
+                entry.icon,
+                Icon.createWithResource(mContext, R.drawable.ic_other_sign_in)
+            )
+        ).isTrue()
+    }
+
+    @Test
+    fun fromSlice_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructEntryWithRequiredParams()
+
+        val entry = fromSlice(originalEntry.slice)
+
+        assertNotNull(entry)
+        if (entry != null) {
+            assertEntryWithRequiredParamsFromSlice(entry)
+        }
+    }
+
+    @Test
+    fun fromSlice_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructEntryWithAllParams()
+
+        val entry = fromSlice(originalEntry.slice)
+
+        assertNotNull(entry)
+        if (entry != null) {
+            assertEntryWithAllParamsFromSlice(entry)
+        }
+    }
+
+    private fun constructEntryWithRequiredParams(): CustomCredentialEntry {
+        return CustomCredentialEntry(
+            mContext,
+            TITLE,
+            mPendingIntent,
+            BEGIN_OPTION
+        )
+    }
+
+    private fun constructEntryWithAllParams(): CustomCredentialEntry {
+        return CustomCredentialEntry(
+            mContext,
+            TITLE,
+            mPendingIntent,
+            BEGIN_OPTION,
+            SUBTITLE,
+            TYPE_DISPLAY_NAME,
+            Instant.ofEpochMilli(LAST_USED_TIME),
+            ICON,
+            IS_AUTO_SELECT_ALLOWED
+        )
+    }
+
+    private fun assertEntryWithAllParams(entry: CustomCredentialEntry) {
+        assertThat(TITLE == entry.title)
+        assertThat(TYPE == entry.type)
+        assertThat(SUBTITLE == entry.subtitle)
+        assertThat(TYPE_DISPLAY_NAME == entry.typeDisplayName)
+        assertThat(ICON).isEqualTo(entry.icon)
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.lastUsedTime)
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    private fun assertEntryWithAllParamsFromSlice(entry: CustomCredentialEntry) {
+        assertThat(TITLE == entry.title)
+        assertThat(TYPE == entry.type)
+        assertThat(SUBTITLE == entry.subtitle)
+        assertThat(TYPE_DISPLAY_NAME == entry.typeDisplayName)
+        assertThat(ICON).isEqualTo(entry.icon)
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.lastUsedTime)
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+        // TODO: Assert BeginOption
+    }
+
+    private fun assertEntryWithRequiredParams(entry: CustomCredentialEntry) {
+        assertThat(TITLE == entry.title)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+        // TODO: Assert BeginOption
+    }
+
+    private fun assertEntryWithRequiredParamsFromSlice(entry: CustomCredentialEntry) {
+        assertThat(TITLE == entry.title)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+        // TODO: Assert BeginOption
+    }
+
+    companion object {
+        private val TITLE: CharSequence = "title"
+        private val BEGIN_OPTION: BeginGetCredentialOption = BeginGetCustomCredentialOption(
+            "id", "type", Bundle())
+        private val SUBTITLE: CharSequence = "subtitle"
+        private const val TYPE = "custom_type"
+        private val TYPE_DISPLAY_NAME: CharSequence = "Password"
+        private const val LAST_USED_TIME: Long = 10L
+        private val ICON = Icon.createWithBitmap(
+            Bitmap.createBitmap(
+                100, 100, Bitmap.Config.ARGB_8888
+            )
+        )
+        private const val IS_AUTO_SELECT_ALLOWED = true
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryJavaTest.java
new file mode 100644
index 0000000..94e2caa
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryJavaTest.java
@@ -0,0 +1,261 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.PasswordCredential;
+import androidx.credentials.R;
+import androidx.credentials.TestUtilsKt;
+import androidx.credentials.provider.BeginGetPasswordOption;
+import androidx.credentials.provider.PasswordCredentialEntry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+import java.util.HashSet;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class PasswordCredentialEntryJavaTest {
+    private static final CharSequence USERNAME = "title";
+    private static final CharSequence DISPLAYNAME = "subtitle";
+    private static final CharSequence TYPE_DISPLAY_NAME = "Password";
+    private static final Long LAST_USED_TIME = 10L;
+
+    private static final boolean IS_AUTO_SELECT_ALLOWED = true;
+
+    private static final Icon ICON = Icon.createWithBitmap(Bitmap.createBitmap(
+            100, 100, Bitmap.Config.ARGB_8888));
+    private final BeginGetPasswordOption mBeginGetPasswordOption = new BeginGetPasswordOption(
+            new HashSet<>(),
+            Bundle.EMPTY, "id");
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void build_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry entry = constructEntryWithRequiredParamsOnly();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertThat(entry.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertEntryWithRequiredParamsOnly(entry, false);
+    }
+
+    @Test
+    public void build_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry entry = constructEntryWithAllParams();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertThat(entry.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertEntryWithAllParams(entry);
+    }
+
+    @Test
+    public void build_nullContext_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null context to throw NPE",
+                NullPointerException.class,
+                () -> new PasswordCredentialEntry.Builder(
+                        null, USERNAME, mPendingIntent, mBeginGetPasswordOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullUsername_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null username to throw NPE",
+                NullPointerException.class,
+                () -> new PasswordCredentialEntry.Builder(
+                        mContext, null, mPendingIntent, mBeginGetPasswordOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new PasswordCredentialEntry.Builder(
+                        mContext, USERNAME, null, mBeginGetPasswordOption
+                ).build());
+    }
+
+    @Test
+    public void build_nullBeginOption_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null option to throw NPE",
+                NullPointerException.class,
+                () -> new PasswordCredentialEntry.Builder(
+                        mContext, USERNAME, mPendingIntent, null
+                ).build());
+    }
+
+    @Test
+    public void build_emptyUsername_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty username to throw IllegalArgumentException",
+                IllegalArgumentException.class,
+                () -> new PasswordCredentialEntry.Builder(
+                        mContext, "", mPendingIntent, mBeginGetPasswordOption).build());
+    }
+
+    @Test
+    public void build_nullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry entry = new PasswordCredentialEntry
+                .Builder(mContext, USERNAME, mPendingIntent, mBeginGetPasswordOption).build();
+
+        assertThat(TestUtilsKt.equals(entry.getIcon(),
+                Icon.createWithResource(mContext, R.drawable.ic_password))).isTrue();
+    }
+
+    @Test
+    public void build_nullTypeDisplayName_defaultDisplayNameSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry entry = new PasswordCredentialEntry.Builder(
+                        mContext, USERNAME, mPendingIntent, mBeginGetPasswordOption).build();
+
+        assertThat(entry.getTypeDisplayName()).isEqualTo(
+                mContext.getString(
+                        R.string.android_credentials_TYPE_PASSWORD_CREDENTIAL)
+        );
+    }
+
+    @Test
+    public void build_isAutoSelectAllowedDefault_false() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry entry = constructEntryWithRequiredParamsOnly();
+
+        assertFalse(entry.isAutoSelectAllowed());
+    }
+
+    @Test
+    public void fromSlice_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry originalEntry = constructEntryWithRequiredParamsOnly();
+
+        assertNotNull(originalEntry.getSlice());
+        PasswordCredentialEntry entry = PasswordCredentialEntry.fromSlice(
+                originalEntry.getSlice());
+
+        assertNotNull(entry);
+        assertEntryWithRequiredParamsOnly(entry, true);
+    }
+
+    @Test
+    public void fromSlice_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PasswordCredentialEntry originalEntry = constructEntryWithAllParams();
+
+        assertNotNull(originalEntry.getSlice());
+        PasswordCredentialEntry entry = PasswordCredentialEntry.fromSlice(
+                originalEntry.getSlice());
+
+        assertNotNull(entry);
+        assertEntryWithAllParams(entry);
+    }
+
+    private PasswordCredentialEntry constructEntryWithRequiredParamsOnly() {
+        return new PasswordCredentialEntry.Builder(
+                mContext,
+                USERNAME,
+                mPendingIntent,
+                mBeginGetPasswordOption).build();
+    }
+
+    private PasswordCredentialEntry constructEntryWithAllParams() {
+        return new PasswordCredentialEntry.Builder(
+                mContext,
+                USERNAME,
+                mPendingIntent,
+                mBeginGetPasswordOption)
+                .setDisplayName(DISPLAYNAME)
+                .setLastUsedTime(Instant.ofEpochMilli(LAST_USED_TIME))
+                .setIcon(ICON)
+                .setAutoSelectAllowed(IS_AUTO_SELECT_ALLOWED)
+                .build();
+    }
+
+    private void assertEntryWithRequiredParamsOnly(PasswordCredentialEntry entry,
+            Boolean assertOptionIdOnly) {
+        assertThat(USERNAME.equals(entry.getUsername()));
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+        // TODO: Assert BeginOption
+    }
+
+    private void assertEntryWithAllParams(PasswordCredentialEntry entry) {
+        assertThat(USERNAME.equals(entry.getUsername()));
+        assertThat(DISPLAYNAME.equals(entry.getDisplayName()));
+        assertThat(TYPE_DISPLAY_NAME.equals(entry.getTypeDisplayName()));
+        assertThat(ICON).isEqualTo(entry.getIcon());
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed());
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.getLastUsedTime());
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+        // TODO: Assert BeginOption
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryTest.kt
new file mode 100644
index 0000000..6c86911
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PasswordCredentialEntryTest.kt
@@ -0,0 +1,206 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.credentials.PasswordCredential
+import androidx.credentials.R
+import androidx.credentials.equals
+import androidx.credentials.provider.BeginGetPasswordOption
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.time.Instant
+import junit.framework.TestCase.assertFalse
+import junit.framework.TestCase.assertNotNull
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class PasswordCredentialEntryTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(
+        mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE
+    )
+
+    @Test
+    fun constructor_requiredParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParamsOnly()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertThat(entry.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        assertEntryWithRequiredParamsOnly(entry)
+    }
+
+    @Test
+    fun constructor_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithAllParams()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertThat(entry.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        assertEntryWithAllParams(entry)
+    }
+
+    @Test
+    fun constructor_emptyUsername_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        assertThrows(
+            "Expected empty username to throw IllegalArgumentException",
+            IllegalArgumentException::class.java
+        ) {
+            PasswordCredentialEntry(
+                mContext, "", mPendingIntent, BEGIN_OPTION
+            )
+        }
+    }
+
+    @Test
+    fun constructor_nullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = PasswordCredentialEntry.Builder(
+            mContext, USERNAME, mPendingIntent, BEGIN_OPTION).build()
+
+        assertThat(
+            equals(
+                entry.icon,
+                Icon.createWithResource(mContext, R.drawable.ic_password)
+            )
+        ).isTrue()
+    }
+
+    @Test
+    fun constructor_nullTypeDisplayName_defaultDisplayNameSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = PasswordCredentialEntry(
+            mContext, USERNAME, mPendingIntent, BEGIN_OPTION)
+
+        assertThat(entry.typeDisplayName).isEqualTo(
+            mContext.getString(
+                R.string.android_credentials_TYPE_PASSWORD_CREDENTIAL
+            )
+        )
+    }
+
+    @Test
+    fun constructor_isAutoSelectAllowedDefault_false() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructEntryWithRequiredParamsOnly()
+        val entry1 = constructEntryWithAllParams()
+
+        assertFalse(entry.isAutoSelectAllowed)
+        assertFalse(entry1.isAutoSelectAllowed)
+    }
+
+    @Test
+    fun fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructEntryWithAllParams()
+
+        val entry = fromSlice(originalEntry.slice)
+
+        assertNotNull(entry)
+        entry?.let {
+            assertEntryWithAllParams(entry)
+        }
+    }
+
+    private fun constructEntryWithRequiredParamsOnly(): PasswordCredentialEntry {
+        return PasswordCredentialEntry(
+            mContext,
+            USERNAME,
+            mPendingIntent,
+            BEGIN_OPTION
+        )
+    }
+
+    private fun constructEntryWithAllParams(): PasswordCredentialEntry {
+        return PasswordCredentialEntry(
+            mContext,
+            USERNAME,
+            mPendingIntent,
+            BEGIN_OPTION,
+            DISPLAYNAME,
+            LAST_USED_TIME,
+            ICON
+        )
+    }
+
+    private fun assertEntryWithRequiredParamsOnly(entry: PasswordCredentialEntry) {
+        assertThat(USERNAME == entry.username)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    private fun assertEntryWithAllParams(entry: PasswordCredentialEntry) {
+        assertThat(USERNAME == entry.username)
+        assertThat(DISPLAYNAME == entry.displayName)
+        assertThat(TYPE_DISPLAY_NAME == entry.typeDisplayName)
+        assertThat(ICON).isEqualTo(entry.icon)
+        assertNotNull(entry.lastUsedTime)
+        entry.lastUsedTime?.let {
+            assertThat(LAST_USED_TIME.toEpochMilli()).isEqualTo(
+                it.toEpochMilli())
+        }
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    companion object {
+        private val USERNAME: CharSequence = "title"
+        private val DISPLAYNAME: CharSequence = "subtitle"
+        private val TYPE_DISPLAY_NAME: CharSequence = "Password"
+        private val LAST_USED_TIME = Instant.now()
+        private val BEGIN_OPTION = BeginGetPasswordOption(
+            emptySet<String>(),
+            Bundle.EMPTY, "id")
+        private val ICON = Icon.createWithBitmap(
+            Bitmap.createBitmap(
+                100, 100, Bitmap.Config.ARGB_8888
+            )
+        )
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryJavaTest.java
new file mode 100644
index 0000000..ffec2b8
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryJavaTest.java
@@ -0,0 +1,216 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.PublicKeyCredential;
+import androidx.credentials.R;
+import androidx.credentials.TestUtilsKt;
+import androidx.credentials.provider.BeginGetPublicKeyCredentialOption;
+import androidx.credentials.provider.PublicKeyCredentialEntry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class PublicKeyCredentialEntryJavaTest {
+    private static final CharSequence USERNAME = "title";
+    private static final CharSequence DISPLAYNAME = "subtitle";
+    private static final CharSequence TYPE_DISPLAY_NAME = "Password";
+    private static final Long LAST_USED_TIME = 10L;
+    private static final Icon ICON = Icon.createWithBitmap(Bitmap.createBitmap(
+            100, 100, Bitmap.Config.ARGB_8888));
+    private static final boolean IS_AUTO_SELECT_ALLOWED = true;
+    private final BeginGetPublicKeyCredentialOption mBeginOption =
+            new BeginGetPublicKeyCredentialOption(
+                    new Bundle(), "id", "{\"key1\":{\"key2\":{\"key3\":\"value3\"}}}");
+
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void build_requiredParamsOnly_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PublicKeyCredentialEntry entry = constructWithRequiredParamsOnly();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertThat(entry.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertEntryWithRequiredParams(entry);
+    }
+
+    @Test
+    public void build_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PublicKeyCredentialEntry entry = constructWithAllParams();
+
+        assertNotNull(entry);
+        assertNotNull(entry.getSlice());
+        assertThat(entry.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertEntryWithAllParams(entry);
+    }
+
+    @Test
+    public void build_withNullUsername_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null username to throw NPE",
+                NullPointerException.class,
+                () -> new PublicKeyCredentialEntry.Builder(
+                        mContext, null, mPendingIntent, mBeginOption
+                ).build());
+    }
+
+    @Test
+    public void build_withNullBeginOption_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null option to throw NPE",
+                NullPointerException.class,
+                () -> new PublicKeyCredentialEntry.Builder(
+                        mContext, USERNAME, mPendingIntent, null
+                ).build());
+    }
+
+    @Test
+    public void build_withNullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new PublicKeyCredentialEntry.Builder(
+                        mContext, USERNAME, null, mBeginOption
+                ).build());
+    }
+
+    @Test
+    public void build_withEmptyUsername_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected empty username to throw IllegalArgumentException",
+                IllegalArgumentException.class,
+                () -> new PublicKeyCredentialEntry.Builder(
+                        mContext, "", mPendingIntent, mBeginOption).build());
+    }
+
+    @Test
+    public void build_withNullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PublicKeyCredentialEntry entry = new PublicKeyCredentialEntry
+                .Builder(
+                mContext, USERNAME, mPendingIntent, mBeginOption).build();
+
+        assertThat(TestUtilsKt.equals(entry.getIcon(),
+                Icon.createWithResource(mContext, R.drawable.ic_passkey))).isTrue();
+    }
+
+    @Test
+    public void build_nullTypeDisplayName_defaultDisplayNameSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PublicKeyCredentialEntry entry = new PublicKeyCredentialEntry.Builder(
+                        mContext, USERNAME, mPendingIntent, mBeginOption).build();
+
+        assertThat(entry.getTypeDisplayName()).isEqualTo(
+                mContext.getString(
+                        R.string.androidx_credentials_TYPE_PUBLIC_KEY_CREDENTIAL)
+        );
+    }
+
+    @Test
+    public void fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        PublicKeyCredentialEntry originalEntry = constructWithAllParams();
+        assertNotNull(originalEntry.getSlice());
+
+        PublicKeyCredentialEntry entry = PublicKeyCredentialEntry.fromSlice(
+                originalEntry.getSlice());
+
+        assertNotNull(entry);
+        assertEntryWithRequiredParams(entry);
+    }
+
+    private PublicKeyCredentialEntry constructWithRequiredParamsOnly() {
+        return new PublicKeyCredentialEntry.Builder(
+                mContext,
+                USERNAME,
+                mPendingIntent,
+                mBeginOption
+        ).build();
+    }
+
+    private PublicKeyCredentialEntry constructWithAllParams() {
+        return new PublicKeyCredentialEntry.Builder(
+                mContext, USERNAME, mPendingIntent, mBeginOption)
+                .setAutoSelectAllowed(IS_AUTO_SELECT_ALLOWED)
+                .setDisplayName(DISPLAYNAME)
+                .setLastUsedTime(Instant.ofEpochMilli(LAST_USED_TIME))
+                .setIcon(ICON)
+                .build();
+    }
+
+    private void assertEntryWithRequiredParams(PublicKeyCredentialEntry entry) {
+        assertThat(USERNAME.equals(entry.getUsername()));
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    private void assertEntryWithAllParams(PublicKeyCredentialEntry entry) {
+        assertThat(USERNAME.equals(entry.getUsername()));
+        assertThat(DISPLAYNAME.equals(entry.getDisplayName()));
+        assertThat(TYPE_DISPLAY_NAME.equals(entry.getTypeDisplayName()));
+        assertThat(ICON).isEqualTo(entry.getIcon());
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.getLastUsedTime());
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed());
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryTest.kt
new file mode 100644
index 0000000..ba4f546
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/PublicKeyCredentialEntryTest.kt
@@ -0,0 +1,189 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import androidx.core.os.BuildCompat
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.R
+import androidx.credentials.equals
+import androidx.credentials.provider.BeginGetPublicKeyCredentialOption
+import androidx.credentials.provider.PublicKeyCredentialEntry
+import androidx.credentials.provider.PublicKeyCredentialEntry.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.time.Instant
+import junit.framework.TestCase.assertNotNull
+import org.junit.Assert.assertThrows
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class PublicKeyCredentialEntryTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(
+        mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE
+    )
+
+    @Test
+    fun constructor_requiredParamsOnly_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructWithRequiredParamsOnly()
+
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertThat(entry.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertEntryWithRequiredParams(entry)
+    }
+
+    @Test
+    fun constructor_allParams_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = constructWithAllParams()
+        assertNotNull(entry)
+        assertNotNull(entry.slice)
+        assertThat(entry.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertEntryWithAllParams(entry)
+    }
+
+    @Test
+    fun constructor_emptyUsername_throwsIAE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        assertThrows(
+            "Expected empty username to throw IllegalArgumentException",
+            IllegalArgumentException::class.java
+        ) {
+            PublicKeyCredentialEntry(
+                mContext, "", mPendingIntent, BEGIN_OPTION
+            )
+        }
+    }
+
+    @Test
+    fun constructor_nullIcon_defaultIconSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = PublicKeyCredentialEntry(
+            mContext, USERNAME, mPendingIntent, BEGIN_OPTION
+        )
+
+        assertThat(
+            equals(
+                entry.icon,
+                Icon.createWithResource(mContext, R.drawable.ic_passkey)
+            )
+        ).isTrue()
+    }
+
+    @Test
+    fun constructor_nullTypeDisplayName_defaultDisplayNameSet() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = PublicKeyCredentialEntry(
+            mContext, USERNAME, mPendingIntent, BEGIN_OPTION
+        )
+        assertThat(entry.typeDisplayName).isEqualTo(
+            mContext.getString(
+                R.string.androidx_credentials_TYPE_PUBLIC_KEY_CREDENTIAL
+            )
+        )
+    }
+
+    @Test
+    fun fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = constructWithAllParams()
+
+        val entry = fromSlice(originalEntry.slice)
+
+        assertNotNull(entry)
+        entry?.let {
+            assertEntryWithRequiredParams(entry)
+        }
+    }
+
+    private fun constructWithRequiredParamsOnly(): PublicKeyCredentialEntry {
+        return PublicKeyCredentialEntry(
+            mContext,
+            USERNAME,
+            mPendingIntent,
+            BEGIN_OPTION
+        )
+    }
+
+    private fun constructWithAllParams(): PublicKeyCredentialEntry {
+        return PublicKeyCredentialEntry(
+            mContext,
+            USERNAME,
+            mPendingIntent,
+            BEGIN_OPTION,
+            DISPLAYNAME,
+            Instant.ofEpochMilli(LAST_USED_TIME),
+            ICON,
+            IS_AUTO_SELECT_ALLOWED
+        )
+    }
+
+    private fun assertEntryWithRequiredParams(entry: PublicKeyCredentialEntry) {
+        assertThat(USERNAME == entry.username)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    private fun assertEntryWithAllParams(entry: PublicKeyCredentialEntry) {
+        assertThat(USERNAME == entry.username)
+        assertThat(DISPLAYNAME == entry.displayName)
+        assertThat(TYPE_DISPLAY_NAME == entry.typeDisplayName)
+        assertThat(ICON).isEqualTo(entry.icon)
+        assertThat(Instant.ofEpochMilli(LAST_USED_TIME)).isEqualTo(entry.lastUsedTime)
+        assertThat(IS_AUTO_SELECT_ALLOWED).isEqualTo(entry.isAutoSelectAllowed)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    companion object {
+        private val BEGIN_OPTION: BeginGetPublicKeyCredentialOption =
+            BeginGetPublicKeyCredentialOption(Bundle(), "id",
+                "{\"key1\":{\"key2\":{\"key3\":\"value3\"}}}")
+        private val USERNAME: CharSequence = "title"
+        private val DISPLAYNAME: CharSequence = "subtitle"
+        private val TYPE_DISPLAY_NAME: CharSequence = "Password"
+        private const val LAST_USED_TIME: Long = 10L
+        private val ICON = Icon.createWithBitmap(Bitmap.createBitmap(
+            100, 100, Bitmap.Config.ARGB_8888))
+        private const val IS_AUTO_SELECT_ALLOWED = true
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryJavaTest.java
new file mode 100644
index 0000000..90be938
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryJavaTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.credentials.provider.ui;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.core.os.BuildCompat;
+import androidx.credentials.provider.RemoteEntry;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+public class RemoteEntryJavaTest {
+    private final Context mContext = ApplicationProvider.getApplicationContext();
+    private final Intent mIntent = new Intent();
+    private final PendingIntent mPendingIntent =
+            PendingIntent.getActivity(mContext, 0, mIntent,
+                    PendingIntent.FLAG_IMMUTABLE);
+
+    @Test
+    public void constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry entry = new RemoteEntry(mPendingIntent);
+
+        assertNotNull(entry);
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    @Test
+    public void build_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry entry = new RemoteEntry.Builder(mPendingIntent).build();
+
+        assertNotNull(entry);
+        assertThat(mPendingIntent).isEqualTo(entry.getPendingIntent());
+    }
+
+    @Test
+    public void constructor_nullPendingIntent_throwsNPE() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        assertThrows("Expected null pending intent to throw NPE",
+                NullPointerException.class,
+                () -> new RemoteEntry(null));
+    }
+
+    @Test
+    public void fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return;
+        }
+        RemoteEntry originalEntry = new RemoteEntry(mPendingIntent);
+
+        RemoteEntry fromSlice = RemoteEntry.fromSlice(RemoteEntry.toSlice(originalEntry));
+
+        assertThat(fromSlice).isNotNull();
+        assertThat(fromSlice.getPendingIntent()).isEqualTo(mPendingIntent);
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryTest.kt
new file mode 100644
index 0000000..0278077
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/RemoteEntryTest.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import androidx.core.os.BuildCompat
+import androidx.credentials.provider.RemoteEntry
+import androidx.credentials.provider.RemoteEntry.Companion.fromSlice
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import junit.framework.TestCase.assertNotNull
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+class RemoteEntryTest {
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+    private val mIntent = Intent()
+    private val mPendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
+        PendingIntent.FLAG_IMMUTABLE)
+
+    @Test
+    fun constructor_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = RemoteEntry(mPendingIntent)
+
+        assertNotNull(entry)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    @Test
+    fun build_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val entry = RemoteEntry.Builder(mPendingIntent).build()
+
+        assertNotNull(entry)
+        assertThat(mPendingIntent).isEqualTo(entry.pendingIntent)
+    }
+
+    @Test
+    fun fromSlice_success() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val originalEntry = RemoteEntry(mPendingIntent)
+
+        val fromSlice = fromSlice(RemoteEntry.toSlice(originalEntry))
+
+        assertThat(fromSlice).isNotNull()
+        if (fromSlice != null) {
+            assertThat(fromSlice.pendingIntent).isEqualTo(mPendingIntent)
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/UiUtils.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/UiUtils.kt
new file mode 100644
index 0000000..60cd479
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/provider/ui/UiUtils.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.credentials.provider.ui
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.BeginGetPasswordOption
+import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.PasswordCredentialEntry
+import androidx.credentials.provider.RemoteEntry
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SdkSuppress
+
+@SdkSuppress(minSdkVersion = 34, codeName = "UpsideDownCake")
+class UiUtils {
+    companion object {
+        private val sContext = ApplicationProvider.getApplicationContext<Context>()
+        private val sIntent = Intent()
+        private val sPendingIntent = PendingIntent.getActivity(
+            sContext, 0, sIntent,
+            PendingIntent.FLAG_IMMUTABLE
+        )
+        private val ACCOUNT_NAME: CharSequence = "account_name"
+        private const val DESCRIPTION = "description"
+        private const val PASSWORD_COUNT = 10
+        private const val PUBLIC_KEY_CREDENTIAL_COUNT = 10
+        private const val TOTAL_COUNT = 10
+        private const val LAST_USED_TIME = 10L
+        private val ICON = Icon.createWithBitmap(
+            Bitmap.createBitmap(
+                100, 100, Bitmap.Config.ARGB_8888
+            )
+        )
+        private val BEGIN_OPTION = BeginGetPasswordOption(
+            setOf(), Bundle.EMPTY, "id"
+        )
+
+        /**
+         * Generates a default authentication action entry that can be used for tests around the
+         * provider objects.
+         */
+        @JvmStatic
+        fun constructAuthenticationActionEntry(title: CharSequence): AuthenticationAction {
+            return AuthenticationAction(title, sPendingIntent)
+        }
+
+        /**
+         * Generates a default action entry that can be used for tests around the provider
+         * objects.
+         */
+        @JvmStatic
+        fun constructActionEntry(title: CharSequence, subtitle: CharSequence): Action {
+            return Action(title, sPendingIntent, subtitle)
+        }
+
+        /**
+         * Generates a default password credential entry that can be used for tests around the
+         * provider objects.
+         */
+        @JvmStatic
+        fun constructPasswordCredentialEntryDefault(username: CharSequence): CredentialEntry {
+            return PasswordCredentialEntry(
+                sContext,
+                username,
+                sPendingIntent,
+                BEGIN_OPTION
+            )
+        }
+
+        /**
+         * Generate a default remote entry that can be used for tests around the provider objects.
+         */
+        @JvmStatic
+        fun constructRemoteEntryDefault(): RemoteEntry {
+            return RemoteEntry(sPendingIntent)
+        }
+
+        /**
+         * Generates a create entry with known inputs for accountName and description in order
+         * to test proper formation.
+         *
+         * @param accountName the account name associated with the create entry
+         * @param description the description associated with the create entry
+         */
+        @JvmStatic
+        fun constructCreateEntryWithSimpleParams(
+            accountName: CharSequence,
+            description: CharSequence
+        ):
+            CreateEntry {
+            return CreateEntry.Builder(accountName, sPendingIntent).setDescription(description)
+                .build()
+        }
+
+        @JvmStatic
+        fun constructRemoteEntry():
+            RemoteEntry {
+            return RemoteEntry(sPendingIntent)
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
index c3e25f2..17d2ac5 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
@@ -30,28 +30,46 @@
  * An application can construct a subtype request and call [CredentialManager.createCredential] to
  * launch framework UI flows to collect consent and any other metadata needed from the user to
  * register a new user credential.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass (e.g.
+ * the type for [CreatePasswordRequest] is [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] and for
+ * [CreatePublicKeyCredentialRequest] is [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL])
+ * @property credentialData the request data in the [Bundle] format
+ * @property candidateQueryData the partial request data in the [Bundle] format that will be sent
+ * to the provider during the initial candidate query stage, which should not contain sensitive
+ * user credential information (note: bundle keys in the form of `androidx.credentials.*` are
+ * reserved for internal library use)
+ * @property isSystemProviderRequired true if must only be fulfilled by a system provider and
+ * false otherwise
+ * @property isAutoSelectAllowed whether a create option will be automatically chosen if it is
+ * the only one available to the user
+ * @property displayInfo the information to be displayed on the screen
+ * @property origin the origin of a different application if the request is being made on behalf of
+ * that application (Note: for API level >=34, setting a non-null value for this parameter will
+ * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+ * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available passkey registration offering instead of falling back to
+ * discovering remote options, and false (preferred by default) otherwise
  */
 abstract class CreateCredentialRequest internal constructor(
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val type: String,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val credentialData: Bundle,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val candidateQueryData: Bundle,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val isSystemProviderRequired: Boolean,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val isAutoSelectAllowed: Boolean,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    val type: String,
+    val credentialData: Bundle,
+    val candidateQueryData: Bundle,
+    val isSystemProviderRequired: Boolean,
+    val isAutoSelectAllowed: Boolean,
     val displayInfo: DisplayInfo,
     val origin: String?,
+    @get:JvmName("preferImmediatelyAvailableCredentials")
+    val preferImmediatelyAvailableCredentials: Boolean,
 ) {
 
     init {
-        @Suppress("UNNECESSARY_SAFE_CALL")
-        credentialData?.let {
-            credentialData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
-        }
+        credentialData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
+        credentialData.putBoolean(
+            BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+            preferImmediatelyAvailableCredentials
+        )
+        candidateQueryData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
     }
 
     /**
@@ -69,7 +87,7 @@
         @get:RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
         val credentialTypeIcon: Icon?,
         @get:RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
-        val defaultProvider: String?,
+        val preferDefaultProvider: String?,
     ) {
 
         /**
@@ -91,19 +109,45 @@
             null,
         )
 
+        /**
+         * Constructs a [DisplayInfo].
+         *
+         * @param userId the user id of the created credential
+         * @param userDisplayName an optional display name in addition to the [userId] that may be
+         * displayed next to the `userId` during the user consent to help your user better
+         * understand the credential being created
+         * @param preferDefaultProvider the preferred default provider component name to prioritize in the
+         * selection UI flows. Your app must have the permission
+         * android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this, or it
+         * would not take effect. Also this bit may not take effect for Android API level 33 and
+         * below, depending on the pre-34 provider(s) you have chosen.
+         * @throws IllegalArgumentException If [userId] is empty
+         */
+        constructor(
+            userId: CharSequence,
+            userDisplayName: CharSequence?,
+            preferDefaultProvider: String?
+        ) : this(
+            userId,
+            userDisplayName,
+            null,
+            preferDefaultProvider,
+        )
+
         init {
             require(userId.isNotEmpty()) { "userId should not be empty" }
         }
 
+        @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
         @RequiresApi(23)
-        internal fun toBundle(): Bundle {
+        fun toBundle(): Bundle {
             val bundle = Bundle()
             bundle.putCharSequence(BUNDLE_KEY_USER_ID, userId)
             if (!TextUtils.isEmpty(userDisplayName)) {
                 bundle.putCharSequence(BUNDLE_KEY_USER_DISPLAY_NAME, userDisplayName)
             }
-            if (!TextUtils.isEmpty(defaultProvider)) {
-                bundle.putString(BUNDLE_KEY_DEFAULT_PROVIDER, defaultProvider)
+            if (!TextUtils.isEmpty(preferDefaultProvider)) {
+                bundle.putString(BUNDLE_KEY_DEFAULT_PROVIDER, preferDefaultProvider)
             }
             // Today the type icon is determined solely within this library right before the
             // request is passed into the framework. Later if needed a new API can be added for
@@ -156,6 +200,9 @@
 
     internal companion object {
         @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
+        const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+        @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
         const val BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED =
             "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED"
 
@@ -177,13 +224,14 @@
             return try {
                 when (type) {
                     PasswordCredential.TYPE_PASSWORD_CREDENTIAL ->
-                        CreatePasswordRequest.createFrom(credentialData, origin)
+                        CreatePasswordRequest.createFrom(credentialData, origin, candidateQueryData)
 
                     PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
                         when (credentialData.getString(BUNDLE_KEY_SUBTYPE)) {
                             CreatePublicKeyCredentialRequest
                                 .BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST ->
-                                CreatePublicKeyCredentialRequest.createFrom(credentialData, origin)
+                                CreatePublicKeyCredentialRequest.createFrom(
+                                    credentialData, origin, candidateQueryData)
 
                             else -> throw FrameworkClassParsingException()
                         }
@@ -201,7 +249,10 @@
                     DisplayInfo.parseFromCredentialDataBundle(
                         credentialData
                     ) ?: return null,
-                    credentialData.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false)
+                    credentialData.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false),
+                    origin,
+                    credentialData.getBoolean(
+                        BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS, false),
                 )
             }
         }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
index 88f20a3..50cad1b 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
@@ -23,12 +23,15 @@
 /**
  * Base response class for the credential creation operation made with the
  * [CreateCredentialRequest].
+ *
+ * @property type the credential type determined by the credential-type-specific subclass (e.g.
+ * the type for [CreatePasswordResponse] is [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] and for
+ * [CreatePublicKeyCredentialResponse] is [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL])
+ * @property data the response data in the [Bundle] format
  */
 abstract class CreateCredentialResponse internal constructor(
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val type: String,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val data: Bundle,
+    val type: String,
+    val data: Bundle,
 ) {
     internal companion object {
         @JvmStatic
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialRequest.kt
index 09c6b6f..b5f580e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialRequest.kt
@@ -36,32 +36,36 @@
  * @param type the credential type determined by the credential-type-specific subclass for
  * custom use cases
  * @param credentialData the data of this [CreateCustomCredentialRequest] in the [Bundle]
- * format (note: bundle keys in the form of `androidx.credentials.*` are reserved for internal
- * library use)
+ * format (note: bundle keys in the form of `androidx.credentials.*` and `android.credentials.*` are
+ * reserved for internal library usage)
  * @param candidateQueryData the partial request data in the [Bundle] format that will be sent
  * to the provider during the initial candidate query stage, which should not contain sensitive
- * user credential information (note: bundle keys in the form of `androidx.credentials.*` are
- * reserved for internal library use)
+ * user credential information (note: bundle keys in the form of `androidx.credentials.*` and
+ * `android.credentials.*` are reserved for internal library usage)
  * @param isSystemProviderRequired true if must only be fulfilled by a system provider and
  * false otherwise
  * @param isAutoSelectAllowed defines if a create entry will be automatically chosen if it is
  * the only one available option, false by default
  * @param displayInfo the information to be displayed on the screen
  * @param origin the origin of a different application if the request is being made on behalf of
- * that application. For API level >=34, setting a non-null value for this parameter, will throw
- * a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present.
+ * that application (Note: for API level >=34, setting a non-null value for this parameter will
+ * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+ * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available passkey registration offering instead of falling back to
+ * discovering remote options, and false (default) otherwise
  * @throws IllegalArgumentException If [type] is empty
  * @throws NullPointerException If [type], [credentialData], or [candidateQueryData] is null
  */
 open class CreateCustomCredentialRequest
 @JvmOverloads constructor(
-    final override val type: String,
-    final override val credentialData: Bundle,
-    final override val candidateQueryData: Bundle,
-    final override val isSystemProviderRequired: Boolean,
+    type: String,
+    credentialData: Bundle,
+    candidateQueryData: Bundle,
+    isSystemProviderRequired: Boolean,
     displayInfo: DisplayInfo,
-    final override val isAutoSelectAllowed: Boolean = false,
+    isAutoSelectAllowed: Boolean = false,
     origin: String? = null,
+    preferImmediatelyAvailableCredentials: Boolean = false,
 ) : CreateCredentialRequest(
     type,
     credentialData,
@@ -69,9 +73,9 @@
     isSystemProviderRequired,
     isAutoSelectAllowed,
     displayInfo,
-    origin
+    origin,
+    preferImmediatelyAvailableCredentials
 ) {
-
     init {
         require(type.isNotEmpty()) { "type should not be empty" }
     }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialResponse.kt
index caf0dac..a623a2e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCustomCredentialResponse.kt
@@ -30,15 +30,17 @@
  * Note: The Bundle keys for [data] should not be in the form of androidx.credentials.*` as they
  * are reserved for internal use by this androidx library.
  *
- * @property type the credential type determined by the credential-type-specific subclass for custom
+ * @param type the credential type determined by the credential-type-specific subclass for custom
  * use cases
- * @property data the response data in the [Bundle] format for custom use cases
+ * @param data the response data in the [Bundle] format for custom use cases  (note: bundle keys in
+ * the form of `androidx.credentials.*` and `android.credentials.*` are reserved for internal
+ * library usage)
  * @throws IllegalArgumentException If [type] is empty
  * @throws NullPointerException If [type] or [data] are null
 */
 open class CreateCustomCredentialResponse(
-    final override val type: String,
-    final override val data: Bundle
+    type: String,
+    data: Bundle
 ) : CreateCredentialResponse(type, data) {
     init {
         require(type.isNotEmpty()) { "type should not be empty" }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
index a124749..33f8b28 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
@@ -26,24 +26,33 @@
  *
  * @property id the user id associated with the password
  * @property password the password
+ * @param id the user id associated with the password
+ * @param password the password
  * @param origin the origin of a different application if the request is being made on behalf of
- * that application. For API level >=34, setting a non-null value for this parameter, will throw a
- * SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present when
- * API level >= 34.
+ * that application (Note: for API level >=34, setting a non-null value for this parameter will
+ * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+ * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available credential creation offering instead of falling back to
+ * discovering remote options, and false (default) otherwise
  */
 class CreatePasswordRequest private constructor(
     val id: String,
     val password: String,
+    isAutoSelectAllowed: Boolean,
     displayInfo: DisplayInfo,
     origin: String? = null,
+    preferImmediatelyAvailableCredentials: Boolean,
+    credentialData: Bundle = toCredentialDataBundle(id, password),
+    candidateQueryData: Bundle = toCandidateDataBundle(),
 ) : CreateCredentialRequest(
     type = PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
-    credentialData = toCredentialDataBundle(id, password),
-    candidateQueryData = toCandidateDataBundle(),
+    credentialData = credentialData,
+    candidateQueryData = candidateQueryData,
     isSystemProviderRequired = false,
-    isAutoSelectAllowed = false,
+    isAutoSelectAllowed,
     displayInfo,
-    origin
+    origin,
+    preferImmediatelyAvailableCredentials,
 ) {
 
     /**
@@ -53,15 +62,83 @@
      * @param id the user id associated with the password
      * @param password the password
      * @param origin the origin of a different application if the request is being made on behalf of
-     * that application. For API level >=34, setting a non-null value for this parameter, will throw
-     * a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present.
+     * that application (Note: for API level >=34, setting a non-null value for this parameter will
+     * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+     * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+     * immediately when there is no available password saving option instead of falling back
+     * to discovering remote options, and false (default) otherwise
+     * @param isAutoSelectAllowed whether a create option will be automatically chosen if it is
+     * the only one available to the user (note that there is a chance that the credential provider
+     * does not support auto-select even if you turn this bit on); not recommended to be true for
+     * password request type to ensure that the user will always get a confirmation dialog even if
+     * the password saving provider does not offer any UI
      * @throws NullPointerException If [id] is null
      * @throws NullPointerException If [password] is null
      * @throws IllegalArgumentException If [password] is empty
-     * @throws SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present
+     * @throws SecurityException if [origin] is set but
+     * android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present
      */
-    @JvmOverloads constructor(id: String, password: String, origin: String? = null) : this(id,
-        password, DisplayInfo(id, null), origin)
+    @JvmOverloads constructor(
+        id: String,
+        password: String,
+        origin: String? = null,
+        preferImmediatelyAvailableCredentials: Boolean = false,
+        isAutoSelectAllowed: Boolean = false,
+    ) : this(
+        id = id,
+        password = password,
+        isAutoSelectAllowed = isAutoSelectAllowed,
+        displayInfo = DisplayInfo(id, null),
+        origin = origin,
+        preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials)
+
+    /**
+     * Constructs a [CreatePasswordRequest] to save the user password credential with their
+     * password provider.
+     *
+     * @param id the user id associated with the password
+     * @param password the password
+     * @param origin the origin of a different application if the request is being made on behalf of
+     * that application (Note: for API level >=34, setting a non-null value for this parameter will
+     * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+     * @param preferDefaultProvider the preferred default provider component name to prioritize in
+     * the selection UI flows (Note: your app must have the permission
+     * android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this, or it
+     * would not take effect; also this bit may not take effect for Android API level 33 and below,
+     * depending on the pre-34 provider(s) you have chosen)
+     * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+     * immediately when there is no available passkey registration offering instead of falling back
+     * to discovering remote options, and false (preferably) otherwise
+     * @param isAutoSelectAllowed whether a create option will be automatically chosen if it is
+     * the only one available to the user (note that there is a chance that the credential provider
+     * does not support auto-select even if you turn this bit on); not recommended to be true for
+     * password request type to ensure that the user will always get a confirmation dialog even if
+     * the password saving provider does not offer any UI
+     * @throws NullPointerException If [id] is null
+     * @throws NullPointerException If [password] is null
+     * @throws IllegalArgumentException If [password] is empty
+     * @throws SecurityException if [origin] is set but
+     * android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present
+     */
+    constructor(
+        id: String,
+        password: String,
+        origin: String?,
+        preferDefaultProvider: String?,
+        preferImmediatelyAvailableCredentials: Boolean,
+        isAutoSelectAllowed: Boolean
+    ) : this(
+        id = id,
+        password = password,
+        isAutoSelectAllowed = isAutoSelectAllowed,
+        displayInfo = DisplayInfo(
+            userId = id,
+            userDisplayName = null,
+            preferDefaultProvider = preferDefaultProvider,
+        ),
+        origin = origin,
+        preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
+    )
 
     init {
         require(password.isNotEmpty()) { "password should not be empty" }
@@ -89,16 +166,30 @@
 
         @JvmStatic
         @RequiresApi(23)
-        internal fun createFrom(data: Bundle, origin: String? = null): CreatePasswordRequest {
+        internal fun createFrom(
+            data: Bundle,
+            origin: String?,
+            candidateQueryData: Bundle,
+        ): CreatePasswordRequest {
             try {
-                val id = data.getString(BUNDLE_KEY_ID)
-                val password = data.getString(BUNDLE_KEY_PASSWORD)
+                val id = data.getString(BUNDLE_KEY_ID)!!
+                val password = data.getString(BUNDLE_KEY_PASSWORD)!!
                 val displayInfo = DisplayInfo.parseFromCredentialDataBundle(data)
-                return if (displayInfo == null) CreatePasswordRequest(
-                    id!!,
-                    password!!,
-                    origin
-                ) else CreatePasswordRequest(id!!, password!!, displayInfo, origin)
+                    ?: DisplayInfo(id, null)
+                val preferImmediatelyAvailableCredentials =
+                    data.getBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS, false)
+                val isAutoSelectAllowed =
+                    data.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false)
+                return CreatePasswordRequest(
+                    id = id,
+                    password = password,
+                    displayInfo = displayInfo,
+                    origin = origin,
+                    preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
+                    credentialData = data,
+                    candidateQueryData = candidateQueryData,
+                    isAutoSelectAllowed = isAutoSelectAllowed,
+                )
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
             }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
index f34f0ec..bd173fc 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
@@ -19,15 +19,18 @@
 import android.os.Bundle
 
 /** A response of a password saving flow. */
-class CreatePasswordResponse : CreateCredentialResponse(
+class CreatePasswordResponse private constructor(data: Bundle) : CreateCredentialResponse(
     PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
-    Bundle(),
+    data,
 ) {
+
+    /** Constructs a [CreatePasswordResponse]. */
+    constructor() : this(Bundle())
+
     internal companion object {
-        @Suppress("UNUSED_PARAMETER")
         @JvmStatic
         internal fun createFrom(data: Bundle): CreatePasswordResponse {
-            return CreatePasswordResponse()
+            return CreatePasswordResponse(data)
         }
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
index d1d5875..85b21c5 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
@@ -20,42 +20,49 @@
 import androidx.annotation.RequiresApi
 import androidx.credentials.PublicKeyCredential.Companion.BUNDLE_KEY_SUBTYPE
 import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.internal.RequestValidationHelper
 import org.json.JSONObject
 
 /**
  * A request to register a passkey from the user's public key credential provider.
  *
+ * @property requestJson the request in JSON format in the [standard webauthn web json](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson).
+ * @property clientDataHash a clientDataHash value to sign over in place of assembling and hashing
+ * clientDataJSON during the signature request; only meaningful when [origin] is set
  * @param requestJson the request in JSON format in the [standard webauthn web json](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson).
- * @param clientDataHash a hash that is used to verify the origin
+ * @param clientDataHash a clientDataHash value to sign over in place of assembling and hashing
+ * clientDataJSON during the signature request; only meaningful when [origin] is set
  * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
  * immediately when there is no available passkey registration offering instead of falling back to
  * discovering remote options, and false (default) otherwise
  * @param origin the origin of a different application if the request is being made on behalf of
- * that application. For API level >=34, setting a non-null value for this parameter, will throw
- * a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present.
+ * that application (Note: for API level >=34, setting a non-null value for this parameter will
+ * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
  */
 class CreatePublicKeyCredentialRequest private constructor(
     val requestJson: String,
-    val clientDataHash: String?,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean,
+    val clientDataHash: ByteArray?,
+    isAutoSelectAllowed: Boolean,
+    preferImmediatelyAvailableCredentials: Boolean,
     displayInfo: DisplayInfo,
     origin: String? = null,
+    credentialData: Bundle = toCredentialDataBundle(requestJson, clientDataHash),
+    candidateQueryData: Bundle = toCandidateDataBundle(requestJson, clientDataHash),
 ) : CreateCredentialRequest(
     type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    credentialData = toCredentialDataBundle(requestJson, clientDataHash,
-        preferImmediatelyAvailableCredentials),
+    credentialData = credentialData,
     // The whole request data should be passed during the query phase.
-    candidateQueryData = toCredentialDataBundle(requestJson, clientDataHash,
-        preferImmediatelyAvailableCredentials),
+    candidateQueryData = candidateQueryData,
     isSystemProviderRequired = false,
-    isAutoSelectAllowed = false,
+    isAutoSelectAllowed = isAutoSelectAllowed,
     displayInfo,
-    origin
+    origin,
+    preferImmediatelyAvailableCredentials
 ) {
 
     /**
-     * Constructs a [CreatePublicKeyCredentialRequest] to register a passkey from the user's public key credential provider.
+     * Constructs a [CreatePublicKeyCredentialRequest] to register a passkey from the user's public
+     * key credential provider.
      *
      * @param requestJson the privileged request in JSON format in the [standard webauthn web json](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson).
      * @param clientDataHash a hash that is used to verify the relying party identity
@@ -63,27 +70,80 @@
      * immediately when there is no available passkey registration offering instead of falling back to
      * discovering remote options, and false (default) otherwise
      * @param origin the origin of a different application if the request is being made on behalf of
-     * that application. For API level >=34, setting a non-null value for this parameter, will throw
-     * a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present.
+     * that application (Note: for API level >=34, setting a non-null value for this parameter will
+     * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+     * @param isAutoSelectAllowed whether a create option will be automatically chosen if it is
+     * the only one available to the user (note that there is a chance that the crendeiatl provider
+     * does not support auto-select even if you turn this bit on)
      * @throws NullPointerException If [requestJson] is null
-     * @throws IllegalArgumentException If [requestJson] is empty, or if it doesn't have a valid
-     * `user.name` defined according to the [webauthn spec](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson)
+     * @throws IllegalArgumentException If [requestJson] is empty, or if it is not a valid JSON,
+     * or if it doesn't have a valid `user.name` defined according to the
+     * [webauthn spec]
+     * (https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson)
      */
     @JvmOverloads constructor(
         requestJson: String,
-        clientDataHash: String? = null,
+        clientDataHash: ByteArray? = null,
         preferImmediatelyAvailableCredentials: Boolean = false,
-        origin: String? = null
-    ) : this(requestJson, clientDataHash, preferImmediatelyAvailableCredentials,
-        getRequestDisplayInfo(requestJson), origin)
+        origin: String? = null,
+        isAutoSelectAllowed: Boolean = false,
+    ) : this(
+        requestJson = requestJson,
+        clientDataHash = clientDataHash,
+        preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
+        displayInfo = getRequestDisplayInfo(requestJson),
+        origin = origin,
+        isAutoSelectAllowed = isAutoSelectAllowed,
+    )
+
+    /**
+     * Constructs a [CreatePublicKeyCredentialRequest] to register a passkey from the user's public
+     * key credential provider.
+     *
+     * @param requestJson the privileged request in JSON format in the [standard webauthn web
+     * json](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson).
+     * @param clientDataHash a hash that is used to verify the relying party identity
+     * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+     * immediately when there is no available passkey registration offering instead of falling back to
+     * discovering remote options, and false (preferably) otherwise
+     * @param origin the origin of a different application if the request is being made on behalf of
+     * that application (Note: for API level >=34, setting a non-null value for this parameter will
+     * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+     * @param preferDefaultProvider the preferred default provider component name to prioritize in
+     * the selection UI flows (Note: tour app must have the permission
+     * android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this, or it
+     * would not take effect; also this bit may not take effect for Android API level 33 and below,
+     * depending on the pre-34 provider(s) you have chosen)
+     * @param isAutoSelectAllowed whether a create option will be automatically chosen if it is
+     * the only one available to the user (note that there is a chance that the credential provider
+     * does not support auto-select even if you turn this bit on)
+     * @throws NullPointerException If [requestJson] is null
+     * @throws IllegalArgumentException If [requestJson] is empty, or if it doesn't have a valid
+     * `user.name` defined according to the [webauthn
+     * spec](https://w3c.github.io/webauthn/#dictdef-publickeycredentialcreationoptionsjson)
+     */
+    constructor(
+        requestJson: String,
+        clientDataHash: ByteArray?,
+        preferImmediatelyAvailableCredentials: Boolean,
+        origin: String?,
+        preferDefaultProvider: String?,
+        isAutoSelectAllowed: Boolean,
+    ) : this(
+        requestJson = requestJson,
+        clientDataHash = clientDataHash,
+        preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
+        displayInfo = getRequestDisplayInfo(requestJson, preferDefaultProvider),
+        origin = origin,
+        isAutoSelectAllowed = isAutoSelectAllowed,
+    )
 
     init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+        require(RequestValidationHelper.isValidJSON(requestJson)) {
+            "requestJson must not be empty, and must be a valid JSON" }
     }
 
     internal companion object {
-        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
         internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
             "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
         internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
@@ -91,14 +151,22 @@
             "androidx.credentials.BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST"
 
         @JvmStatic
-        internal fun getRequestDisplayInfo(requestJson: String): DisplayInfo {
+        internal fun getRequestDisplayInfo(
+            requestJson: String,
+            defaultProvider: String? = null,
+        ): DisplayInfo {
             return try {
                 val json = JSONObject(requestJson)
                 val user = json.getJSONObject("user")
                 val userName = user.getString("name")
                 val displayName: String? =
                     if (user.isNull("displayName")) null else user.getString("displayName")
-                DisplayInfo(userName, displayName)
+                DisplayInfo(
+                    userId = userName,
+                    userDisplayName = displayName,
+                    credentialTypeIcon = null,
+                    preferDefaultProvider = defaultProvider,
+                )
             } catch (e: Exception) {
                 throw IllegalArgumentException("user.name must be defined in requestJson")
             }
@@ -107,8 +175,7 @@
         @JvmStatic
         internal fun toCredentialDataBundle(
             requestJson: String,
-            clientDataHash: String? = null,
-            preferImmediatelyAvailableCredentials: Boolean
+            clientDataHash: ByteArray? = null,
         ): Bundle {
             val bundle = Bundle()
             bundle.putString(
@@ -116,19 +183,14 @@
                 BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST
             )
             bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
-            bundle.putBoolean(
-                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials
-            )
+            bundle.putByteArray(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
             return bundle
         }
 
         @JvmStatic
         internal fun toCandidateDataBundle(
             requestJson: String,
-            clientDataHash: String?,
-            preferImmediatelyAvailableCredentials: Boolean
+            clientDataHash: ByteArray?,
         ): Bundle {
             val bundle = Bundle()
             bundle.putString(
@@ -136,37 +198,32 @@
                 BUNDLE_VALUE_SUBTYPE_CREATE_PUBLIC_KEY_CREDENTIAL_REQUEST
             )
             bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
-            bundle.putBoolean(
-                BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials
-            )
+            bundle.putByteArray(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
             return bundle
         }
 
-        @Suppress("deprecation") // bundle.get() used for boolean value
-        // to prevent default boolean value from being returned.
         @JvmStatic
         @RequiresApi(23)
-        internal fun createFrom(data: Bundle, origin: String? = null):
+        internal fun createFrom(data: Bundle, origin: String?, candidateQueryData: Bundle):
             CreatePublicKeyCredentialRequest {
             try {
-                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
+                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)!!
+                val clientDataHash = data.getByteArray(BUNDLE_KEY_CLIENT_DATA_HASH)
                 val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
+                    data.getBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS, false)
                 val displayInfo = DisplayInfo.parseFromCredentialDataBundle(data)
-                return if (displayInfo == null) CreatePublicKeyCredentialRequest(
-                    requestJson!!,
-                    clientDataHash,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean,
-                    origin
-                ) else CreatePublicKeyCredentialRequest(
-                    requestJson!!,
-                    clientDataHash,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean,
-                    displayInfo,
-                    origin
+                    ?: getRequestDisplayInfo(requestJson)
+                val isAutoSelectAllowed =
+                    data.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false)
+                return CreatePublicKeyCredentialRequest(
+                    requestJson = requestJson,
+                    clientDataHash = clientDataHash,
+                    preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,
+                    displayInfo = displayInfo,
+                    origin = origin,
+                    isAutoSelectAllowed = isAutoSelectAllowed,
+                    credentialData = data,
+                    candidateQueryData = candidateQueryData,
                 )
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
index ee01b33..75c2f12 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
@@ -18,24 +18,35 @@
 
 import android.os.Bundle
 import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.internal.RequestValidationHelper
 
 /**
  * A response of a public key credential (passkey) flow.
  *
  * @property registrationResponseJson the public key credential registration response in JSON format
- * @throws NullPointerException If [registrationResponseJson] is null
- * @throws IllegalArgumentException If [registrationResponseJson] is blank
  */
-class CreatePublicKeyCredentialResponse(
-    val registrationResponseJson: String
+class CreatePublicKeyCredentialResponse private constructor(
+    val registrationResponseJson: String,
+    data: Bundle,
 ) : CreateCredentialResponse(
     PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    toBundle(registrationResponseJson)
+    data,
 ) {
 
+    /**
+     * Constructs a [CreatePublicKeyCredentialResponse].
+     *
+     * @param registrationResponseJson the public key credential registration response in JSON format
+     * @throws NullPointerException If [registrationResponseJson] is null
+     * @throws IllegalArgumentException If [registrationResponseJson] is empty, or an invalid JSON
+     */
+    constructor(
+        registrationResponseJson: String
+    ) : this(registrationResponseJson, toBundle(registrationResponseJson))
+
     init {
-        require(registrationResponseJson.isNotEmpty()) { "registrationResponseJson must not be " +
-            "empty" }
+        require(RequestValidationHelper.isValidJSON(registrationResponseJson)) {
+            "registrationResponseJson must not be empty, and must be a valid JSON" }
     }
 
     internal companion object {
@@ -54,7 +65,7 @@
             try {
                 val registrationResponseJson =
                     data.getString(BUNDLE_KEY_REGISTRATION_RESPONSE_JSON)
-                return CreatePublicKeyCredentialResponse(registrationResponseJson!!)
+                return CreatePublicKeyCredentialResponse(registrationResponseJson!!, data)
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
             }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/Credential.kt b/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
index 6488093..b32cf51 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
@@ -22,12 +22,15 @@
 
 /**
  * Base class for a credential with which the user consented to authenticate to the app.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass (e.g.
+ * [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] for `PasswordCredential` or
+ * [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL] for `PublicKeyCredential`)
+ * @property data the credential data in the [Bundle] format
  */
 abstract class Credential internal constructor(
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val type: String,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val data: Bundle,
+    val type: String,
+    val data: Bundle,
 ) {
     internal companion object {
         @JvmStatic
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialManager.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialManager.kt
index 53396d9..8d4eb30 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CredentialManager.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialManager.kt
@@ -16,15 +16,14 @@
 
 package androidx.credentials
 
-import android.app.Activity
+import android.annotation.SuppressLint
+import android.app.PendingIntent
 import android.content.Context
 import android.os.CancellationSignal
+import androidx.annotation.RequiresApi
 import androidx.credentials.exceptions.ClearCredentialException
-import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException
 import androidx.credentials.exceptions.CreateCredentialException
-import androidx.credentials.exceptions.CreateCredentialProviderConfigurationException
 import androidx.credentials.exceptions.GetCredentialException
-import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
 import java.util.concurrent.Executor
 import kotlin.coroutines.resume
 import kotlin.coroutines.resumeWithException
@@ -85,11 +84,17 @@
  *
  *
  */
-@Suppress("UNUSED_PARAMETER")
-class CredentialManager private constructor(private val context: Context) {
+@RequiresApi(16)
+@SuppressLint("ObsoleteSdkInt") // Accommodate dependencies with a lower min sdk requirement
+interface CredentialManager {
     companion object {
+        /**
+         * Creates a [CredentialManager] based on the given [context].
+         *
+         * @param context the context with which the CredentialManager should be associated
+         */
         @JvmStatic
-        fun create(context: Context): CredentialManager = CredentialManager(context)
+        fun create(context: Context): CredentialManager = CredentialManagerImpl(context)
     }
 
     /**
@@ -98,13 +103,14 @@
      * The execution potentially launches framework UI flows for a user to view available
      * credentials, consent to using one of them, etc.
      *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
      * @param request the request for getting the credential
-     * @param activity the activity used to potentially launch any UI needed
      * @throws GetCredentialException If the request fails
      */
     suspend fun getCredential(
+        context: Context,
         request: GetCredentialRequest,
-        activity: Activity,
     ): GetCredentialResponse = suspendCancellableCoroutine { continuation ->
         // Any Android API that supports cancellation should be configured to propagate
         // coroutine cancellation as follows:
@@ -123,8 +129,97 @@
         }
 
         getCredentialAsync(
+            context,
             request,
-            activity,
+            canceller,
+            // Use a direct executor to avoid extra dispatch. Resuming the continuation will
+            // handle getting to the right thread or pool via the ContinuationInterceptor.
+            Runnable::run,
+            callback)
+    }
+
+    /**
+     * Requests a credential from the user.
+     *
+     * Different from the other `getCredential(GetCredentialRequest, Activity)` API, this API
+     * launches the remaining flows to retrieve an app credential from the user, after the
+     * completed prefetch work corresponding to the given `pendingGetCredentialHandle`. Use this
+     * API to complete the full credential retrieval operation after you initiated a request through
+     * the [prepareGetCredential] API.
+     *
+     * The execution can potentially launch UI flows to collect user consent to using a
+     * credential, display a picker when multiple credentials exist, etc.
+     *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
+     * @param pendingGetCredentialHandle the handle representing the pending operation to resume
+     * @throws GetCredentialException If the request fails
+     */
+    @RequiresApi(34)
+    suspend fun getCredential(
+        context: Context,
+        pendingGetCredentialHandle: PrepareGetCredentialResponse.PendingGetCredentialHandle,
+    ): GetCredentialResponse = suspendCancellableCoroutine { continuation ->
+        // Any Android API that supports cancellation should be configured to propagate
+        // coroutine cancellation as follows:
+        val canceller = CancellationSignal()
+        continuation.invokeOnCancellation { canceller.cancel() }
+
+        val callback = object : CredentialManagerCallback<GetCredentialResponse,
+            GetCredentialException> {
+            override fun onResult(result: GetCredentialResponse) {
+                continuation.resume(result)
+            }
+
+            override fun onError(e: GetCredentialException) {
+                continuation.resumeWithException(e)
+            }
+        }
+
+        getCredentialAsync(
+            context,
+            pendingGetCredentialHandle,
+            canceller,
+            // Use a direct executor to avoid extra dispatch. Resuming the continuation will
+            // handle getting to the right thread or pool via the ContinuationInterceptor.
+            Runnable::run,
+            callback)
+    }
+
+    /**
+     * Prepares for a get-credential operation. Returns a [PrepareGetCredentialResponse]
+     * that can later be used to launch the credential retrieval UI flow to finalize a user
+     * credential for your app.
+     *
+     * This API doesn't invoke any UI. It only performs the preparation work so that you can
+     * later launch the remaining get-credential operation (involves UIs) through the
+     * [getCredential] API which incurs less latency than executing the whole operation in one call.
+     *
+     * @param request the request for getting the credential
+     * @throws GetCredentialException If the request fails
+     */
+    @RequiresApi(34)
+    suspend fun prepareGetCredential(
+        request: GetCredentialRequest,
+    ): PrepareGetCredentialResponse = suspendCancellableCoroutine { continuation ->
+        // Any Android API that supports cancellation should be configured to propagate
+        // coroutine cancellation as follows:
+        val canceller = CancellationSignal()
+        continuation.invokeOnCancellation { canceller.cancel() }
+
+        val callback = object : CredentialManagerCallback<PrepareGetCredentialResponse,
+            GetCredentialException> {
+            override fun onResult(result: PrepareGetCredentialResponse) {
+                continuation.resume(result)
+            }
+
+            override fun onError(e: GetCredentialException) {
+                continuation.resumeWithException(e)
+            }
+        }
+
+        prepareGetCredentialAsync(
+            request,
             canceller,
             // Use a direct executor to avoid extra dispatch. Resuming the continuation will
             // handle getting to the right thread or pool via the ContinuationInterceptor.
@@ -139,13 +234,14 @@
      * The execution potentially launches framework UI flows for a user to view their registration
      * options, grant consent, etc.
      *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
      * @param request the request for creating the credential
-     * @param activity the activity used to potentially launch any UI needed
      * @throws CreateCredentialException If the request fails
      */
     suspend fun createCredential(
+        context: Context,
         request: CreateCredentialRequest,
-        activity: Activity,
     ): CreateCredentialResponse = suspendCancellableCoroutine { continuation ->
         // Any Android API that supports cancellation should be configured to propagate
         // coroutine cancellation as follows:
@@ -164,8 +260,8 @@
         }
 
         createCredentialAsync(
+            context,
             request,
-            activity,
             canceller,
             // Use a direct executor to avoid extra dispatch. Resuming the continuation will
             // handle getting to the right thread or pool via the ContinuationInterceptor.
@@ -216,73 +312,112 @@
     }
 
     /**
-     * Java API for requesting a credential from the user.
+     * Requests a credential from the user.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
      *
      * The execution potentially launches framework UI flows for a user to view available
      * credentials, consent to using one of them, etc.
      *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
      * @param request the request for getting the credential
-     * @param activity an optional activity used to potentially launch any UI needed
      * @param cancellationSignal an optional signal that allows for cancelling this call
      * @param executor the callback will take place on this executor
      * @param callback the callback invoked when the request succeeds or fails
      */
     fun getCredentialAsync(
+        context: Context,
         request: GetCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
-    ) {
-        val provider: CredentialProvider? = CredentialProviderFactory
-            .getBestAvailableProvider(context)
-        if (provider == null) {
-            // TODO (Update with the right error code when ready)
-            callback.onError(
-                GetCredentialProviderConfigurationException(
-                    "getCredentialAsync no provider dependencies found - please ensure " +
-                        "the desired provider dependencies are added")
-            )
-            return
-        }
-        provider.onGetCredential(request, activity, cancellationSignal, executor, callback)
-    }
+    )
 
     /**
-     * Java API for registering a user credential that can be used to authenticate the user to
+     * Requests a credential from the user.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * Different from the other `getCredentialAsync(GetCredentialRequest, Activity)` API, this API
+     * launches the remaining flows to retrieve an app credential from the user, after the
+     * completed prefetch work corresponding to the given `pendingGetCredentialHandle`. Use this
+     * API to complete the full credential retrieval operation after you initiated a request through
+     * the [prepareGetCredentialAsync] API.
+     *
+     * The execution can potentially launch UI flows to collect user consent to using a
+     * credential, display a picker when multiple credentials exist, etc.
+     *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
+     * @param pendingGetCredentialHandle the handle representing the pending operation to resume
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    fun getCredentialAsync(
+        context: Context,
+        pendingGetCredentialHandle: PrepareGetCredentialResponse.PendingGetCredentialHandle,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
+    )
+
+    /**
+     * Prepares for a get-credential operation. Returns a [PrepareGetCredentialResponse]
+     * that can later be used to launch the credential retrieval UI flow to finalize a user
+     * credential for your app.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * This API doesn't invoke any UI. It only performs the preparation work so that you can
+     * later launch the remaining get-credential operation (involves UIs) through the
+     * [getCredentialAsync] API which incurs less latency than executing the whole operation in one
+     * call.
+     *
+     * @param request the request for getting the credential
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    fun prepareGetCredentialAsync(
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<PrepareGetCredentialResponse, GetCredentialException>,
+    )
+
+    /**
+     * Registers a user credential that can be used to authenticate the user to
      * the app in the future.
      *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
      * The execution potentially launches framework UI flows for a user to view their registration
      * options, grant consent, etc.
      *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
      * @param request the request for creating the credential
-     * @param activity an optional activity used to potentially launch any UI needed
      * @param cancellationSignal an optional signal that allows for cancelling this call
      * @param executor the callback will take place on this executor
      * @param callback the callback invoked when the request succeeds or fails
      */
     fun createCredentialAsync(
+        context: Context,
         request: CreateCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>,
-    ) {
-        val provider: CredentialProvider? = CredentialProviderFactory
-            .getBestAvailableProvider(context)
-        if (provider == null) {
-            // TODO (Update with the right error code when ready)
-            callback.onError(CreateCredentialProviderConfigurationException(
-                "createCredentialAsync no provider dependencies found - please ensure the " +
-                    "desired provider dependencies are added"))
-            return
-        }
-        provider.onCreateCredential(request, activity, cancellationSignal, executor, callback)
-    }
+    )
 
     /**
      * Clears the current user credential state from all credential providers.
      *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
      * You should invoked this api after your user signs out of your app to notify all credential
      * providers that any stored credential session for the given app should be cleared.
      *
@@ -302,16 +437,12 @@
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<Void?, ClearCredentialException>,
-    ) {
-        val provider: CredentialProvider? = CredentialProviderFactory
-            .getBestAvailableProvider(context)
-        if (provider == null) {
-            // TODO (Update with the right error code when ready)
-            callback.onError(ClearCredentialProviderConfigurationException(
-                "clearCredentialStateAsync no provider dependencies found - please ensure the " +
-                    "desired provider dependencies are added"))
-            return
-        }
-        provider.onClearCredential(request, cancellationSignal, executor, callback)
-    }
+    )
+
+    /**
+     * Returns a pending intent that shows a screen that lets a user enable a Credential Manager provider.
+     * @return the pending intent that can be launched
+     */
+    @RequiresApi(34)
+    fun createSettingsPendingIntent(): PendingIntent
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialManagerImpl.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialManagerImpl.kt
new file mode 100644
index 0000000..dabfdd7b
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialManagerImpl.kt
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.CancellationSignal
+import androidx.annotation.RequiresApi
+import androidx.credentials.exceptions.ClearCredentialException
+import androidx.credentials.exceptions.ClearCredentialProviderConfigurationException
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.CreateCredentialProviderConfigurationException
+import androidx.credentials.exceptions.GetCredentialException
+import androidx.credentials.exceptions.GetCredentialProviderConfigurationException
+import java.util.concurrent.Executor
+
+/**
+ * Manages user authentication flows.
+ *
+ * An application can call the CredentialManager apis to launch framework UI flows for a user to
+ * register a new credential or to consent to a saved credential from supported credential
+ * providers, which can then be used to authenticate to the app.
+ *
+ * This class contains its own exception types.
+ * They represent unique failures during the Credential Manager flow. As required, they
+ * can be extended for unique types containing new and unique versions of the exception - either
+ * with new 'exception types' (same credential class, different exceptions), or inner subclasses
+ * and their exception types (a subclass credential class and all their exception types).
+ *
+ * For example, if there is an UNKNOWN exception type, assuming the base Exception is
+ * [ClearCredentialException], we can add an 'exception type' class for it as follows:
+ * TODO("Add in new flow with extensive 'getType' function")
+ * ```
+ * class ClearCredentialUnknownException(
+ *     errorMessage: CharSequence? = null
+ * ) : ClearCredentialException(TYPE_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION, errorMessage) {
+ *  // ...Any required impl here...//
+ *  companion object {
+ *       private const val TYPE_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION: String =
+ *       "androidx.credentials.TYPE_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION"
+ *   }
+ * }
+ * ```
+ *
+ * Furthermore, the base class can be subclassed to a new more specific credential type, which
+ * then can further be subclassed into individual exception types. The first is an example of a
+ * 'inner credential type exception', and the next is a 'exception type' of this subclass exception.
+ *
+ * ```
+ * class UniqueCredentialBasedOnClearCredentialException(
+ *     type: String,
+ *     errorMessage: CharSequence? = null
+ * ) : ClearCredentialException(type, errorMessage) {
+ *  // ... Any required impl here...//
+ * }
+ * // .... code and logic .... //
+ * class UniqueCredentialBasedOnClearCredentialUnknownException(
+ *     errorMessage: CharSequence? = null
+ * ) : ClearCredentialException(TYPE_UNIQUE_CREDENTIAL_BASED_ON_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION,
+ * errorMessage) {
+ * // ... Any required impl here ... //
+ *  companion object {
+ *       private const val
+ *       TYPE_UNIQUE_CREDENTIAL_BASED_ON_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION: String =
+ *       "androidx.credentials.TYPE_CLEAR_CREDENTIAL_UNKNOWN_EXCEPTION"
+ *   }
+ * }
+ * ```
+ *
+ *
+ */
+@RequiresApi(16)
+@SuppressLint("ObsoleteSdkInt") // Accommodate dependencies with a lower min sdk requirement
+internal class CredentialManagerImpl internal constructor(
+    private val context: Context
+) : CredentialManager {
+    companion object {
+        /**
+         * An intent action that shows a screen that let user enable a Credential Manager provider.
+         */
+        private const val
+        INTENT_ACTION_FOR_CREDENTIAL_PROVIDER_SETTINGS: String =
+        "android.settings.CREDENTIAL_PROVIDER"
+    }
+
+    /**
+     * Requests a credential from the user.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * The execution potentially launches framework UI flows for a user to view available
+     * credentials, consent to using one of them, etc.
+     *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
+     * @param request the request for getting the credential
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    override fun getCredentialAsync(
+        context: Context,
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
+    ) {
+        val provider: CredentialProvider? = CredentialProviderFactory
+            .getBestAvailableProvider(this.context)
+        if (provider == null) {
+            callback.onError(
+                GetCredentialProviderConfigurationException(
+                    "getCredentialAsync no provider dependencies found - please ensure " +
+                        "the desired provider dependencies are added")
+            )
+            return
+        }
+        provider.onGetCredential(context, request, cancellationSignal, executor, callback)
+    }
+
+    /**
+     * Requests a credential from the user.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * Different from the other `getCredentialAsync(GetCredentialRequest, Activity)` API, this API
+     * launches the remaining flows to retrieve an app credential from the user, after the
+     * completed prefetch work corresponding to the given `pendingGetCredentialHandle`. Use this
+     * API to complete the full credential retrieval operation after you initiated a request through
+     * the [prepareGetCredentialAsync] API.
+     *
+     * The execution can potentially launch UI flows to collect user consent to using a
+     * credential, display a picker when multiple credentials exist, etc.
+     *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
+     * @param pendingGetCredentialHandle the handle representing the pending operation to resume
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    override fun getCredentialAsync(
+        context: Context,
+        pendingGetCredentialHandle: PrepareGetCredentialResponse.PendingGetCredentialHandle,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
+    ) {
+        val provider = CredentialProviderFactory.getUAndAboveProvider(context)
+        provider.onGetCredential(
+            context, pendingGetCredentialHandle, cancellationSignal, executor, callback)
+    }
+
+    /**
+     * Prepares for a get-credential operation. Returns a [PrepareGetCredentialResponse]
+     * that can later be used to launch the credential retrieval UI flow to finalize a user
+     * credential for your app.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * This API doesn't invoke any UI. It only performs the preparation work so that you can
+     * later launch the remaining get-credential operation (involves UIs) through the
+     * [getCredentialAsync] API which incurs less latency than executing the whole operation in one
+     * call.
+     *
+     * @param request the request for getting the credential
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    override fun prepareGetCredentialAsync(
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<PrepareGetCredentialResponse, GetCredentialException>,
+    ) {
+        val provider = CredentialProviderFactory.getUAndAboveProvider(context)
+        provider.onPrepareCredential(request, cancellationSignal, executor, callback)
+    }
+
+    /**
+     * Registers a user credential that can be used to authenticate the user to
+     * the app in the future.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * The execution potentially launches framework UI flows for a user to view their registration
+     * options, grant consent, etc.
+     *
+     * @param context the context used to launch any UI needed; use an activity context to make
+     * sure the UI will be launched within the same task stack
+     * @param request the request for creating the credential
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    override fun createCredentialAsync(
+        context: Context,
+        request: CreateCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>,
+    ) {
+        val provider: CredentialProvider? = CredentialProviderFactory
+            .getBestAvailableProvider(this.context)
+        if (provider == null) {
+            callback.onError(CreateCredentialProviderConfigurationException(
+                "createCredentialAsync no provider dependencies found - please ensure the " +
+                    "desired provider dependencies are added"))
+            return
+        }
+        provider.onCreateCredential(context, request, cancellationSignal, executor, callback)
+    }
+
+    /**
+     * Clears the current user credential state from all credential providers.
+     *
+     * This API uses callbacks instead of Kotlin coroutines.
+     *
+     * You should invoked this api after your user signs out of your app to notify all credential
+     * providers that any stored credential session for the given app should be cleared.
+     *
+     * A credential provider may have stored an active credential session and use it to limit
+     * sign-in options for future get-credential calls. For example, it may prioritize the active
+     * credential over any other available credential. When your user explicitly signs out of your
+     * app and in order to get the holistic sign-in options the next time, you should call this API
+     * to let the provider clear any stored credential session.
+     *
+     * @param request the request for clearing the app user's credential state
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    override fun clearCredentialStateAsync(
+        request: ClearCredentialStateRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<Void?, ClearCredentialException>,
+    ) {
+        val provider: CredentialProvider? = CredentialProviderFactory
+            .getBestAvailableProvider(context)
+        if (provider == null) {
+            callback.onError(ClearCredentialProviderConfigurationException(
+                "clearCredentialStateAsync no provider dependencies found - please ensure the " +
+                    "desired provider dependencies are added"))
+            return
+        }
+        provider.onClearCredential(request, cancellationSignal, executor, callback)
+    }
+
+    /**
+     * Returns a pending intent that shows a screen that lets a user enable a Credential Manager provider.
+     * @return the pending intent that can be launched
+     */
+    @RequiresApi(34)
+    override fun createSettingsPendingIntent(): PendingIntent {
+        val intent: Intent = Intent(INTENT_ACTION_FOR_CREDENTIAL_PROVIDER_SETTINGS)
+        intent.setData(Uri.parse("package:" + context.getPackageName()))
+        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialOption.kt
index d1fd69b..94f12dc 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CredentialOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialOption.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
 import androidx.annotation.RestrictTo
 import androidx.credentials.internal.FrameworkClassParsingException
@@ -25,48 +26,66 @@
  *
  * [GetCredentialRequest] will be composed of a list of [CredentialOption] subclasses to indicate
  * the specific credential types and configurations that your app accepts.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass (e.g.
+ * the type for [GetPasswordOption] is [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] and for
+ * [GetPublicKeyCredentialOption] is [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL])
+ * @property requestData the request data in the [Bundle] format
+ * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
+ * the provider during the initial candidate query stage, which will not contain sensitive user
+ * information
+ * @property isSystemProviderRequired true if must only be fulfilled by a system provider and false
+ * otherwise
+ * @property isAutoSelectAllowed whether a credential entry will be automatically chosen if it is
+ * the only one available option
+ * @property allowedProviders a set of provider service [ComponentName] allowed to receive this
+ * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app does
+ * not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 34,
+ * this property will not take effect and you should control the allowed provider via
+ * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies))
  */
 abstract class CredentialOption internal constructor(
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val type: String,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val requestData: Bundle,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val candidateQueryData: Bundle,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val isSystemProviderRequired: Boolean,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    open val isAutoSelectAllowed: Boolean,
+    val type: String,
+    val requestData: Bundle,
+    val candidateQueryData: Bundle,
+    val isSystemProviderRequired: Boolean,
+    val isAutoSelectAllowed: Boolean,
+    val allowedProviders: Set<ComponentName>,
 ) {
 
     init {
-        @Suppress("UNNECESSARY_SAFE_CALL")
-        requestData?.let {
-            it.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
-        }
+        requestData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
+        candidateQueryData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
     }
 
     internal companion object {
         internal const val BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED =
             "androidx.credentials.BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED"
 
+        internal fun extractAutoSelectValue(data: Bundle): Boolean {
+            return data.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)
+        }
+
         @JvmStatic
         @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
         fun createFrom(
             type: String,
             requestData: Bundle,
             candidateQueryData: Bundle,
-            requireSystemProvider: Boolean
+            requireSystemProvider: Boolean,
+            allowedProviders: Set<ComponentName>,
         ): CredentialOption {
             return try {
                 when (type) {
                     PasswordCredential.TYPE_PASSWORD_CREDENTIAL ->
-                        GetPasswordOption.createFrom(requestData)
+                        GetPasswordOption.createFrom(
+                            requestData, allowedProviders, candidateQueryData)
                     PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL ->
                         when (requestData.getString(PublicKeyCredential.BUNDLE_KEY_SUBTYPE)) {
                             GetPublicKeyCredentialOption
                                 .BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION ->
-                                GetPublicKeyCredentialOption.createFrom(requestData)
+                                GetPublicKeyCredentialOption.createFrom(
+                                    requestData, allowedProviders, candidateQueryData)
                             else -> throw FrameworkClassParsingException()
                         }
                     else -> throw FrameworkClassParsingException()
@@ -75,11 +94,13 @@
                 // Parsing failed but don't crash the process. Instead just output a request with
                 // the raw framework values.
                 GetCustomCredentialOption(
-                    type,
-                    requestData,
-                    candidateQueryData,
-                    requireSystemProvider,
-                    requestData.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false)
+                    type = type,
+                    requestData = requestData,
+                    candidateQueryData = candidateQueryData,
+                    isSystemProviderRequired = requireSystemProvider,
+                    isAutoSelectAllowed = requestData.getBoolean(
+                        BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false),
+                    allowedProviders = allowedProviders,
                 )
             }
         }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialProvider.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialProvider.kt
index 49085d8..1dab141 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CredentialProvider.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialProvider.kt
@@ -16,8 +16,9 @@
 
 package androidx.credentials
 
-import android.app.Activity
+import android.content.Context
 import android.os.CancellationSignal
+import androidx.annotation.RequiresApi
 import androidx.credentials.exceptions.ClearCredentialException
 import androidx.credentials.exceptions.CreateCredentialException
 import androidx.credentials.exceptions.GetCredentialException
@@ -50,15 +51,15 @@
     /**
      * Invoked on a request to get a credential.
      *
+     * @param context the client calling context used to potentially launch any UI needed
      * @param request the request for getting the credential
-     * @param activity the client calling activity used to potentially launch any UI needed
      * @param cancellationSignal an optional signal that allows for cancelling this call
      * @param executor the callback will take place on this executor
      * @param callback the callback invoked when the request succeeds or fails
      */
     fun onGetCredential(
+        context: Context,
         request: GetCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
@@ -67,15 +68,15 @@
     /**
      * Invoked on a request to create a credential.
      *
+     * @param context the client calling context used to potentially launch any UI needed
      * @param request the request for creating the credential
-     * @param activity the client calling activity used to potentially launch any UI needed
      * @param cancellationSignal an optional signal that allows for cancelling this call
      * @param executor the callback will take place on this executor
      * @param callback the callback invoked when the request succeeds or fails
      */
     fun onCreateCredential(
+        context: Context,
         request: CreateCredentialRequest,
-        activity: Activity,
         cancellationSignal: CancellationSignal?,
         executor: Executor,
         callback: CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>,
@@ -98,4 +99,38 @@
         executor: Executor,
         callback: CredentialManagerCallback<Void?, ClearCredentialException>,
     )
+
+    /**
+     * Invoked on a request to prepare for a get-credential operation
+     *
+     * @param request the request for getting the credential
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    fun onPrepareCredential(
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<PrepareGetCredentialResponse, GetCredentialException>,
+    ) {}
+
+    /**
+     * Complete on a request to get a credential represented by the [pendingGetCredentialHandle].
+     *
+     * @param context the client calling context used to potentially launch any UI needed
+     * @param pendingGetCredentialHandle the handle representing the pending operation to resume
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor the callback will take place on this executor
+     * @param callback the callback invoked when the request succeeds or fails
+     */
+    @RequiresApi(34)
+    fun onGetCredential(
+        context: Context,
+        pendingGetCredentialHandle: PrepareGetCredentialResponse.PendingGetCredentialHandle,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>,
+    ) {}
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFactory.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFactory.kt
index d230818..1c8d122 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFactory.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFactory.kt
@@ -18,7 +18,9 @@
 
 import android.content.Context
 import android.content.pm.PackageManager
+import android.os.Build
 import android.util.Log
+import androidx.annotation.RequiresApi
 
 /**
  * Factory that returns the credential provider to be used by Credential Manager.
@@ -26,6 +28,7 @@
 internal class CredentialProviderFactory {
     companion object {
         private const val TAG = "CredProviderFactory"
+        private const val MAX_CRED_MAN_PRE_FRAMEWORK_API_LEVEL = Build.VERSION_CODES.TIRAMISU
 
         /** The metadata key to be used when specifying the provider class name in the
          * android manifest file. */
@@ -38,7 +41,18 @@
          * Post-U, providers will be registered with the framework, and enabled by the user.
          */
         fun getBestAvailableProvider(context: Context): CredentialProvider? {
-            return tryCreatePreUOemProvider(context)
+            return if (Build.VERSION.SDK_INT >= 34) { // Android U
+                CredentialProviderFrameworkImpl(context)
+            } else if (Build.VERSION.SDK_INT <= MAX_CRED_MAN_PRE_FRAMEWORK_API_LEVEL) {
+                tryCreatePreUOemProvider(context)
+            } else {
+                null
+            }
+        }
+
+        @RequiresApi(34)
+        fun getUAndAboveProvider(context: Context): CredentialProvider {
+            return CredentialProviderFrameworkImpl(context)
         }
 
         private fun tryCreatePreUOemProvider(context: Context): CredentialProvider? {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt
new file mode 100644
index 0000000..25082b7
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/CredentialProviderFrameworkImpl.kt
@@ -0,0 +1,376 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.credentials.CredentialManager
+import android.os.Build
+import android.os.Bundle
+import android.os.CancellationSignal
+import android.os.OutcomeReceiver
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.credentials.exceptions.ClearCredentialException
+import androidx.credentials.exceptions.ClearCredentialUnknownException
+import androidx.credentials.exceptions.ClearCredentialUnsupportedException
+import androidx.credentials.exceptions.CreateCredentialCancellationException
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.CreateCredentialInterruptedException
+import androidx.credentials.exceptions.CreateCredentialNoCreateOptionException
+import androidx.credentials.exceptions.CreateCredentialUnknownException
+import androidx.credentials.exceptions.CreateCredentialUnsupportedException
+import androidx.credentials.exceptions.GetCredentialCancellationException
+import androidx.credentials.exceptions.GetCredentialException
+import androidx.credentials.exceptions.GetCredentialInterruptedException
+import androidx.credentials.exceptions.GetCredentialUnknownException
+import androidx.credentials.exceptions.GetCredentialUnsupportedException
+import androidx.credentials.exceptions.NoCredentialException
+import androidx.credentials.internal.FrameworkImplHelper
+import java.util.concurrent.Executor
+
+/**
+ * Framework credential provider implementation that allows credential
+ * manager requests to be routed to the framework.
+ */
+@RequiresApi(34)
+internal class CredentialProviderFrameworkImpl(context: Context) : CredentialProvider {
+    private val credentialManager: CredentialManager? =
+        context.getSystemService(Context.CREDENTIAL_SERVICE) as CredentialManager?
+
+    override fun onPrepareCredential(
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<PrepareGetCredentialResponse, GetCredentialException>
+    ) {
+        if (isCredmanDisabled {
+                callback.onError(
+                    GetCredentialUnsupportedException(
+                        "Your device doesn't support credential manager"
+                    )
+                )
+            }) return
+        val outcome = object : OutcomeReceiver<
+            android.credentials.PrepareGetCredentialResponse,
+            android.credentials.GetCredentialException> {
+            override fun onResult(response: android.credentials.PrepareGetCredentialResponse) {
+                callback.onResult(convertPrepareGetResponseToJetpackClass(response))
+            }
+
+            override fun onError(error: android.credentials.GetCredentialException) {
+                callback.onError(convertToJetpackGetException(error))
+            }
+        }
+
+        credentialManager!!.prepareGetCredential(
+            convertGetRequestToFrameworkClass(request),
+            cancellationSignal,
+            executor,
+            outcome
+        )
+    }
+
+    override fun onGetCredential(
+        context: Context,
+        pendingGetCredentialHandle: PrepareGetCredentialResponse.PendingGetCredentialHandle,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>
+    ) {
+        if (isCredmanDisabled {
+                callback.onError(
+                    GetCredentialUnsupportedException(
+                        "Your device doesn't support credential manager"
+                    )
+                )
+            }) return
+        val outcome = object : OutcomeReceiver<
+            android.credentials.GetCredentialResponse, android.credentials.GetCredentialException> {
+            override fun onResult(response: android.credentials.GetCredentialResponse) {
+                callback.onResult(convertGetResponseToJetpackClass(response))
+            }
+
+            override fun onError(error: android.credentials.GetCredentialException) {
+                callback.onError(convertToJetpackGetException(error))
+            }
+        }
+
+        credentialManager!!.getCredential(
+            context,
+            pendingGetCredentialHandle.frameworkHandle!!,
+            cancellationSignal,
+            executor,
+            outcome
+        )
+    }
+
+    override fun onGetCredential(
+        context: Context,
+        request: GetCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<GetCredentialResponse, GetCredentialException>
+    ) {
+        if (isCredmanDisabled {
+                callback.onError(
+                    GetCredentialUnsupportedException(
+                        "Your device doesn't support credential manager"
+                    )
+                )
+            }) return
+
+        val outcome = object : OutcomeReceiver<
+            android.credentials.GetCredentialResponse, android.credentials.GetCredentialException> {
+            override fun onResult(response: android.credentials.GetCredentialResponse) {
+                Log.i(TAG, "GetCredentialResponse returned from framework")
+                callback.onResult(convertGetResponseToJetpackClass(response))
+            }
+
+            override fun onError(error: android.credentials.GetCredentialException) {
+                Log.i(TAG, "GetCredentialResponse error returned from framework")
+                callback.onError(convertToJetpackGetException(error))
+            }
+        }
+
+        credentialManager!!.getCredential(
+            context,
+            convertGetRequestToFrameworkClass(request),
+            cancellationSignal,
+            executor,
+            outcome
+        )
+    }
+
+    private fun isCredmanDisabled(handleNullCredMan: () -> Unit): Boolean {
+        if (credentialManager == null) {
+            handleNullCredMan()
+            return true
+        }
+        return false
+    }
+
+    override fun onCreateCredential(
+        context: Context,
+        request: CreateCredentialRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<CreateCredentialResponse, CreateCredentialException>
+    ) {
+        if (isCredmanDisabled {
+                callback.onError(
+                    CreateCredentialUnsupportedException(
+                        "Your device doesn't support credential manager"
+                    )
+                )
+            }) return
+        val outcome = object : OutcomeReceiver<
+            android.credentials.CreateCredentialResponse,
+            android.credentials.CreateCredentialException> {
+            override fun onResult(response: android.credentials.CreateCredentialResponse) {
+                Log.i(TAG, "Create Result returned from framework: ")
+                callback.onResult(
+                    CreateCredentialResponse.createFrom(
+                        request.type, response.data
+                    )
+                )
+            }
+
+            override fun onError(error: android.credentials.CreateCredentialException) {
+                Log.i(TAG, "CreateCredentialResponse error returned from framework")
+                callback.onError(convertToJetpackCreateException(error))
+            }
+        }
+
+        credentialManager!!.createCredential(
+            context,
+            convertCreateRequestToFrameworkClass(request, context),
+            cancellationSignal,
+            executor,
+            outcome
+        )
+    }
+
+    private fun convertCreateRequestToFrameworkClass(
+        request: CreateCredentialRequest,
+        context: Context
+    ): android.credentials.CreateCredentialRequest {
+        val createCredentialRequestBuilder: android.credentials.CreateCredentialRequest.Builder =
+            android.credentials.CreateCredentialRequest
+                .Builder(request.type,
+                    FrameworkImplHelper.getFinalCreateCredentialData(request, context),
+                    request.candidateQueryData)
+                .setIsSystemProviderRequired(request.isSystemProviderRequired)
+                // TODO("change to taking value from the request when ready")
+                .setAlwaysSendAppInfoToProvider(true)
+        setOriginForCreateRequest(request, createCredentialRequestBuilder)
+        return createCredentialRequestBuilder.build()
+    }
+
+    @SuppressLint("MissingPermission")
+    private fun setOriginForCreateRequest(
+        request: CreateCredentialRequest,
+        builder: android.credentials.CreateCredentialRequest.Builder
+    ) {
+        if (request.origin != null) {
+            builder.setOrigin(request.origin)
+        }
+    }
+
+    private fun convertGetRequestToFrameworkClass(request: GetCredentialRequest):
+        android.credentials.GetCredentialRequest {
+        val builder = android.credentials.GetCredentialRequest.Builder(
+            GetCredentialRequest.toRequestDataBundle(request))
+        request.credentialOptions.forEach {
+            // TODO(b/278308121): clean up the temporary bundle value injection after the Beta 2
+            // release.
+            if (request.preferImmediatelyAvailableCredentials &&
+                it is GetPublicKeyCredentialOption) {
+                it.requestData.putBoolean(
+                    "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS",
+                    true,
+                )
+            }
+
+            builder.addCredentialOption(
+                android.credentials.CredentialOption.Builder(
+                    it.type, it.requestData, it.candidateQueryData
+                ).setIsSystemProviderRequired(
+                    it.isSystemProviderRequired
+                ).setAllowedProviders(it.allowedProviders).build()
+            )
+        }
+        setOriginForGetRequest(request, builder)
+        return builder.build()
+    }
+
+    @SuppressLint("MissingPermission")
+    private fun setOriginForGetRequest(
+        request: GetCredentialRequest,
+        builder: android.credentials.GetCredentialRequest.Builder
+    ) {
+        if (request.origin != null) {
+            builder.setOrigin(request.origin)
+        }
+    }
+
+    private fun createFrameworkClearCredentialRequest():
+        android.credentials.ClearCredentialStateRequest {
+        return android.credentials.ClearCredentialStateRequest(Bundle())
+    }
+
+    internal fun convertToJetpackGetException(error: android.credentials.GetCredentialException):
+        GetCredentialException {
+        return when (error.type) {
+            android.credentials.GetCredentialException.TYPE_NO_CREDENTIAL ->
+                NoCredentialException(error.message)
+
+            android.credentials.GetCredentialException.TYPE_USER_CANCELED ->
+                GetCredentialCancellationException(error.message)
+
+            android.credentials.GetCredentialException.TYPE_INTERRUPTED ->
+                GetCredentialInterruptedException(error.message)
+
+            else -> GetCredentialUnknownException(error.message)
+        }
+    }
+
+    internal fun convertToJetpackCreateException(
+        error: android.credentials.CreateCredentialException
+    ): CreateCredentialException {
+        return when (error.type) {
+            android.credentials.CreateCredentialException.TYPE_NO_CREATE_OPTIONS ->
+                CreateCredentialNoCreateOptionException(error.message)
+
+            android.credentials.CreateCredentialException.TYPE_USER_CANCELED ->
+                CreateCredentialCancellationException(error.message)
+
+            android.credentials.CreateCredentialException.TYPE_INTERRUPTED ->
+                CreateCredentialInterruptedException(error.message)
+
+            else -> CreateCredentialUnknownException(error.message)
+        }
+    }
+
+    internal fun convertGetResponseToJetpackClass(
+        response: android.credentials.GetCredentialResponse
+    ): GetCredentialResponse {
+        val credential = response.credential
+        return GetCredentialResponse(
+            Credential.createFrom(
+                credential.type, credential.data
+            )
+        )
+    }
+
+    internal fun convertPrepareGetResponseToJetpackClass(
+        response: android.credentials.PrepareGetCredentialResponse
+    ): PrepareGetCredentialResponse {
+        return PrepareGetCredentialResponse(
+            response,
+            PrepareGetCredentialResponse.PendingGetCredentialHandle(
+                response.pendingGetCredentialHandle,
+            )
+        )
+    }
+
+    override fun isAvailableOnDevice(): Boolean {
+        return Build.VERSION.SDK_INT >= 34
+    }
+
+    override fun onClearCredential(
+        request: ClearCredentialStateRequest,
+        cancellationSignal: CancellationSignal?,
+        executor: Executor,
+        callback: CredentialManagerCallback<Void?, ClearCredentialException>
+    ) {
+        Log.i(TAG, "In CredentialProviderFrameworkImpl onClearCredential")
+
+        if (isCredmanDisabled { ->
+                callback.onError(
+                    ClearCredentialUnsupportedException(
+                        "Your device doesn't support credential manager"
+                    )
+                )
+            }) return
+
+        val outcome = object : OutcomeReceiver<Void,
+            android.credentials.ClearCredentialStateException> {
+            override fun onResult(response: Void) {
+                Log.i(TAG, "Clear result returned from framework: ")
+                callback.onResult(response)
+            }
+
+            override fun onError(error: android.credentials.ClearCredentialStateException) {
+                Log.i(TAG, "ClearCredentialStateException error returned from framework")
+                // TODO("Covert to the appropriate exception")
+                callback.onError(ClearCredentialUnknownException())
+            }
+        }
+
+        credentialManager!!.clearCredentialState(
+            createFrameworkClearCredentialRequest(),
+            cancellationSignal,
+            executor,
+            outcome
+        )
+    }
+
+    private companion object {
+        private const val TAG = "CredManProvService"
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CustomCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/CustomCredential.kt
index 7550543..a229a32 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CustomCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CustomCredential.kt
@@ -30,15 +30,17 @@
  * Note: The Bundle keys for [data] should not be in the form of `androidx.credentials.*` as they
  * are reserved for internal use by this androidx library.
  *
- * @property type the credential type determined by the credential-type-specific subclass for custom
+ * @param type the credential type determined by the credential-type-specific subclass for custom
  * use cases
- * @property data the credential data in the [Bundle] format for custom use cases
+ * @param data the credential data in the [Bundle] format for custom use cases (note: bundle keys in
+ * the form of `androidx.credentials.*` and `android.credentials.*` are reserved for internal
+ * library usage)
  * @throws IllegalArgumentException If [type] is empty
  * @throws NullPointerException If [data] or [type] is null
  */
 open class CustomCredential(
-    final override val type: String,
-    final override val data: Bundle
+    type: String,
+    data: Bundle
 ) : Credential(type, data) {
 
     init {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/GetCredentialRequest.kt
index 225880c..0f2e462 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetCredentialRequest.kt
@@ -16,6 +16,11 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
+import android.os.Bundle
+import androidx.annotation.RestrictTo
+import androidx.credentials.internal.FrameworkClassParsingException
+
 /**
  * Encapsulates a request to get a user credential.
  *
@@ -28,12 +33,41 @@
  * @property origin the origin of a different application if the request is being made on behalf of
  * that application. For API level >=34, setting a non-null value for this parameter, will throw
  * a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present.
+ * @property preferIdentityDocUi the value which signals if the UI should be tailored to display an
+ * identity document like driver license etc.
+ * @property preferUiBrandingComponentName a service [ComponentName] from which the Credential
+ * Selector UI will pull its label and icon to render top level branding. Your app must have the
+ * permission android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this, or
+ * it would not take effect. Notice that this bit may not take effect for Android API level
+ * 33 and below, depending on the pre-34 provider(s) you have chosen.
+ * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available credentials instead of falling back to discovering remote
+ * options, and false (default) otherwise
+ * @param credentialOptions the list of [CredentialOption] from which the user can choose
+ * one to authenticate to the app
+ * @param origin the origin of a different application if the request is being made on behalf of
+ * that application (Note: for API level >=34, setting a non-null value for this parameter, will
+ * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not present)
+ * @param preferIdentityDocUi the value which signals if the UI should be tailored to display an
+ * identity document like driver license etc
+ * @param preferUiBrandingComponentName a service [ComponentName] from which the Credential
+ * Selector UI will pull its label and icon to render top level branding (Note: your app must have
+ * the permission android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this, or
+ * it would not take effect; also this bit may not take effect for Android API level 33 and below,
+ * depending on the pre-34 provider(s) you have chosen
+ * @param preferImmediatelyAvailableCredentials true if you prefer the operation to return
+ * immediately when there is no available credentials instead of falling back to discovering remote
+ * options, and false (default) otherwise
  * @throws IllegalArgumentException If [credentialOptions] is empty
  */
 class GetCredentialRequest
 @JvmOverloads constructor(
     val credentialOptions: List<CredentialOption>,
     val origin: String? = null,
+    val preferIdentityDocUi: Boolean = false,
+    val preferUiBrandingComponentName: ComponentName? = null,
+    @get:JvmName("preferImmediatelyAvailableCredentials")
+    val preferImmediatelyAvailableCredentials: Boolean = false,
 ) {
 
     init {
@@ -44,6 +78,9 @@
     class Builder {
         private var credentialOptions: MutableList<CredentialOption> = mutableListOf()
         private var origin: String? = null
+        private var preferIdentityDocUi: Boolean = false
+        private var preferImmediatelyAvailableCredentials: Boolean = false
+        private var preferUiBrandingComponentName: ComponentName? = null
 
         /** Adds a specific type of [CredentialOption]. */
         fun addCredentialOption(credentialOption: CredentialOption): Builder {
@@ -57,22 +94,115 @@
             return this
         }
 
-        /** Sets the [origin] of a different application if the request is being made on behalf of
+        /**
+         * Sets the [origin] of a different application if the request is being made on behalf of
          * that application. For API level >=34, setting a non-null value for this parameter, will
          * throw a SecurityException if android.permission.CREDENTIAL_MANAGER_SET_ORIGIN is not
-         * present. */
+         * present.
+         */
         fun setOrigin(origin: String): Builder {
             this.origin = origin
             return this
         }
 
         /**
+         * Sets whether you prefer the operation to return immediately when there is no available
+         * credentials instead of falling back to discovering remote options. The default value
+         * is false.
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setPreferImmediatelyAvailableCredentials(
+            preferImmediatelyAvailableCredentials: Boolean
+        ): Builder {
+            this.preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
+            return this
+        }
+
+        /**
+         * Sets service [ComponentName] from which the Credential Selector UI will pull its label
+         * and icon to render top level branding. Your app must have the
+         * permission android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS to specify this,
+         * or it would not take effect. Notice that this bit may not take effect for Android API
+         * level 33 and below, depending on the pre-34 provider(s) you have chosen.
+         */
+        fun setPreferUiBrandingComponentName(component: ComponentName?): Builder {
+            this.preferUiBrandingComponentName = component
+            return this
+        }
+
+        /**
+         * Sets the [Boolean] preferIdentityDocUi to true if the requester wants to prefer using a
+         * UI suited for Identity Documents like mDocs, Driving License etc.
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setPreferIdentityDocUi(preferIdentityDocUi: Boolean): Builder {
+            this.preferIdentityDocUi = preferIdentityDocUi
+            return this
+        }
+
+        /**
          * Builds a [GetCredentialRequest].
          *
          * @throws IllegalArgumentException If [credentialOptions] is empty
          */
         fun build(): GetCredentialRequest {
-            return GetCredentialRequest(credentialOptions.toList(), origin)
+            return GetCredentialRequest(
+                credentialOptions.toList(),
+                origin,
+                preferIdentityDocUi,
+                preferUiBrandingComponentName,
+                preferImmediatelyAvailableCredentials
+            )
+        }
+    }
+
+    internal companion object {
+        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
+            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
+        private const val BUNDLE_KEY_PREFER_IDENTITY_DOC_UI =
+            "androidx.credentials.BUNDLE_KEY_PREFER_IDENTITY_DOC_UI"
+        private const val BUNDLE_KEY_PREFER_UI_BRANDING_COMPONENT_NAME =
+            "androidx.credentials.BUNDLE_KEY_PREFER_UI_BRANDING_COMPONENT_NAME"
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        fun toRequestDataBundle(
+            request: GetCredentialRequest
+        ): Bundle {
+            val bundle = Bundle()
+            bundle.putBoolean(BUNDLE_KEY_PREFER_IDENTITY_DOC_UI, request.preferIdentityDocUi)
+            bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
+                request.preferImmediatelyAvailableCredentials)
+            bundle.putParcelable(
+                BUNDLE_KEY_PREFER_UI_BRANDING_COMPONENT_NAME, request.preferUiBrandingComponentName)
+            return bundle
+        }
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        fun createFrom(
+            credentialOptions: List<CredentialOption>,
+            origin: String?,
+            data: Bundle
+        ): GetCredentialRequest {
+            try {
+                val preferIdentityDocUi = data.getBoolean(BUNDLE_KEY_PREFER_IDENTITY_DOC_UI)
+                val preferImmediatelyAvailableCredentials = data.getBoolean(
+                    BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
+                @Suppress("DEPRECATION")
+                val preferUiBrandingComponentName = data.getParcelable<ComponentName>(
+                    BUNDLE_KEY_PREFER_UI_BRANDING_COMPONENT_NAME)
+                val getCredentialBuilder = Builder().setCredentialOptions(credentialOptions)
+                    .setPreferIdentityDocUi(preferIdentityDocUi)
+                    .setPreferUiBrandingComponentName(preferUiBrandingComponentName)
+                    .setPreferImmediatelyAvailableCredentials(preferImmediatelyAvailableCredentials)
+                if (origin != null) {
+                    getCredentialBuilder.setOrigin(origin)
+                }
+                return getCredentialBuilder.build()
+            } catch (e: Exception) {
+                throw FrameworkClassParsingException()
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetCustomCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetCustomCredentialOption.kt
index 775e331..5ced43a 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetCustomCredentialOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetCustomCredentialOption.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
 
 /**
@@ -29,37 +30,44 @@
  * Note: The Bundle keys for [requestData] and [candidateQueryData] should not be in the form of
  * `androidx.credentials.*` as they are reserved for internal use by this androidx library.
  *
- * @property type the credential type determined by the credential-type-specific subclass
+ * @param type the credential type determined by the credential-type-specific subclass
  * generated for custom use cases
- * @property requestData the request data in the [Bundle] format, generated for custom use cases
- * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
+ * @param requestData the request data in the [Bundle] format, generated for custom use cases
+ * (note: bundle keys in the form of `androidx.credentials.*` and `android.credentials.*` are
+ * reserved for internal library usage)
+ * @param candidateQueryData the partial request data in the [Bundle] format that will be sent to
  * the provider during the initial candidate query stage, which should not contain sensitive user
- * information
- * @property isSystemProviderRequired true if must only be fulfilled by a system provider and false
+ * information (note: bundle keys in the form of `androidx.credentials.*` and
+ * `android.credentials.*` are reserved for internal library usage)
+ * @param isSystemProviderRequired true if must only be fulfilled by a system provider and false
  * otherwise
- * @property isAutoSelectAllowed defines if a credential entry will be automatically chosen if it is
+ * @param isAutoSelectAllowed defines if a credential entry will be automatically chosen if it is
  * the only one available option, false by default
+ * @param allowedProviders a set of provider service [ComponentName] allowed to receive this
+ * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app does
+ * not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 34,
+ * this property will not take effect and you should control the allowed provider via
+ * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies))
  * @throws IllegalArgumentException If [type] is empty
  * @throws NullPointerException If [requestData] or [type] is null
  */
 open class GetCustomCredentialOption @JvmOverloads constructor(
-    final override val type: String,
-    final override val requestData: Bundle,
-    final override val candidateQueryData: Bundle,
-    final override val isSystemProviderRequired: Boolean,
-    final override val isAutoSelectAllowed: Boolean = false,
+    type: String,
+    requestData: Bundle,
+    candidateQueryData: Bundle,
+    isSystemProviderRequired: Boolean,
+    isAutoSelectAllowed: Boolean = false,
+    allowedProviders: Set<ComponentName> = emptySet(),
 ) : CredentialOption(
     type = type,
     requestData = requestData,
     candidateQueryData = candidateQueryData,
     isSystemProviderRequired = isSystemProviderRequired,
-    isAutoSelectAllowed = isAutoSelectAllowed
+    isAutoSelectAllowed = isAutoSelectAllowed,
+    allowedProviders = allowedProviders,
 ) {
 
     init {
-        if (!requestData.containsKey(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED)) {
-            requestData.putBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, isAutoSelectAllowed)
-        }
         require(type.isNotEmpty()) { "type should not be empty" }
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
index 39f4f4d..c37d50d 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
@@ -16,28 +16,80 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
 
-/** A request to retrieve the user's saved application password from their password provider.
+/**
+ * A request to retrieve the user's saved application password from their password provider.
  *
- * @property isAutoSelectAllowed false by default, allows auto selecting a password if there is
- * only one available
+ * @property allowedUserIds a optional set of user ids with which the credentials associated are
+ * requested; leave as empty if you want to request all the available user credentials
  */
-class GetPasswordOption @JvmOverloads constructor(
-    override val isAutoSelectAllowed: Boolean = false
+class GetPasswordOption private constructor(
+    val allowedUserIds: Set<String>,
+    isAutoSelectAllowed: Boolean,
+    allowedProviders: Set<ComponentName>,
+    requestData: Bundle,
+    candidateQueryData: Bundle,
 ) : CredentialOption(
     type = PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
-    requestData = Bundle(),
-    candidateQueryData = Bundle(),
+    requestData = requestData,
+    candidateQueryData = candidateQueryData,
     isSystemProviderRequired = false,
     isAutoSelectAllowed = isAutoSelectAllowed,
+    allowedProviders,
 ) {
 
+    /**
+     * Constructs a [GetPasswordOption].
+     *
+     * @param allowedUserIds a optional set of user ids with which the credentials associated are
+     * requested; leave as empty if you want to request all the available user credentials
+     * @param isAutoSelectAllowed false by default, allows auto selecting a password if there is
+     * only one available
+     * @param allowedProviders a set of provider service [ComponentName] allowed to receive this
+     * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app does
+     * not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 34,
+     * this property will not take effect and you should control the allowed provider via
+     * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies))
+     */
+    @JvmOverloads constructor(
+        allowedUserIds: Set<String> = emptySet(),
+        isAutoSelectAllowed: Boolean = false,
+        allowedProviders: Set<ComponentName> = emptySet(),
+    ) : this(
+        allowedUserIds = allowedUserIds,
+        isAutoSelectAllowed = isAutoSelectAllowed,
+        allowedProviders = allowedProviders,
+        requestData = toBundle(allowedUserIds),
+        candidateQueryData = toBundle(allowedUserIds)
+    )
+
     internal companion object {
-        @Suppress("UNUSED_PARAMETER")
+        internal const val BUNDLE_KEY_ALLOWED_USER_IDS =
+            "androidx.credentials.BUNDLE_KEY_ALLOWED_USER_IDS"
+
         @JvmStatic
-        internal fun createFrom(data: Bundle): GetPasswordOption {
-            return GetPasswordOption()
+        internal fun createFrom(
+            data: Bundle,
+            allowedProviders: Set<ComponentName>,
+            candidateQueryData: Bundle,
+        ): GetPasswordOption {
+            val allowUserIdList = data.getStringArrayList(BUNDLE_KEY_ALLOWED_USER_IDS)
+            return GetPasswordOption(
+                allowedUserIds = allowUserIdList?.toSet() ?: emptySet(),
+                isAutoSelectAllowed = data.getBoolean(BUNDLE_KEY_IS_AUTO_SELECT_ALLOWED, false),
+                allowedProviders = allowedProviders,
+                requestData = data,
+                candidateQueryData = candidateQueryData,
+            )
+        }
+
+        @JvmStatic
+        internal fun toBundle(allowUserIds: Set<String>): Bundle {
+            val bundle = Bundle()
+            bundle.putStringArrayList(BUNDLE_KEY_ALLOWED_USER_IDS, ArrayList(allowUserIds))
+            return bundle
         }
     }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
index 586cde4..df95fc9 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
@@ -16,43 +16,70 @@
 
 package androidx.credentials
 
+import android.content.ComponentName
 import android.os.Bundle
 import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.internal.RequestValidationHelper
 
 /**
  * A request to get passkeys from the user's public key credential provider.
  *
  * @property requestJson the request in JSON format in the standard webauthn web json
  * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
- * @property clientDataHash a hash that is used to verify the relying party identity, set only if
- * you have set the [GetCredentialRequest.origin]
- * @property preferImmediatelyAvailableCredentials true if you prefer the operation to return
- * immediately when there is no available credential instead of falling back to discovering remote
- * credentials, and false (default) otherwise
- * @throws NullPointerException If [requestJson] is null
- * @throws IllegalArgumentException If [requestJson] is empty
+ * @property clientDataHash a clientDataHash value to sign over in place of assembling and hashing
+ * clientDataJSON during the signature request; meaningful only if you have set the
+ * [GetCredentialRequest.origin]
  */
-class GetPublicKeyCredentialOption @JvmOverloads constructor(
+class GetPublicKeyCredentialOption private constructor(
     val requestJson: String,
-    val clientDataHash: String? = null,
-    @get:JvmName("preferImmediatelyAvailableCredentials")
-    val preferImmediatelyAvailableCredentials: Boolean = false,
+    val clientDataHash: ByteArray?,
+    allowedProviders: Set<ComponentName>,
+    requestData: Bundle,
+    candidateQueryData: Bundle,
 ) : CredentialOption(
     type = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
-    requestData = toRequestDataBundle(requestJson, clientDataHash,
-        preferImmediatelyAvailableCredentials),
-    candidateQueryData = toRequestDataBundle(requestJson, clientDataHash,
-        preferImmediatelyAvailableCredentials),
+    requestData = requestData,
+    candidateQueryData = candidateQueryData,
     isSystemProviderRequired = false,
     isAutoSelectAllowed = true,
+    allowedProviders,
 ) {
+
+    /**
+     * Constructs a [GetPublicKeyCredentialOption].
+     *
+     * @param requestJson the request in JSON format in the standard webauthn web json
+     * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson).
+     * @param clientDataHash a clientDataHash value to sign over in place of assembling and hashing
+     * clientDataJSON during the signature request; set only if you have set the
+     * [GetCredentialRequest.origin]
+     * @param allowedProviders a set of provider service [ComponentName] allowed to receive this
+     * option (Note: a [SecurityException] will be thrown if it is set as non-empty but your app does
+     * not have android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS; for API level < 34,
+     * this property will not take effect and you should control the allowed provider via
+     * [library dependencies](https://developer.android.com/training/sign-in/passkeys#add-dependencies))
+     * @throws NullPointerException If [requestJson] is null
+     * @throws IllegalArgumentException If [requestJson] is empty, or if it
+     * is not a valid JSON
+     */
+    @JvmOverloads constructor(
+        requestJson: String,
+        clientDataHash: ByteArray? = null,
+        allowedProviders: Set<ComponentName> = emptySet(),
+    ) : this(
+        requestJson = requestJson,
+        clientDataHash = clientDataHash,
+        allowedProviders = allowedProviders,
+        requestData = toRequestDataBundle(requestJson, clientDataHash),
+        candidateQueryData = toRequestDataBundle(requestJson, clientDataHash),
+    )
+
     init {
-        require(requestJson.isNotEmpty()) { "requestJson must not be empty" }
+        require(RequestValidationHelper.isValidJSON(requestJson)) {
+            "requestJson must not be empty, and must be a valid JSON" }
     }
 
     internal companion object {
-        internal const val BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS =
-            "androidx.credentials.BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS"
         internal const val BUNDLE_KEY_CLIENT_DATA_HASH =
             "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
         internal const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
@@ -62,8 +89,7 @@
         @JvmStatic
         internal fun toRequestDataBundle(
             requestJson: String,
-            clientDataHash: String?,
-            preferImmediatelyAvailableCredentials: Boolean
+            clientDataHash: ByteArray?,
         ): Bundle {
             val bundle = Bundle()
             bundle.putString(
@@ -71,24 +97,28 @@
                 BUNDLE_VALUE_SUBTYPE_GET_PUBLIC_KEY_CREDENTIAL_OPTION
             )
             bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
-            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
-            bundle.putBoolean(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS,
-                preferImmediatelyAvailableCredentials)
+            bundle.putByteArray(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
             return bundle
         }
 
         @Suppress("deprecation") // bundle.get() used for boolean value to prevent default
                                          // boolean value from being returned.
         @JvmStatic
-        internal fun createFrom(data: Bundle): GetPublicKeyCredentialOption {
+        internal fun createFrom(
+            data: Bundle,
+            allowedProviders: Set<ComponentName>,
+            candidateQueryData: Bundle,
+        ): GetPublicKeyCredentialOption {
             try {
                 val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
-                val clientDataHash = data.getString(BUNDLE_KEY_CLIENT_DATA_HASH)
-                val preferImmediatelyAvailableCredentials =
-                    data.get(BUNDLE_KEY_PREFER_IMMEDIATELY_AVAILABLE_CREDENTIALS)
-                return GetPublicKeyCredentialOption(requestJson!!,
+                val clientDataHash = data.getByteArray(BUNDLE_KEY_CLIENT_DATA_HASH)
+                return GetPublicKeyCredentialOption(
+                    requestJson!!,
                     clientDataHash,
-                    (preferImmediatelyAvailableCredentials!!) as Boolean)
+                    allowedProviders,
+                    requestData = data,
+                    candidateQueryData = candidateQueryData,
+                )
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
             }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
index 3b143ca..3732050 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
@@ -17,7 +17,6 @@
 package androidx.credentials
 
 import android.os.Bundle
-import androidx.annotation.RestrictTo
 import androidx.credentials.internal.FrameworkClassParsingException
 
 /**
@@ -25,25 +24,32 @@
  *
  * @property id the user id associated with the password
  * @property password the password
- * @throws NullPointerException If [id] is null
- * @throws NullPointerException If [password] is null
- * @throws IllegalArgumentException If [password] is empty
  */
-class PasswordCredential constructor(
+class PasswordCredential private constructor(
     val id: String,
     val password: String,
-) : Credential(TYPE_PASSWORD_CREDENTIAL, toBundle(id, password)) {
+    data: Bundle,
+) : Credential(TYPE_PASSWORD_CREDENTIAL, data) {
+
+    /**
+     * Constructs a [PasswordCredential].
+     *
+     * @param id the user id associated with the password
+     * @param password the password
+     * @throws NullPointerException If [id] is null
+     * @throws NullPointerException If [password] is null
+     * @throws IllegalArgumentException If [password] is empty
+     */
+    constructor(id: String, password: String) : this(id, password, toBundle(id, password))
 
     init {
         require(password.isNotEmpty()) { "password should not be empty" }
     }
 
-    internal companion object {
-        // TODO: this type is officially defined in the framework. This definition should be
-        // removed when the framework type is available in jetpack.
-        @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
-        const val TYPE_PASSWORD_CREDENTIAL: String =
-            "android.credentials.TYPE_PASSWORD_CREDENTIAL"
+    /** Companion constants / helpers for [PasswordCredential]. */
+    companion object {
+        /** The type value for password related operations. */
+        const val TYPE_PASSWORD_CREDENTIAL: String = "android.credentials.TYPE_PASSWORD_CREDENTIAL"
 
         internal const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
         internal const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
@@ -61,7 +67,7 @@
             try {
                 val id = data.getString(BUNDLE_KEY_ID)
                 val password = data.getString(BUNDLE_KEY_PASSWORD)
-                return PasswordCredential(id!!, password!!)
+                return PasswordCredential(id!!, password!!, data)
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
             }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/PrepareGetCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/PrepareGetCredentialResponse.kt
new file mode 100644
index 0000000..baa0ffe
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/PrepareGetCredentialResponse.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials
+
+import android.Manifest.permission.CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS
+import android.credentials.PrepareGetCredentialResponse
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.annotation.RequiresPermission
+import androidx.annotation.RestrictTo
+
+/**
+ * A response object that indicates the get-credential prefetch work is complete and provides
+ * metadata about it. It can then be used to issue the full credential retrieval flow via the
+ * [CredentialManager.getCredential] (Kotlin) / [CredentialManager.getCredentialAsync] (Java)
+ * method to perform the remaining flows such as consent
+ * collection and credential selection, to officially retrieve a credential.
+ *
+ * For now this API requires Android U (level 34). However, it is designed with backward
+ * compatibility in mind and can potentially be made accessible <34 if any provider decides to
+ * support that.
+ *
+ * @property frameworkResponse the corresponding framework response, guaranteed to be nonnull
+ * at API level >= 34
+ * @property pendingGetCredentialHandle a handle that represents this pending get-credential
+ * operation; pass this handle to [CredentialManager.getCredential] (Kotlin) /
+ * [CredentialManager.getCredentialAsync] (Java) to perform the remaining flows to officially
+ * retrieve a credential.
+ * @throws NullPointerException If [frameworkResponse] is null at API level >= 34.
+ */
+@RequiresApi(34)
+class PrepareGetCredentialResponse internal constructor(
+    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    val frameworkResponse: PrepareGetCredentialResponse?,
+    val pendingGetCredentialHandle: PendingGetCredentialHandle,
+) {
+    init {
+        if (Build.VERSION.SDK_INT >= 34) { // Android U
+            frameworkResponse!!
+        }
+    }
+
+    /**
+     * Returns true if the user has any candidate credentials for the given {@code credentialType},
+     * and false otherwise.
+     *
+     * Note: this API will always return false at API level < 34.
+     */
+    @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+    fun hasCredentialResults(credentialType: String): Boolean {
+        return frameworkResponse?.hasCredentialResults(credentialType) ?: false
+    }
+
+    /**
+     * Returns true if the user has any candidate authentication actions (locked credential
+     * supplier), and false otherwise.
+     *
+     * Note: this API will always return false at API level < 34.
+     */
+    @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+    fun hasAuthenticationResults(): Boolean {
+        return frameworkResponse?.hasAuthenticationResults() ?: false
+    }
+
+    /**
+     * Returns true if the user has any candidate remote credential results, and false otherwise.
+     *
+     * Note: this API will always return false at API level < 34.
+     */
+    @RequiresPermission(CREDENTIAL_MANAGER_QUERY_CANDIDATE_CREDENTIALS)
+    fun hasRemoteResults(): Boolean {
+        return frameworkResponse?.hasRemoteResults() ?: false
+    }
+
+    /**
+     * A handle that represents a pending get-credential operation. Pass this handle to
+     * [CredentialManager.getCredential] or [CredentialManager.getCredentialAsync] to perform the
+     * remaining flows to officially retrieve a credential.
+     *
+     * @property frameworkHandle the framework handle representing this pending operation. Must not
+     * be null at API level >= 34.
+     * @throws NullPointerException If [frameworkHandle] is null at API level >= 34.
+     */
+    @RequiresApi(34)
+    class PendingGetCredentialHandle(
+        @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+        val frameworkHandle:
+        PrepareGetCredentialResponse.PendingGetCredentialHandle?
+    ) {
+        init {
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                frameworkHandle!!
+            }
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
index e90f1d3..f3789dc 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
@@ -18,6 +18,7 @@
 
 import android.os.Bundle
 import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.internal.RequestValidationHelper
 
 /**
  * Represents the user's passkey credential granted by the user for app sign-in.
@@ -25,27 +26,37 @@
  * @property authenticationResponseJson the public key credential authentication response in
  * JSON format that follows the standard webauthn json format shown at
  * [this w3c link](https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson)
- * @throws NullPointerException If [authenticationResponseJson] is null
- * @throws IllegalArgumentException If [authenticationResponseJson] is empty
  */
-class PublicKeyCredential constructor(
-    val authenticationResponseJson: String
-) : Credential(
-    TYPE_PUBLIC_KEY_CREDENTIAL,
-    toBundle(authenticationResponseJson)
-) {
+class PublicKeyCredential private constructor(
+    val authenticationResponseJson: String,
+    data: Bundle,
+) : Credential(TYPE_PUBLIC_KEY_CREDENTIAL, data) {
+
+    /**
+     * Constructs a [PublicKeyCredential].
+     *
+     * @param authenticationResponseJson the public key credential authentication response in
+     * JSON format that follows the standard webauthn json format shown at
+     * [this w3c link](https://w3c.github.io/webauthn/#dictdef-authenticationresponsejson)
+     * @throws NullPointerException If [authenticationResponseJson] is null
+     * @throws IllegalArgumentException If [authenticationResponseJson] is empty, or if it is
+     * not a valid JSON
+     */
+    constructor(
+        authenticationResponseJson: String
+    ) : this(authenticationResponseJson, toBundle(authenticationResponseJson))
 
     init {
-        require(authenticationResponseJson.isNotEmpty()) {
-            "authentication response JSON must not be empty" }
+        require(RequestValidationHelper.isValidJSON(authenticationResponseJson)) {
+            "authenticationResponseJson must not be empty, and must be a valid JSON" }
     }
 
-    internal companion object {
-        /**
-         * The type value for public key credential related operations.
-         */
-        internal const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
+    /** Companion constants / helpers for [PublicKeyCredential]. */
+    companion object {
+        /** The type value for public key credential related operations. */
+        const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
             "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
+
         /** The Bundle key value for the public key credential subtype (privileged or regular). */
         internal const val BUNDLE_KEY_SUBTYPE = "androidx.credentials.BUNDLE_KEY_SUBTYPE"
         internal const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
@@ -63,7 +74,7 @@
             try {
                 val authenticationResponseJson =
                     data.getString(BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON)
-                return PublicKeyCredential(authenticationResponseJson!!)
+                return PublicKeyCredential(authenticationResponseJson!!, data)
             } catch (e: Exception) {
                 throw FrameworkClassParsingException()
             }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/AbortError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/AbortError.kt
index 07decbe..dee644b 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/AbortError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/AbortError.kt
@@ -16,16 +16,12 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an abort-err from the fido spec, indicating the operation was aborted. The
  * fido spec can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class AbortError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_ABORT_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ConstraintError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ConstraintError.kt
index 974d005..f6cb08a 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ConstraintError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ConstraintError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a constraint_err from the fido spec, indicating that some mutation operation
  * occurring during a transaction failed by not satisfying constraints. The
  * fido spec can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class ConstraintError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_CONSTRAINT_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataCloneError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataCloneError.kt
index 2a85a7f..b9bb35f 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataCloneError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataCloneError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a data_clone_err from the fido spec, indicating the object cannot be
  * cloned. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class DataCloneError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_DATA_CLONE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataError.kt
index a64dac5..334f169 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/DataError.kt
@@ -16,8 +16,6 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a data_err code from the fido spec, indicating inadequate data provided. The
@@ -25,7 +23,7 @@
  *
  * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class DataError : DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_DATA_ERROR) {
     internal companion object {
         internal const val TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_DATA_ERROR: String =
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/EncodingError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/EncodingError.kt
index 064393c..288ded0 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/EncodingError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/EncodingError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an encoding_err code from the fido spec, indicating failure in encoding or
  * decoding operations. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class EncodingError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_ENCODING_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/HierarchyRequestError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/HierarchyRequestError.kt
index 2fe4fa1..f676b25 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/HierarchyRequestError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/HierarchyRequestError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a hierarchy_request_err from the fido spec, indicating the operation would
  * yield in an incorrect node tree. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class HierarchyRequestError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_HIERARCHY_REQUEST_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InUseAttributeError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InUseAttributeError.kt
index a65a88e..56de3f6 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InUseAttributeError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InUseAttributeError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an inuse_attribute_err from the fido spec, indicating that an attribute
  * is in used by another element. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class InUseAttributeError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_IN_USE_ATTRIBUTE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidCharacterError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidCharacterError.kt
index 7a84d8c..e35872e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidCharacterError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidCharacterError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an invalid_character_err from the fido spec, indicating a string contains
  * invalid characters. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class InvalidCharacterError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_CHARACTER_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidModificationError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidModificationError.kt
index 52c19ba..29a6ff8 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidModificationError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidModificationError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an invalid_modification_err from the fido spec, indicating an object was
  * incorrectly modified. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class InvalidModificationError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_MODIFICATION_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidNodeTypeError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidNodeTypeError.kt
index 6acd286..c5dd16c 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidNodeTypeError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidNodeTypeError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains an invalid_node_type_err from the fido spec, indicating tthe supplied node is
  * incorrect or has an incorrect ancestor for this operation. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class InvalidNodeTypeError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_NODE_TYPE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidStateError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidStateError.kt
index 11385b4..472d378 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidStateError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/InvalidStateError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a invalid_state_err code from the fido spec, indicating the object reached an
  * invalid state. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class InvalidStateError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_INVALID_STATE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NamespaceError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NamespaceError.kt
index 9e35610..0a17765 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NamespaceError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NamespaceError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a namespace_err from the fido spec, indicating the operation is not allowed
  * by namespaces in XML. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NamespaceError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NAMESPACE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NetworkError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NetworkError.kt
index 7e94ef7..c571e88 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NetworkError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NetworkError.kt
@@ -16,16 +16,12 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a network_err code from the fido spec, indicating a network error occurred.
  * The fido spec can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NetworkError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NETWORK_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NoModificationAllowedError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NoModificationAllowedError.kt
index eb505e1..0186cf4 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NoModificationAllowedError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NoModificationAllowedError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a no_modification_allowed_err from the fido spec, indicating the object
  * can not be modified. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NoModificationAllowedError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NO_MODIFICATION_ALLOWED_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotAllowedError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotAllowedError.kt
index c5474e7c..756998e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotAllowedError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotAllowedError.kt
@@ -16,18 +16,14 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a not_allowed_err code from the fido spec, indicating a request is not allowed
  * by the user agent or the platform in the current context - possibly because the user denied
  * permission. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NotAllowedError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_ALLOWED_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotFoundError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotFoundError.kt
index 16bf573..25d974c 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotFoundError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotFoundError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a not_found_err from the fido spec, indicating the object could not be found
  * in the current flow. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NotFoundError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_FOUND_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotReadableError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotReadableError.kt
index 49be851..312506c 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotReadableError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotReadableError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a NotReadableError from fido, which indicates there was some I/O read
  * operation that failed. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NotReadableError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_READABLE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotSupportedError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotSupportedError.kt
index ebb99fb..eff95cf 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotSupportedError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/NotSupportedError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a not_supported_err code from the fido spec, indicating the operation is not
  * supported. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class NotSupportedError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_NOT_SUPPORTED_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OperationError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OperationError.kt
index 1dbb790..f55f92d 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OperationError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OperationError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains and operation_err from the fido spec, indicating the operation failed for an
  * operation-specific reason. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class OperationError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_OPERATION_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OptOutError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OptOutError.kt
index 6930e15..e45d315 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OptOutError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/OptOutError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains and  opt_out_error from the fido spec, indicating the user opted out of the
  * process. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class OptOutError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_OPT_OUT_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/QuotaExceededError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/QuotaExceededError.kt
index 64e26c5..c00f181 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/QuotaExceededError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/QuotaExceededError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a quota_exceeded_err from the fido spec, indicating the quota has been
  * exceeded. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class QuotaExceededError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_QUOTA_EXCEEDED_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ReadOnlyError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ReadOnlyError.kt
index 48a257d..692ee25 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ReadOnlyError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/ReadOnlyError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a read_only_err from the fido spec, indicating a mutating operation was
  * attempted in a "readonly" transaction. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class ReadOnlyError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_READ_ONLY_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SecurityError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SecurityError.kt
index 2243f52b..47edb55 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SecurityError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SecurityError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a security_err code from the fido spec, indicating the operation is not
  * secure. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class SecurityError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_SECURITY_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SyntaxError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SyntaxError.kt
index 5f57a88..ef01d77 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SyntaxError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/SyntaxError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a syntax_err from the fido spec, indicating the string did not match the
  * expected pattern. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class SyntaxError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_SYNTAX_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TimeoutError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TimeoutError.kt
index 0de2480..f37cb1e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TimeoutError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TimeoutError.kt
@@ -16,16 +16,12 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a timeout_err code from the fido spec, indicating the operation timed out.
  * The fido spec can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class TimeoutError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_TIMEOUT_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TransactionInactiveError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TransactionInactiveError.kt
index 2cfa180..fd1dbcd 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TransactionInactiveError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/TransactionInactiveError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains and transaction_inactive_err from the fido spec, indicating a request
  * was placed against a transaction which is currently not active. The
  * fido spec can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class TransactionInactiveError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_TRANSACTION_INACTIVE_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/UnknownError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/UnknownError.kt
index 3e99a8f..70f8db2 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/UnknownError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/UnknownError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * This is thrown when the create public key credential operation failed with no more detailed
  * information. This could be something such as out of memory or some other transient reason -
  * either from fido directly or through the public key credential flow in general. The fido spec
  * can be found [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class UnknownError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_UNKNOWN_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/VersionError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/VersionError.kt
index b160edb..39b12f1 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/VersionError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/VersionError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a version_err from the fido spec, indicating an attempt was made to open
  * a database using a lower version than the existing version. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class VersionError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_VERSION_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/WrongDocumentError.kt b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/WrongDocumentError.kt
index 6a54a25..0040020 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/WrongDocumentError.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/exceptions/domerrors/WrongDocumentError.kt
@@ -16,17 +16,13 @@
 
 package androidx.credentials.exceptions.domerrors
 
-import androidx.credentials.exceptions.publickeycredential.CreatePublicKeyCredentialDomException
-
 /**
  * During the create public key credential flow, this is thrown when an authenticator response
  * exception contains a wrong_document_err from the fido spec, indicating the object is the wrong
  * document. The fido spec can be found
  * [here](https://webidl.spec.whatwg.org/#idl-DOMException-error-names).
- *
- * @see CreatePublicKeyCredentialDomException
  */
-@Suppress("ExtendsError")
+@Suppress("ExtendsError") // This is not a real java `Error`
 class WrongDocumentError :
     DomError(TYPE_CREATE_PUBLIC_KEY_CREDENTIAL_WRONG_DOCUMENT_ERROR) {
     internal companion object {
diff --git a/credentials/credentials/src/main/java/androidx/credentials/internal/FrameworkImplHelper.kt b/credentials/credentials/src/main/java/androidx/credentials/internal/FrameworkImplHelper.kt
index d3bdf01..9d9f7b2 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/internal/FrameworkImplHelper.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/internal/FrameworkImplHelper.kt
@@ -37,14 +37,14 @@
         @RequiresApi(23)
         fun getFinalCreateCredentialData(
             request: CreateCredentialRequest,
-            activity: Context,
+            context: Context,
         ): Bundle {
             val createCredentialData = request.credentialData
             val displayInfoBundle = request.displayInfo.toBundle()
             displayInfoBundle.putParcelable(
                 CreateCredentialRequest.DisplayInfo.BUNDLE_KEY_CREDENTIAL_TYPE_ICON,
                 Icon.createWithResource(
-                    activity,
+                    context,
                     when (request) {
                         is CreatePasswordRequest -> R.drawable.ic_password
                         is CreatePublicKeyCredentialRequest -> R.drawable.ic_passkey
diff --git a/credentials/credentials/src/main/java/androidx/credentials/internal/RequestValidationHelper.kt b/credentials/credentials/src/main/java/androidx/credentials/internal/RequestValidationHelper.kt
new file mode 100644
index 0000000..7c281d9
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/internal/RequestValidationHelper.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.credentials.internal
+
+import androidx.annotation.RestrictTo
+import org.json.JSONObject
+
+internal class RequestValidationHelper {
+    companion object {
+        /**
+         * Determines whether the given string is a valid JSON.
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        fun isValidJSON(jsonString: String): Boolean {
+            if (jsonString.isEmpty()) {
+                return false
+            }
+            return try {
+                JSONObject(jsonString)
+                true
+            } catch (ex: Exception) {
+                false
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/Action.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/Action.kt
new file mode 100644
index 0000000..2ef577c
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/Action.kt
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.net.Uri
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import java.util.Collections
+
+/**
+ * An actionable entry that is returned as part of the
+ * [android.service.credentials.BeginGetCredentialResponse], and then shown on the user selector
+ * under a separate category of 'Actions'.
+ * An action entry is expected to navigate the user to an activity belonging to the credential
+ * provider, and finally result in a [androidx.credentials.GetCredentialResponse].
+ *
+ * When selected, the associated [PendingIntent] is invoked to launch a provider controlled
+ * activity. The activity invoked due to this pending intent will contain the
+ * [android.service.credentials.BeginGetCredentialRequest] as part of the intent extras. Providers
+ * must use [PendingIntentHandler.retrieveBeginGetCredentialRequest] to get the request.
+ *
+ * When the user is done interacting with the activity and the provider has a credential to return,
+ * provider must call [android.app.Activity.setResult] with the result code as
+ * [android.app.Activity.RESULT_OK], and the [android.content.Intent] data that has been prepared
+ * by setting [androidx.credentials.GetCredentialResponse] using
+ * [PendingIntentHandler.setGetCredentialResponse], or by setting
+ * [androidx.credentials.exceptions.GetCredentialException] using
+ * [PendingIntentHandler.setGetCredentialException] before ending the activity.
+ * If the provider does not have a credential, or an exception to return, provider must call
+ * [android.app.Activity.setResult] with the result code as [android.app.Activity.RESULT_CANCELED].
+ * Setting the result code to [android.app.Activity.RESULT_CANCELED] will re-surface the selector.
+ *
+ * Examples of [Action] entries include an entry that is titled 'Add a new Password', and navigates
+ * to the 'add password' page of the credential provider app, or an entry that is titled
+ * 'Manage Credentials' and navigates to a particular page that lists all credentials, where the
+ * user may end up selecting a credential that the provider can then return.
+ *
+ * @constructor constructs an instance of [Action]
+ *
+ * @param title the title of the entry
+ * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * authentication entry on the UI, must be created with flag [PendingIntent.FLAG_MUTABLE] so
+ * that the system can add the complete request to the extras of the associated intent
+ * @param subtitle the optional subtitle that is displayed on the entry
+ *
+ * @see android.service.credentials.BeginGetCredentialResponse for usage.
+ *
+ * @throws IllegalArgumentException If [title] is empty
+ * @throws NullPointerException If [title] or [pendingIntent] is null
+ */
+class Action constructor(
+    val title: CharSequence,
+    val pendingIntent: PendingIntent,
+    val subtitle: CharSequence? = null,
+) {
+
+    init {
+        require(title.isNotEmpty()) { "title must not be empty" }
+    }
+
+    /**
+     * A builder for [Action]
+     *
+     * @param title the title of this action entry
+     * @param pendingIntent the [PendingIntent] that will be fired when the user selects
+     * this action entry
+     */
+    class Builder constructor(
+        private val title: CharSequence,
+        private val pendingIntent: PendingIntent
+    ) {
+        private var subtitle: CharSequence? = null
+
+        /** Sets a sub title to be shown on the UI with this entry */
+        fun setSubtitle(subtitle: CharSequence?): Builder {
+            this.subtitle = subtitle
+            return this
+        }
+
+        /**
+         * Builds an instance of [Action]
+         *
+         * @throws IllegalArgumentException If [title] is empty
+         */
+        fun build(): Action {
+            return Action(title, pendingIntent, subtitle)
+        }
+    }
+
+    internal companion object {
+        private const val TAG = "Action"
+        private const val SLICE_SPEC_REVISION = 0
+        private const val SLICE_SPEC_TYPE = "Action"
+
+        private const val SLICE_HINT_TITLE =
+            "androidx.credentials.provider.action.HINT_ACTION_TITLE"
+
+        private const val SLICE_HINT_SUBTITLE =
+            "androidx.credentials.provider.action.HINT_ACTION_SUBTEXT"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.action.SLICE_HINT_PENDING_INTENT"
+
+        /**
+         * Converts to slice
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        @RequiresApi(28)
+        fun toSlice(
+            action: Action
+        ): Slice {
+            val title = action.title
+            val subtitle = action.subtitle
+            val pendingIntent = action.pendingIntent
+            val sliceBuilder = Slice.Builder(
+                Uri.EMPTY, SliceSpec(
+                    SLICE_SPEC_TYPE, SLICE_SPEC_REVISION
+                )
+            )
+                .addText(
+                    title, /*subType=*/null,
+                    listOf(SLICE_HINT_TITLE)
+                )
+                .addText(
+                    subtitle, /*subType=*/null,
+                    listOf(SLICE_HINT_SUBTITLE)
+                )
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(),
+                /*subType=*/null
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [Action] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         *
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): Action? {
+            var title: CharSequence = ""
+            var subtitle: CharSequence? = null
+            var pendingIntent: PendingIntent? = null
+
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_TITLE)) {
+                    title = it.text
+                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {
+                    subtitle = it.text
+                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                }
+            }
+
+            return try {
+                Action(title, pendingIntent!!, subtitle)
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/AuthenticationAction.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/AuthenticationAction.kt
new file mode 100644
index 0000000..beb3038
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/AuthenticationAction.kt
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.net.Uri
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import java.util.Collections
+
+/**
+ * An entry on the selector, denoting that the provider service is locked and authentication
+ * is needed to proceed.
+ *
+ * Providers should set this entry when the provider app is locked, and no credentials can
+ * be returned.
+ * Providers must set the [PendingIntent] that leads to their unlock activity. When the user
+ * selects this entry, the corresponding [PendingIntent] is fired and the unlock activity is
+ * invoked.
+ *
+ * When the user is done with the authentication flow and the provider has  credential entries
+ * to return, provider must call [android.app.Activity.setResult] with the result code as
+ * [android.app.Activity.RESULT_OK], and the [android.content.Intent] data that has been prepared
+ * by setting [BeginGetCredentialResponse] using
+ * [PendingIntentHandler.setBeginGetCredentialResponse], or by setting
+ * [androidx.credentials.exceptions.GetCredentialException] using
+ * [PendingIntentHandler.setGetCredentialException] before ending the activity.
+ * If the provider does not have a credential, or an exception to return, provider must call
+ * [android.app.Activity.setResult] with the result code as [android.app.Activity.RESULT_CANCELED].
+ * Setting the result code to [android.app.Activity.RESULT_CANCELED] will re-surface the selector,
+ * with this authentication action labeled as having no valid credentials.
+ *
+ * @constructor constructs an instance of [AuthenticationAction]
+ *
+ * @param title the title to be shown with this entry on the account selector UI
+ * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * authentication entry on the UI, must be created with flag [PendingIntent.FLAG_MUTABLE] so
+ * that the system can add the complete request to the extras of the associated intent
+ *
+ * @see android.service.credentials.BeginGetCredentialResponse
+ * for more usage details.
+ *
+ * @throws NullPointerException If the [pendingIntent] or [title] is null
+ * @throws IllegalArgumentException If the [title] is empty
+ */
+class AuthenticationAction constructor(
+    val title: CharSequence,
+    val pendingIntent: PendingIntent,
+) {
+    init {
+        require(title.isNotEmpty()) { "title must not be empty" }
+    }
+
+    /**
+     * A builder for [AuthenticationAction]
+     *
+     * @param title the title to be displayed with this authentication action entry
+     * @param pendingIntent the [PendingIntent] that will be fired when the user selects
+     * this entry
+     */
+    class Builder constructor(
+        private val title: CharSequence,
+        private val pendingIntent: PendingIntent
+    ) {
+        /**
+         * Builds an instance of [AuthenticationAction]
+         */
+        fun build(): AuthenticationAction {
+            return AuthenticationAction(title, pendingIntent)
+        }
+    }
+
+    internal companion object {
+        private const val TAG = "AuthenticationAction"
+        private const val SLICE_SPEC_REVISION = 0
+        private const val SLICE_SPEC_TYPE = "AuthenticationAction"
+
+        private const val SLICE_HINT_TITLE =
+            "androidx.credentials.provider.authenticationAction.SLICE_HINT_TITLE"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.authenticationAction.SLICE_HINT_PENDING_INTENT"
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @JvmStatic
+        fun toSlice(authenticationAction: AuthenticationAction): Slice {
+            val title = authenticationAction.title
+            val pendingIntent = authenticationAction.pendingIntent
+            val sliceBuilder = Slice.Builder(
+                Uri.EMPTY, SliceSpec(
+                    SLICE_SPEC_TYPE,
+                    SLICE_SPEC_REVISION
+                )
+            )
+            sliceBuilder
+                .addAction(
+                    pendingIntent,
+                    Slice.Builder(sliceBuilder)
+                        .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                        .build(),
+                    /*subType=*/null
+                )
+                .addText(title, /*subType=*/null, listOf(SLICE_HINT_TITLE))
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [AuthenticationAction] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object that contains the information required for
+         * constructing an instance of this class.
+         *
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): AuthenticationAction? {
+            var title: CharSequence? = null
+            var pendingIntent: PendingIntent? = null
+
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                } else if (it.hasHint(SLICE_HINT_TITLE)) {
+                    title = it.text
+                }
+            }
+            return try {
+                AuthenticationAction(title!!, pendingIntent!!)
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialRequest.kt
new file mode 100644
index 0000000..73a1935
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialRequest.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Build
+import android.os.Bundle
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.credentials.provider.utils.BeginCreateCredentialUtil
+
+/**
+ * Abstract request class for beginning a create credential request.
+ *
+ * This class is to be extended by structured create credential requests
+ * such as [BeginCreatePasswordCredentialRequest].
+ */
+abstract class BeginCreateCredentialRequest constructor(
+    val type: String,
+    val candidateQueryData: Bundle,
+    val callingAppInfo: CallingAppInfo?
+) {
+    @RequiresApi(34)
+    private object Api34Impl {
+        private const val REQUEST_KEY = "androidx.credentials.provider.BeginCreateCredentialRequest"
+
+        @JvmStatic
+        @DoNotInline
+        fun asBundle(bundle: Bundle, request: BeginCreateCredentialRequest) {
+            bundle.putParcelable(
+                REQUEST_KEY,
+                BeginCreateCredentialUtil.convertToFrameworkRequest(request)
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun fromBundle(bundle: Bundle): BeginCreateCredentialRequest? {
+            val frameworkRequest = bundle.getParcelable(
+                REQUEST_KEY,
+                android.service.credentials.BeginCreateCredentialRequest::class.java
+            )
+            if (frameworkRequest != null) {
+                return BeginCreateCredentialUtil.convertToJetpackRequest(frameworkRequest)
+            }
+            return null
+        }
+    }
+
+    companion object {
+        /**
+         * Helper method to convert the class to a parcelable [Bundle], in case the class
+         * instance needs to be sent across a process. Consumers of this method should use
+         * [fromBundle] to reconstruct the class instance back from the bundle returned here.
+         */
+        @JvmStatic
+        fun asBundle(request: BeginCreateCredentialRequest): Bundle {
+            val bundle = Bundle()
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.asBundle(bundle, request)
+            }
+            return bundle
+        }
+
+        /**
+         * Helper method to convert a [Bundle] retrieved through [asBundle], back
+         * to an instance of [BeginCreateCredentialRequest].
+         */
+        @JvmStatic
+        fun fromBundle(bundle: Bundle): BeginCreateCredentialRequest? {
+            return if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.fromBundle(bundle)
+            } else {
+                null
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialResponse.kt
new file mode 100644
index 0000000..cc6c167
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCredentialResponse.kt
@@ -0,0 +1,162 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Build
+import android.os.Bundle
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.credentials.provider.utils.BeginCreateCredentialUtil
+
+/**
+ * Response to [BeginCreateCredentialRequest].
+ *
+ * Credential providers must add a list of [CreateEntry], and an
+ * optional [RemoteEntry] to this response.
+ *
+ * Each [CreateEntry] is displayed to the user on the account selector,
+ * as an account option where the given credential can be stored.
+ * A [RemoteEntry] is an entry on the selector, through which user can choose
+ * to create the credential on a remote device.
+ */
+class BeginCreateCredentialResponse constructor(
+    val createEntries: List<CreateEntry> = listOf(),
+    val remoteEntry: RemoteEntry? = null
+) {
+
+    /** Builder for [BeginCreateCredentialResponse]. **/
+    class Builder {
+        private var createEntries: MutableList<CreateEntry> = mutableListOf()
+        private var remoteEntry: RemoteEntry? = null
+
+        /**
+         * Sets the list of create entries to be shown on the UI.
+         *
+         * @throws IllegalArgumentException If [createEntries] is empty.
+         * @throws NullPointerException If [createEntries] is null, or any of its elements
+         * are null.
+         */
+        fun setCreateEntries(createEntries: List<CreateEntry>): Builder {
+            this.createEntries = createEntries.toMutableList()
+            return this
+        }
+
+        /**
+         * Adds an entry to the list of create entries to be shown on the UI.
+         *
+         * @throws NullPointerException If [createEntry] is null.
+         */
+        fun addCreateEntry(createEntry: CreateEntry): Builder {
+            createEntries.add(createEntry)
+            return this
+        }
+
+        /**
+         * Sets a remote create entry to be shown on the UI. Provider must set this entry if they
+         * wish to create the credential on a different device.
+         *
+         * <p> When constructing the {@link CreateEntry] object, the pending intent must be
+         * set such that it leads to an activity that can provide UI to fulfill the request on
+         * a remote device. When user selects this [remoteEntry], the system will
+         * invoke the pending intent set on the [CreateEntry].
+         *
+         * <p> Once the remote credential flow is complete, the [android.app.Activity]
+         * result should be set to [android.app.Activity#RESULT_OK] and an extra with the
+         * [CredentialProviderService#EXTRA_CREATE_CREDENTIAL_RESPONSE] key should be populated
+         * with a [android.credentials.CreateCredentialResponse] object.
+         *
+         * <p> Note that as a provider service you will only be able to set a remote entry if :
+         * - Provider service possesses the
+         * [android.Manifest.permission.PROVIDE_REMOTE_CREDENTIALS] permission.
+         * - Provider service is configured as the provider that can provide remote entries.
+         *
+         * If the above conditions are not met, setting back [BeginCreateCredentialResponse]
+         * on the callback from [CredentialProviderService#onBeginCreateCredential]
+         * will throw a [SecurityException].
+         */
+        fun setRemoteEntry(remoteEntry: RemoteEntry?): Builder {
+            this.remoteEntry = remoteEntry
+            return this
+        }
+
+        /**
+         * Builds a new instance of [BeginCreateCredentialResponse].
+         *
+         * @throws IllegalArgumentException If [createEntries] is empty
+         */
+        fun build(): BeginCreateCredentialResponse {
+            return BeginCreateCredentialResponse(createEntries.toList(), remoteEntry)
+        }
+    }
+
+    @RequiresApi(34)
+    private object Api34Impl {
+        private const val REQUEST_KEY =
+            "androidx.credentials.provider.BeginCreateCredentialResponse"
+
+        @JvmStatic
+        @DoNotInline
+        fun asBundle(bundle: Bundle, response: BeginCreateCredentialResponse) {
+            bundle.putParcelable(
+                REQUEST_KEY,
+                BeginCreateCredentialUtil.convertToFrameworkResponse(response)
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun fromBundle(bundle: Bundle): BeginCreateCredentialResponse? {
+            val frameworkResponse = bundle.getParcelable(
+                REQUEST_KEY,
+                android.service.credentials.BeginCreateCredentialResponse::class.java
+            )
+            if (frameworkResponse != null) {
+                return BeginCreateCredentialUtil.convertToJetpackResponse(frameworkResponse)
+            }
+            return null
+        }
+    }
+
+    companion object {
+        /**
+         * Helper method to convert the class to a parcelable [Bundle], in case the class
+         * instance needs to be sent across a process. Consumers of this method should use
+         * [fromBundle] to reconstruct the class instance back from the bundle returned here.
+         */
+        @JvmStatic
+        fun asBundle(response: BeginCreateCredentialResponse): Bundle {
+            val bundle = Bundle()
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.asBundle(bundle, response)
+            }
+            return bundle
+        }
+
+        /**
+         * Helper method to convert a [Bundle] retrieved through [asBundle], back
+         * to an instance of [BeginGetCredentialResponse].
+         */
+        @JvmStatic
+        fun fromBundle(bundle: Bundle): BeginCreateCredentialResponse? {
+            return if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.fromBundle(bundle)
+            } else {
+                null
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCustomCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCustomCredentialRequest.kt
new file mode 100644
index 0000000..0ee1b04
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreateCustomCredentialRequest.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Bundle
+
+/**
+ * Base custom begin create request class for registering a credential.
+ *
+ * If you get a [BeginCreateCustomCredentialRequest] instead of a type-safe request class such as
+ * [BeginCreatePasswordCredentialRequest], [BeginCreatePublicKeyCredentialRequest], etc., then
+ * as a credential provider, you should check if you have any other library of interest that
+ * supports this custom [type] of credential request,
+ * and if so use its parsing utilities to resolve to a type-safe class within that library.
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ *
+ * @constructor constructs an instance of [BeginCreateCustomCredentialRequest]
+ *
+ * @param type the credential type determined by the credential-type-specific subclass for
+ * custom use cases
+ * @param candidateQueryData the partial request data in the [Bundle] format that will be sent
+ * to the provider during the initial candidate query stage, which should not contain sensitive
+ * user credential information (note: bundle keys in the form of `androidx.credentials.*` are
+ * reserved for internal library use)
+ * @param callingAppInfo info pertaining to the app that is requesting for credentials
+ * retrieval or creation
+ *
+ * @throws IllegalArgumentException If [type] is empty
+ * @throws NullPointerException If [type], or [candidateQueryData] is null
+ */
+open class BeginCreateCustomCredentialRequest constructor(
+    type: String,
+    candidateQueryData: Bundle,
+    callingAppInfo: CallingAppInfo?
+) : BeginCreateCredentialRequest(type, candidateQueryData, callingAppInfo) {
+    init {
+        require(type.isNotEmpty()) { "type should not be empty" }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePasswordCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePasswordCredentialRequest.kt
new file mode 100644
index 0000000..fa270a2
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePasswordCredentialRequest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.os.Bundle
+import androidx.credentials.CreatePasswordRequest
+import androidx.credentials.PasswordCredential
+import androidx.credentials.internal.FrameworkClassParsingException
+
+/**
+ * Request to begin saving a password credential, received by the provider with a
+ * CredentialProviderBaseService.onBeginCreateCredentialRequest call.
+ *
+ * This request will not contain all parameters needed to store the password. Provider must
+ * use the initial parameters to determine if the password can be stored, and return a
+ * [BeginGetCredentialResponse] containing a list of [CreateEntry], denoting the
+ * accounts/groups where the password can be stored.
+ * When user selects one of the returned [CreateEntry], the corresponding [PendingIntent] set on
+ * the [CreateEntry] will be fired. The [Intent] invoked through the [PendingIntent] will
+ * contain the complete [CreatePasswordRequest] as part of its extras, to be retrieved by
+ * passing the intent to [PendingIntentHandler.retrieveProviderCreateCredentialRequest].
+ * This request will contain all required parameters needed to actually store the password.
+ *
+ * @see BeginCreateCredentialRequest
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ *
+ * @constructor constructs an instance of [BeginCreatePasswordCredentialRequest]
+ *
+ * @param callingAppInfo the information associated with the requesting for the credentials
+ * @param candidateQueryData the bundle containing raw key-value pairs coming from the app
+ * requesting the credentials, mostly to be ignored for a password request, and only to be used
+ * if the credential provider knows of some custom attributes being provided by a
+ * particular calling app
+ *
+ * @throws NullPointerException If [candidateQueryData] is null
+ */
+class BeginCreatePasswordCredentialRequest constructor(
+    callingAppInfo: CallingAppInfo?,
+    candidateQueryData: Bundle
+) : BeginCreateCredentialRequest(
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    candidateQueryData,
+    callingAppInfo,
+) {
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(data: Bundle, callingAppInfo: CallingAppInfo?):
+            BeginCreatePasswordCredentialRequest {
+            try {
+                return BeginCreatePasswordCredentialRequest(
+                    callingAppInfo, data)
+            } catch (e: Exception) {
+                throw FrameworkClassParsingException()
+            }
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequest.kt
new file mode 100644
index 0000000..41a07cf
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginCreatePublicKeyCredentialRequest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.app.PendingIntent
+import android.content.Intent
+import android.os.Bundle
+import androidx.credentials.CreatePublicKeyCredentialRequest
+import androidx.credentials.CreatePublicKeyCredentialRequest.Companion.BUNDLE_KEY_CLIENT_DATA_HASH
+import androidx.credentials.CreatePublicKeyCredentialRequest.Companion.BUNDLE_KEY_REQUEST_JSON
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.provider.utils.RequestValidationUtil
+
+/**
+ * Request to begin registering a public key credential.
+ *
+ * This request will not contain all parameters needed to create the public key. Provider must
+ * use the initial parameters to determine if the public key can be created, and return a
+ * [BeginCreateCredentialResponse] containing a list of [CreateEntry], denoting the
+ * accounts/groups where the public key can be registered.
+ * When user selects one of the returned [CreateEntry], the corresponding [PendingIntent] set on
+ * the [CreateEntry] will be fired. The [Intent] invoked through the [PendingIntent] will contain
+ * the complete [CreatePublicKeyCredentialRequest]. This request will contain all required
+ * parameters to actually register a public key.
+ *
+ * @see BeginCreateCredentialRequest
+ *
+ * Note: Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ *
+ * @constructor constructs an instance of [BeginCreatePublicKeyCredentialRequest]
+ * @param requestJson the request json to be used for registering the public key credential
+ * @param callingAppInfo the information pertaining to the app requesting for credentials
+ * @param candidateQueryData the raw bundle containing the request parameters, not expected to
+ * be used directly as all basic parameters are parsed into structured properties in this class
+ * like [requestJson] and [clientDataHash]
+ * @param clientDataHash a hash that is used to verify the relying party identity, set only if
+ * [android.service.credentials.CallingAppInfo.getOrigin] is set
+ *
+ * @throws NullPointerException If [requestJson] or [candidateQueryData] is null
+ * @throws IllegalArgumentException If [requestJson] is empty, or is not a valid JSON
+ */
+class BeginCreatePublicKeyCredentialRequest @JvmOverloads constructor(
+    val requestJson: String,
+    callingAppInfo: CallingAppInfo?,
+    candidateQueryData: Bundle,
+    val clientDataHash: ByteArray? = null,
+) : BeginCreateCredentialRequest(
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    candidateQueryData,
+    callingAppInfo
+) {
+    init {
+        require(RequestValidationUtil.isValidJSON(requestJson)) { "requestJson must not " +
+            "be empty, and must be a valid JSON" }
+        initiateBundle(candidateQueryData, requestJson)
+    }
+
+    private fun initiateBundle(candidateQueryData: Bundle, requestJson: String) {
+        candidateQueryData.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+    }
+
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(data: Bundle, callingAppInfo: CallingAppInfo?):
+            BeginCreatePublicKeyCredentialRequest {
+            try {
+                val requestJson = data.getString(BUNDLE_KEY_REQUEST_JSON)
+                val clientDataHash = data.getByteArray(BUNDLE_KEY_CLIENT_DATA_HASH)
+                return BeginCreatePublicKeyCredentialRequest(requestJson!!,
+                    callingAppInfo, data, clientDataHash)
+            } catch (e: Exception) {
+                throw FrameworkClassParsingException()
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialOption.kt
new file mode 100644
index 0000000..669c5a6
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialOption.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Bundle
+import androidx.credentials.PasswordCredential
+import androidx.credentials.PublicKeyCredential
+
+/**
+ * Base class that a credential provider receives during the query phase of a get-credential flow.
+ * Classes derived from this base class contain
+ * parameters required to retrieve a specific type of credential. E.g. [BeginGetPasswordOption]
+ * contains parameters required to retrieve passwords.
+ *
+ * [BeginGetCredentialRequest] will be composed of a list of [BeginGetCredentialOption]
+ * subclasses to indicate the specific credential types and configurations that the credential
+ * provider must include while building the [BeginGetCredentialResponse].
+ *
+ * @property id unique id representing this particular option, to be used while
+ * constructing the [CredentialEntry] to be set on [BeginGetCredentialResponse]
+ * @property type the type of the credential to be retrieved against this option, e.g. a
+ * [BeginGetPasswordOption] will have type [PasswordCredential.TYPE_PASSWORD_CREDENTIAL]
+ * @property candidateQueryData the parameters needed to retrieve the credentials, in the form of
+ * the raw [Bundle] - can typically be ignored by the credential provider as the required properties
+ * are already parse into the structured subclasses
+ *
+ * @throws NullPointerException If [id], [type] or [candidateQueryData] is null
+ */
+abstract class BeginGetCredentialOption internal constructor(
+    val id: String,
+    val type: String,
+    val candidateQueryData: Bundle
+) {
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(id: String, type: String, candidateQueryData: Bundle):
+            BeginGetCredentialOption {
+            return when (type) {
+                PasswordCredential.TYPE_PASSWORD_CREDENTIAL -> {
+                    BeginGetPasswordOption.createFrom(candidateQueryData, id)
+                }
+
+                PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> {
+                    BeginGetPublicKeyCredentialOption.createFrom(candidateQueryData, id)
+                }
+
+                else -> {
+                    BeginGetCustomCredentialOption(id, type, candidateQueryData)
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialRequest.kt
new file mode 100644
index 0000000..8639447
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialRequest.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Build
+import android.os.Bundle
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.credentials.provider.utils.BeginGetCredentialUtil
+
+/**
+ * Query stage request for getting user's credentials from a given credential provider.
+ *
+ * This request contains a list of [BeginGetCredentialOption] that have parameters
+ * to be used to query credentials, and return a [BeginGetCredentialResponse], containing
+ * a list [CredentialEntry] that are presented to the user on an selector.
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ *
+ * @constructor constructs an instance of [BeginGetCredentialRequest]
+ *
+ * @param beginGetCredentialOptions the list of type specific credential options to to be processed
+ * in order to produce a [BeginGetCredentialResponse]
+ * @param callingAppInfo info pertaining to the app requesting credentials
+ *
+ * @throws NullPointerException If [beginGetCredentialOptions] is null
+ */
+class BeginGetCredentialRequest @JvmOverloads constructor(
+    val beginGetCredentialOptions: List<BeginGetCredentialOption>,
+    val callingAppInfo: CallingAppInfo? = null,
+) {
+    @RequiresApi(34)
+    private object Api34Impl {
+        private const val REQUEST_KEY = "androidx.credentials.provider.BeginGetCredentialRequest"
+
+        @JvmStatic
+        @DoNotInline
+        fun asBundle(bundle: Bundle, request: BeginGetCredentialRequest) {
+            bundle.putParcelable(
+                REQUEST_KEY,
+                BeginGetCredentialUtil.convertToFrameworkRequest(request)
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun fromBundle(bundle: Bundle): BeginGetCredentialRequest? {
+            val frameworkRequest = bundle.getParcelable(
+                REQUEST_KEY,
+                android.service.credentials.BeginGetCredentialRequest::class.java
+            )
+            if (frameworkRequest != null) {
+                return BeginGetCredentialUtil.convertToJetpackRequest(frameworkRequest)
+            }
+            return null
+        }
+    }
+
+    companion object {
+        /**
+         * Helper method to convert the class to a parcelable [Bundle], in case the class
+         * instance needs to be sent across a process. Consumers of this method should use
+         * [fromBundle] to reconstruct the class instance back from the bundle returned here.
+         */
+        @JvmStatic
+        fun asBundle(request: BeginGetCredentialRequest): Bundle {
+            val bundle = Bundle()
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.asBundle(bundle, request)
+            }
+            return bundle
+        }
+
+        /**
+         * Helper method to convert a [Bundle] retrieved through [asBundle], back
+         * to an instance of [BeginGetCredentialRequest].
+         */
+        @JvmStatic
+        fun fromBundle(bundle: Bundle): BeginGetCredentialRequest? {
+            return if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.fromBundle(bundle)
+            } else {
+                null
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialResponse.kt
new file mode 100644
index 0000000..5225e5a
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCredentialResponse.kt
@@ -0,0 +1,216 @@
+/*
+ * 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.credentials.provider
+
+import android.os.Build
+import android.os.Bundle
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.credentials.provider.utils.BeginGetCredentialUtil
+
+/**
+ * Response from a credential provider to [BeginGetCredentialRequest], containing credential
+ * entries and other associated entries/data to be shown on the account selector UI.
+ *
+ * @constructor constructs an instance of [BeginGetCredentialResponse]
+ *
+ * @param credentialEntries the list of credential entries to be shown on the selector UI, whereby
+ * each entry is set to provide a potential credential corresponding to a given
+ * [BeginGetCredentialOption] from the original [BeginGetCredentialRequest]
+ * @param actions the list of action entries to be shown on the selector UI, whereby each entry
+ * is set to provide an action that the user can perform before retrieving the credential, e.g.
+ * selecting a credential from a provider UI
+ * @param authenticationActions the list of authentication actions to be shown on the selector UI,
+ * whereby each entry is set to denote an account/group that is currently locked and cannot
+ * return any credentials, allowing the user to select one of these entries and unlock another
+ * set of credentials
+ * @param remoteEntry the entry that is set to allow retrieving a credential from another device
+ */
+class BeginGetCredentialResponse constructor(
+    val credentialEntries: List<CredentialEntry> = listOf(),
+    val actions: List<Action> = listOf(),
+    val authenticationActions: List<AuthenticationAction> = listOf(),
+    val remoteEntry: RemoteEntry? = null
+) {
+    /** Builder for [BeginGetCredentialResponse]. **/
+    class Builder {
+        private var credentialEntries: MutableList<CredentialEntry> = mutableListOf()
+        private var actions: MutableList<Action> = mutableListOf()
+        private var authenticationActions: MutableList<AuthenticationAction> = mutableListOf()
+        private var remoteEntry: RemoteEntry? = null
+
+        /**
+         * Sets a remote credential entry to be shown on the UI. Provider must set this if they
+         * wish to get the credential from a different device.
+         *
+         * When constructing the [CredentialEntry] object, the pending intent
+         * must be set such that it leads to an activity that can provide UI to fulfill the request
+         * on a remote device. When user selects this [remoteEntry], the system will
+         * invoke the pending intent set on the [CredentialEntry].
+         *
+         * <p> Once the remote credential flow is complete, the [android.app.Activity]
+         * result should be set to [android.app.Activity#RESULT_OK] and an extra with the
+         * [CredentialProviderService#EXTRA_GET_CREDENTIAL_RESPONSE] key should be populated
+         * with a [android.credentials.Credential] object.
+         *
+         * <p> Note that as a provider service you will only be able to set a remote entry if :
+         * - Provider service possesses the
+         * [android.Manifest.permission.PROVIDE_REMOTE_CREDENTIALS] permission.
+         * - Provider service is configured as the provider that can provide remote entries.
+         *
+         * If the above conditions are not met, setting back [BeginGetCredentialResponse]
+         * on the callback from [CredentialProviderService#onBeginGetCredential] will
+         * throw a [SecurityException].
+         */
+        fun setRemoteEntry(remoteEntry: RemoteEntry?): Builder {
+            this.remoteEntry = remoteEntry
+            return this
+        }
+
+        /**
+         * Adds a [CredentialEntry] to the list of entries to be displayed on the UI.
+         */
+        fun addCredentialEntry(entry: CredentialEntry): Builder {
+            credentialEntries.add(entry)
+            return this
+        }
+
+        /**
+         * Sets the list of credential entries to be displayed on the account selector UI.
+         */
+        fun setCredentialEntries(entries: List<CredentialEntry>): Builder {
+            credentialEntries = entries.toMutableList()
+            return this
+        }
+
+        /**
+         * Adds an [Action] to the list of actions to be displayed on
+         * the UI.
+         *
+         * <p> An [Action] must be used for independent user actions,
+         * such as opening the app, intenting directly into a certain app activity etc. The
+         * pending intent set with the [action] must invoke the corresponding activity.
+         */
+        fun addAction(action: Action): Builder {
+            this.actions.add(action)
+            return this
+        }
+
+        /**
+         * Sets the list of actions to be displayed on the UI.
+         */
+        fun setActions(actions: List<Action>): Builder {
+            this.actions = actions.toMutableList()
+            return this
+        }
+
+        /**
+         * Add an authentication entry to be shown on the UI. Providers must set this entry if
+         * the corresponding account is locked and no underlying credentials can be returned.
+         *
+         * <p> When the user selects this [authenticationAction], the system invokes the
+         * corresponding pending intent.
+         * Once the authentication action activity is launched, and the user is authenticated,
+         * providers should create another response with [BeginGetCredentialResponse] using
+         * this time adding the unlocked credentials in the form of [CredentialEntry]'s.
+         *
+         * <p>The new response object must be set on the authentication activity's
+         * result. The result code should be set to [android.app.Activity#RESULT_OK] and
+         * the [CredentialProviderService#EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE] extra
+         * should be set with the new fully populated [BeginGetCredentialResponse] object.
+         */
+        fun addAuthenticationAction(authenticationAction: AuthenticationAction): Builder {
+            this.authenticationActions.add(authenticationAction)
+            return this
+        }
+
+        /**
+         * Sets the list of authentication entries to be displayed on the account selector UI.
+         */
+        fun setAuthenticationActions(authenticationEntries: List<AuthenticationAction>): Builder {
+            this.authenticationActions = authenticationEntries.toMutableList()
+            return this
+        }
+
+        /**
+         * Builds a [BeginGetCredentialResponse] instance.
+         */
+        fun build(): BeginGetCredentialResponse {
+            return BeginGetCredentialResponse(
+                credentialEntries.toList(),
+                actions.toList(),
+                authenticationActions.toList(),
+                remoteEntry
+            )
+        }
+    }
+
+    @RequiresApi(34)
+    private object Api34Impl {
+        private const val REQUEST_KEY = "androidx.credentials.provider.BeginGetCredentialResponse"
+
+        @JvmStatic
+        @DoNotInline
+        fun asBundle(bundle: Bundle, response: BeginGetCredentialResponse) {
+            bundle.putParcelable(
+                REQUEST_KEY,
+                BeginGetCredentialUtil.convertToFrameworkResponse(response)
+            )
+        }
+
+        @JvmStatic
+        @DoNotInline
+        fun fromBundle(bundle: Bundle): BeginGetCredentialResponse? {
+            val frameworkResponse = bundle.getParcelable(
+                REQUEST_KEY,
+                android.service.credentials.BeginGetCredentialResponse::class.java
+            )
+            if (frameworkResponse != null) {
+                return BeginGetCredentialUtil.convertToJetpackResponse(frameworkResponse)
+            }
+            return null
+        }
+    }
+
+    companion object {
+        /**
+         * Helper method to convert the class to a parcelable [Bundle], in case the class
+         * instance needs to be sent across a process. Consumers of this method should use
+         * [fromBundle] to reconstruct the class instance back from the bundle returned here.
+         */
+        @JvmStatic
+        fun asBundle(response: BeginGetCredentialResponse): Bundle {
+            val bundle = Bundle()
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                Api34Impl.asBundle(bundle, response)
+            }
+            return bundle
+        }
+
+        /**
+         * Helper method to convert a [Bundle] retrieved through [asBundle], back
+         * to an instance of [BeginGetCredentialResponse].
+         */
+        @JvmStatic
+        fun fromBundle(bundle: Bundle): BeginGetCredentialResponse? {
+            if (Build.VERSION.SDK_INT >= 34) { // Android U
+                return Api34Impl.fromBundle(bundle)
+            }
+            return null
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCustomCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCustomCredentialOption.kt
new file mode 100644
index 0000000..385f1a4
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetCustomCredentialOption.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.os.Bundle
+
+/**
+ * Allows extending custom versions of BeginGetCredentialOptions for unique use cases.
+ *
+ * If you get a [BeginGetCustomCredentialOption] instead of a type-safe option class such as
+ * [BeginGetPasswordOption], [BeginGetPublicKeyCredentialOption], etc., then you should check if
+ * you have any other library at interest that supports this custom [type] of credential option,
+ * and if so use its parsing utilities to resolve to a type-safe class within that library.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * generated for custom use cases
+ * @property candidateQueryData the partial request data in the [Bundle] format that will be sent to
+ * the provider during the initial candidate query stage, which should not contain sensitive user
+ * information
+ * @throws IllegalArgumentException If [type] is null or, empty
+ */
+open class BeginGetCustomCredentialOption constructor(
+    id: String,
+    type: String,
+    candidateQueryData: Bundle,
+) : BeginGetCredentialOption(
+    id,
+    type,
+    candidateQueryData
+) {
+    init {
+        require(id.isNotEmpty()) { "id should not be empty" }
+        require(type.isNotEmpty()) { "type should not be empty" }
+    }
+
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(
+            data: Bundle,
+            id: String,
+            type: String
+        ): BeginGetCustomCredentialOption {
+            return BeginGetCustomCredentialOption(id, type, data)
+        }
+
+        @JvmStatic
+        internal fun createFromEntrySlice(
+            data: Bundle,
+            id: String,
+            type: String
+        ): BeginGetCustomCredentialOption {
+            return BeginGetCustomCredentialOption(id, type, data)
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPasswordOption.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPasswordOption.kt
new file mode 100644
index 0000000..6ae4eed
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPasswordOption.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.os.Bundle
+import android.service.credentials.BeginGetCredentialResponse
+import androidx.credentials.GetPasswordOption
+import androidx.credentials.PasswordCredential
+
+/**
+ * A request to a password provider to begin the flow of retrieving the user's saved passwords.
+ *
+ * Providers must use the parameters in this option to retrieve the corresponding credentials'
+ * metadata, and then return them in the form of a list of [PasswordCredentialEntry]
+ * set on the [BeginGetCredentialResponse].
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ *
+ * @property allowedUserIds a optional set of user ids with which the credentials associated are
+ * requested; left as empty if the caller app wants to request all the available user credentials
+ */
+class BeginGetPasswordOption constructor(
+    val allowedUserIds: Set<String>,
+    candidateQueryData: Bundle,
+    id: String,
+) : BeginGetCredentialOption(
+    id,
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    candidateQueryData
+) {
+
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(data: Bundle, id: String): BeginGetPasswordOption {
+            val allowUserIdList = data.getStringArrayList(
+                GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS)
+            return BeginGetPasswordOption(allowUserIdList?.toSet() ?: emptySet(), data, id)
+        }
+
+        @JvmStatic
+        internal fun createFromEntrySlice(data: Bundle, id: String): BeginGetPasswordOption {
+            val allowUserIdList = data.getStringArrayList(
+                GetPasswordOption.BUNDLE_KEY_ALLOWED_USER_IDS)
+            return BeginGetPasswordOption(allowUserIdList?.toSet() ?: emptySet(), data, id)
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOption.kt
new file mode 100644
index 0000000..766aac0
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/BeginGetPublicKeyCredentialOption.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.os.Bundle
+import androidx.credentials.GetPublicKeyCredentialOption
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.provider.utils.RequestValidationUtil
+
+/**
+ * A request to begin the flow of getting passkeys from the user's public key credential provider.
+ *
+ * @constructor constructs an instance of [BeginGetPublicKeyCredentialOption]
+ *
+ * @param candidateQueryData the request data in the [Bundle] format
+ * @param id the id of this request option
+ * @param requestJson the request in JSON format in the standard webauthn web json
+ * shown [here](https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptionsjson)
+ * @param clientDataHash a hash that is used to verify the relying party identity, set only if
+ * [android.service.credentials.CallingAppInfo.getOrigin] is set
+ *
+ * @throws NullPointerException If [requestJson] is null
+ * @throws IllegalArgumentException If [requestJson] is empty
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ */
+class BeginGetPublicKeyCredentialOption @JvmOverloads constructor(
+    candidateQueryData: Bundle,
+    id: String,
+    val requestJson: String,
+    val clientDataHash: ByteArray? = null,
+) : BeginGetCredentialOption(
+    id,
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    candidateQueryData
+) {
+    init {
+        require(RequestValidationUtil.isValidJSON(requestJson)) { "requestJson must not " +
+            "be empty, and must be a valid JSON" }
+    }
+
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(data: Bundle, id: String): BeginGetPublicKeyCredentialOption {
+            try {
+                val requestJson = data.getString(GetPublicKeyCredentialOption
+                    .BUNDLE_KEY_REQUEST_JSON)
+                val clientDataHash = data.getByteArray(GetPublicKeyCredentialOption
+                    .BUNDLE_KEY_CLIENT_DATA_HASH)
+                return BeginGetPublicKeyCredentialOption(data, id, requestJson!!, clientDataHash)
+            } catch (e: Exception) {
+                throw FrameworkClassParsingException()
+            }
+        }
+
+        @JvmStatic
+        internal fun createFromEntrySlice(data: Bundle, id: String):
+            BeginGetPublicKeyCredentialOption {
+            val requestJson = "{\"dummy_key\":\"dummy_value\"}"
+            return BeginGetPublicKeyCredentialOption(data, id, requestJson)
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/CallingAppInfo.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/CallingAppInfo.kt
new file mode 100644
index 0000000..33ee07a
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/CallingAppInfo.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.credentials.provider
+
+import android.content.pm.SigningInfo
+
+/**
+ * Information pertaining to the calling application.
+ *
+ * @constructor constructs an instance of [CallingAppInfo]
+ *
+ * @param packageName the calling package name of the calling app
+ * @param signingInfo the signingInfo associated with the calling app
+ * @param origin the origin of the calling app. This is only set when a
+ * privileged app like a browser, calls on behalf of another application.
+ *
+ * @throws NullPointerException If [packageName] or [signingInfo] is null
+ * @throws IllegalArgumentException If [packageName] is empty
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ */
+class CallingAppInfo @JvmOverloads constructor(
+    val packageName: String,
+    val signingInfo: SigningInfo,
+    val origin: String? = null
+) {
+
+    init {
+        require(packageName.isNotEmpty()) { "packageName must not be empty" }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/CreateEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/CreateEntry.kt
new file mode 100644
index 0000000..e777052
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/CreateEntry.kt
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.graphics.drawable.Icon
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.CredentialManager
+import androidx.credentials.PasswordCredential
+import androidx.credentials.PublicKeyCredential
+import java.time.Instant
+import java.util.Collections
+
+/**
+ * An entry to be shown on the selector during a create flow initiated when an app calls
+ * [CredentialManager.createCredential]
+ *
+ * A [CreateEntry] points to a location such as an account, or a group where the credential can be
+ * registered. When user selects this entry, the corresponding [PendingIntent] is fired, and the
+ * credential creation can be completed.
+ *
+ * @throws IllegalArgumentException If [accountName] is empty
+ */
+@RequiresApi(28)
+class CreateEntry internal constructor(
+    val accountName: CharSequence,
+    val pendingIntent: PendingIntent,
+    val icon: Icon?,
+    val description: CharSequence?,
+    val lastUsedTime: Instant?,
+    private val credentialCountInformationMap: MutableMap<String, Int?>,
+    val isAutoSelectAllowed: Boolean
+) {
+
+    /**
+     * Creates an entry to be displayed on the selector during create flows.
+     *
+     * @constructor constructs an instance of [CreateEntry]
+     *
+     * @param accountName the name of the account where the credential will be saved
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param description the localized description shown on UI about where the credential is stored
+     * @param icon the icon to be displayed with this entry on the UI
+     * @param lastUsedTime the last time the account underlying this entry was used by the user,
+     * distinguishable up to the milli second mark only such that if two entries have the same
+     * millisecond precision, they will be considered to have been used at the same time
+     * @param passwordCredentialCount the no. of password credentials contained by the provider
+     * @param publicKeyCredentialCount the no. of public key credentials contained by the provider
+     * @param totalCredentialCount the total no. of credentials contained by the provider
+     * @param isAutoSelectAllowed whether this entry should be auto selected if it is the only
+     * entry on the selector
+     *
+     * @throws IllegalArgumentException If [accountName] is empty, or if [description] is longer
+     * than 300 characters (important: make sure your descriptions across all locales are within
+     * this limit)
+     * @throws NullPointerException If [accountName] or [pendingIntent] is null
+     */
+    constructor(
+        accountName: CharSequence,
+        pendingIntent: PendingIntent,
+        description: CharSequence? = null,
+        lastUsedTime: Instant? = null,
+        icon: Icon? = null,
+        @Suppress("AutoBoxing")
+        passwordCredentialCount: Int? = null,
+        @Suppress("AutoBoxing")
+        publicKeyCredentialCount: Int? = null,
+        @Suppress("AutoBoxing")
+        totalCredentialCount: Int? = null,
+        isAutoSelectAllowed: Boolean = false
+    ) : this(
+        accountName,
+        pendingIntent,
+        icon,
+        description,
+        lastUsedTime,
+        mutableMapOf(
+            PasswordCredential.TYPE_PASSWORD_CREDENTIAL to passwordCredentialCount,
+            PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL to publicKeyCredentialCount,
+            TYPE_TOTAL_CREDENTIAL to totalCredentialCount
+        ),
+        isAutoSelectAllowed
+    )
+
+    init {
+        require(accountName.isNotEmpty()) { "accountName must not be empty" }
+        if (description != null) {
+            require(description.length <= DESCRIPTION_MAX_CHAR_LIMIT) {
+                "Description must follow a limit of 300 characters."
+            }
+        }
+    }
+
+    /** Returns the no. of password type credentials that the provider with this entry has. */
+    @Suppress("AutoBoxing")
+    fun getPasswordCredentialCount(): Int? {
+        return credentialCountInformationMap[PasswordCredential.TYPE_PASSWORD_CREDENTIAL]
+    }
+
+    /** Returns the no. of public key type credentials that the provider with this entry has. */
+    @Suppress("AutoBoxing")
+    fun getPublicKeyCredentialCount(): Int? {
+        return credentialCountInformationMap[PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL]
+    }
+
+    /** Returns the no. of total credentials that the provider with this entry has.
+     *
+     * This total count is not necessarily equal to the sum of [getPasswordCredentialCount]
+     * and [getPublicKeyCredentialCount].
+     *
+     */
+    @Suppress("AutoBoxing")
+    fun getTotalCredentialCount(): Int? {
+        return credentialCountInformationMap[TYPE_TOTAL_CREDENTIAL]
+    }
+
+    /**
+     * A builder for [CreateEntry]
+     *
+     * @constructor constructs an instance of [CreateEntry.Builder]
+     *
+     * @param accountName the name of the account where the credential will be registered
+     * @param pendingIntent the [PendingIntent] that will be fired when the user selects
+     * this entry
+     */
+    class Builder constructor(
+        private val accountName: CharSequence,
+        private val pendingIntent: PendingIntent
+    ) {
+
+        private var credentialCountInformationMap: MutableMap<String, Int?> =
+            mutableMapOf()
+        private var icon: Icon? = null
+        private var description: CharSequence? = null
+        private var lastUsedTime: Instant? = null
+        private var passwordCredentialCount: Int? = null
+        private var publicKeyCredentialCount: Int? = null
+        private var totalCredentialCount: Int? = null
+        private var autoSelectAllowed: Boolean = false
+
+        /**
+         * Sets whether the entry should be auto-selected.
+         * The value is false by default.
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setAutoSelectAllowed(autoSelectAllowed: Boolean): Builder {
+            this.autoSelectAllowed = autoSelectAllowed
+            return this
+        }
+
+        /** Sets the password credential count, denoting how many credentials of type
+         * [PasswordCredential.TYPE_PASSWORD_CREDENTIAL] does the provider have stored.
+         *
+         * This information will be displayed on the [CreateEntry] to help the user
+         * make a choice.
+         */
+        fun setPasswordCredentialCount(count: Int): Builder {
+            passwordCredentialCount = count
+            credentialCountInformationMap[PasswordCredential.TYPE_PASSWORD_CREDENTIAL] = count
+            return this
+        }
+
+        /** Sets the password credential count, denoting how many credentials of type
+         * [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL] does the provider have stored.
+         *
+         * This information will be displayed on the [CreateEntry] to help the user
+         * make a choice.
+         */
+        fun setPublicKeyCredentialCount(count: Int): Builder {
+            publicKeyCredentialCount = count
+            credentialCountInformationMap[PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL] = count
+            return this
+        }
+
+        /** Sets the total credential count, denoting how many credentials in total
+         * does the provider have stored.
+         *
+         * This total count no. does not need to be a total of the counts set through
+         * [setPasswordCredentialCount] and [setPublicKeyCredentialCount].
+         *
+         * This information will be displayed on the [CreateEntry] to help the user
+         * make a choice.
+         */
+        fun setTotalCredentialCount(count: Int): Builder {
+            totalCredentialCount = count
+            credentialCountInformationMap[TYPE_TOTAL_CREDENTIAL] = count
+            return this
+        }
+
+        /** Sets an icon to be displayed with the entry on the UI */
+        fun setIcon(icon: Icon?): Builder {
+            this.icon = icon
+            return this
+        }
+
+        /**
+         * Sets a localized description to be displayed on the UI at the time of credential
+         * creation.
+         *
+         * Typically this description should contain information informing the user of the
+         * credential being created, and where it is being stored. Providers are free
+         * to phrase this however they see fit.
+         *
+         * @throws IllegalArgumentException if [description] is longer than 300 characters (
+         * important: make sure your descriptions across all locales are within this limit).
+         */
+        fun setDescription(description: CharSequence?): Builder {
+            if (description?.length != null && description.length > DESCRIPTION_MAX_CHAR_LIMIT) {
+                throw IllegalArgumentException("Description must follow a limit of 300 characters.")
+            }
+            this.description = description
+            return this
+        }
+
+        /** Sets the last time this account was used */
+        fun setLastUsedTime(lastUsedTime: Instant?): Builder {
+            this.lastUsedTime = lastUsedTime
+            return this
+        }
+
+        /**
+         * Builds an instance of [CreateEntry]
+         *
+         * @throws IllegalArgumentException If [accountName] is empty
+         */
+        fun build(): CreateEntry {
+            return CreateEntry(
+                accountName, pendingIntent, icon, description, lastUsedTime,
+                credentialCountInformationMap, autoSelectAllowed
+            )
+        }
+    }
+
+    internal companion object {
+        private const val TAG = "CreateEntry"
+        private const val DESCRIPTION_MAX_CHAR_LIMIT = 300
+
+        internal const val TYPE_TOTAL_CREDENTIAL = "TOTAL_CREDENTIAL_COUNT_TYPE"
+
+        private const val SLICE_HINT_ACCOUNT_NAME =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_USER_PROVIDER_ACCOUNT_NAME"
+
+        private const val SLICE_HINT_NOTE =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_NOTE"
+
+        private const val SLICE_HINT_ICON =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_PROFILE_ICON"
+
+        private const val SLICE_HINT_CREDENTIAL_COUNT_INFORMATION =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_CREDENTIAL_COUNT_INFORMATION"
+
+        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_PENDING_INTENT"
+
+        private const val SLICE_HINT_AUTO_SELECT_ALLOWED =
+            "androidx.credentials.provider.createEntry.SLICE_HINT_AUTO_SELECT_ALLOWED"
+
+        private const val AUTO_SELECT_TRUE_STRING = "true"
+
+        private const val AUTO_SELECT_FALSE_STRING = "false"
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        fun toSlice(
+            createEntry: CreateEntry
+        ): Slice {
+            val accountName = createEntry.accountName
+            val icon = createEntry.icon
+            val description = createEntry.description
+            val lastUsedTime = createEntry.lastUsedTime
+            val credentialCountInformationMap = createEntry.credentialCountInformationMap
+            val pendingIntent = createEntry.pendingIntent
+
+            // TODO("Use the right type and revision")
+            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec("type", 1))
+
+            val autoSelectAllowed = if (createEntry.isAutoSelectAllowed) {
+                AUTO_SELECT_TRUE_STRING
+            } else {
+                AUTO_SELECT_FALSE_STRING
+            }
+
+            sliceBuilder.addText(
+                accountName, /*subType=*/null,
+                listOf(SLICE_HINT_ACCOUNT_NAME)
+            )
+            if (lastUsedTime != null) {
+                sliceBuilder.addLong(
+                    lastUsedTime.toEpochMilli(), /*subType=*/null, listOf(
+                        SLICE_HINT_LAST_USED_TIME_MILLIS
+                    )
+                )
+            }
+            if (description != null) {
+                sliceBuilder.addText(
+                    description, null,
+                    listOf(SLICE_HINT_NOTE)
+                )
+            }
+            if (icon != null) {
+                sliceBuilder.addIcon(
+                    icon, /*subType=*/null,
+                    listOf(SLICE_HINT_ICON)
+                )
+            }
+            val credentialCountBundle = convertCredentialCountInfoToBundle(
+                credentialCountInformationMap
+            )
+            if (credentialCountBundle != null) {
+                sliceBuilder.addBundle(
+                    convertCredentialCountInfoToBundle(
+                        credentialCountInformationMap
+                    ), null, listOf(
+                        SLICE_HINT_CREDENTIAL_COUNT_INFORMATION
+                    )
+                )
+            }
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(),
+                /*subType=*/null
+            ).addText(
+                autoSelectAllowed, /*subType=*/null,
+                listOf(SLICE_HINT_AUTO_SELECT_ALLOWED)
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [CreateEntry] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): CreateEntry? {
+            // TODO("Put the right spec and version value")
+            var accountName: CharSequence? = null
+            var icon: Icon? = null
+            var pendingIntent: PendingIntent? = null
+            var credentialCountInfo: MutableMap<String, Int?> = mutableMapOf()
+            var description: CharSequence? = null
+            var lastUsedTime: Instant? = null
+            var autoSelectAllowed = false
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_ACCOUNT_NAME)) {
+                    accountName = it.text
+                } else if (it.hasHint(SLICE_HINT_ICON)) {
+                    icon = it.icon
+                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                } else if (it.hasHint(SLICE_HINT_CREDENTIAL_COUNT_INFORMATION)) {
+                    credentialCountInfo = convertBundleToCredentialCountInfo(it.bundle)
+                        as MutableMap<String, Int?>
+                } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
+                    lastUsedTime = Instant.ofEpochMilli(it.long)
+                } else if (it.hasHint(SLICE_HINT_NOTE)) {
+                    description = it.text
+                } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
+                    lastUsedTime = Instant.ofEpochMilli(it.long)
+                } else if (it.hasHint(SLICE_HINT_AUTO_SELECT_ALLOWED)) {
+                    val autoSelectValue = it.text
+                    if (autoSelectValue == AUTO_SELECT_TRUE_STRING) {
+                        autoSelectAllowed = true
+                    }
+                }
+            }
+            return try {
+                CreateEntry(
+                    accountName!!, pendingIntent!!, icon, description,
+                    lastUsedTime, credentialCountInfo, autoSelectAllowed
+                )
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+
+        @JvmStatic
+        internal fun convertBundleToCredentialCountInfo(bundle: Bundle?):
+            Map<String, Int?> {
+            val credentialCountMap = HashMap<String, Int?>()
+            if (bundle == null) {
+                return credentialCountMap
+            }
+            bundle.keySet().forEach {
+                try {
+                    credentialCountMap[it] = bundle.getInt(it)
+                } catch (e: Exception) {
+                    Log.i(TAG, "Issue unpacking credential count info bundle: " + e.message)
+                }
+            }
+            return credentialCountMap
+        }
+
+        @JvmStatic
+        internal fun convertCredentialCountInfoToBundle(
+            credentialCountInformationMap: Map<String, Int?>
+        ): Bundle? {
+            var foundCredentialCount = false
+            val bundle = Bundle()
+            credentialCountInformationMap.forEach {
+                if (it.value != null) {
+                    bundle.putInt(it.key, it.value!!)
+                    foundCredentialCount = true
+                }
+            }
+            if (!foundCredentialCount) {
+                return null
+            }
+            return bundle
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialEntry.kt
new file mode 100644
index 0000000..c7a4878
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialEntry.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.credentials.provider
+
+import android.app.slice.Slice
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.PasswordCredential.Companion.TYPE_PASSWORD_CREDENTIAL
+import androidx.credentials.PublicKeyCredential.Companion.TYPE_PUBLIC_KEY_CREDENTIAL
+
+/**
+ * Base class for a credential entry to be displayed on
+ * the selector.
+ */
+abstract class CredentialEntry internal constructor(
+    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    open val type: String,
+    val beginGetCredentialOption: BeginGetCredentialOption,
+    @get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    val slice: Slice
+) {
+    internal companion object {
+        @JvmStatic
+        @RequiresApi(34)
+        internal fun createFrom(slice: Slice): CredentialEntry? {
+            return try {
+                when (slice.spec?.type) {
+                    TYPE_PASSWORD_CREDENTIAL -> PasswordCredentialEntry.fromSlice(slice)!!
+                    TYPE_PUBLIC_KEY_CREDENTIAL -> PublicKeyCredentialEntry.fromSlice(slice)!!
+                    else -> CustomCredentialEntry.fromSlice(slice)!!
+                }
+            } catch (e: Exception) {
+                // Try CustomCredentialEntry.fromSlice one last time in case the cause was a failed
+                // password / passkey parsing attempt.
+                CustomCredentialEntry.fromSlice(slice)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialProviderService.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialProviderService.kt
new file mode 100644
index 0000000..27406d7
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/CredentialProviderService.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.app.Activity
+import android.app.PendingIntent
+import android.credentials.ClearCredentialStateException
+import android.credentials.GetCredentialException
+import android.os.CancellationSignal
+import android.os.OutcomeReceiver
+import android.service.credentials.ClearCredentialStateRequest
+import android.service.credentials.CredentialEntry
+import android.service.credentials.CredentialProviderService
+import androidx.annotation.RequiresApi
+import androidx.credentials.exceptions.ClearCredentialException
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.provider.utils.BeginCreateCredentialUtil
+import androidx.credentials.provider.utils.BeginGetCredentialUtil
+import androidx.credentials.provider.utils.ClearCredentialUtil
+
+/**
+ * A [CredentialProviderService] is a service used to save and retrieve credentials for a given
+ * user, upon the request of a client app that typically uses these credentials for sign-in flows.
+ *
+ * The credential retrieval and creation/saving is mediated by the Android System that
+ * aggregates credentials from multiple credential provider services, and presents them to
+ * the user in the form of a selector UI for credential selections/account selections/
+ * confirmations etc.
+ *
+ * A [CredentialProviderService] is only bound to the Android System for the span
+ * of a [androidx.credentials.CredentialManager] get/create API call. The service is bound only
+ * if :
+ *  1. The service requires the [android.Manifest.permission.BIND_CREDENTIAL_PROVIDER_SERVICE]
+ *  permission.
+ *  2. The user has enabled this service as a credential provider from the
+ *  settings.
+ *
+ *  ## Basic Usage
+ *  The basic Credential Manager flow is as such:
+ *  - Client app calls one of the APIs exposed in [androidx.credentials.CredentialManager].
+ *  - Android system propagates the developer's request to providers that have been
+ *  enabled by the user, and can support the [androidx.credentials.Credential] type
+ *  specified in the request. We call this the **query phase** of provider communication.
+ *  Developer may specify a different set of request parameters to be sent to the provider
+ *  during this phase.
+ *  - In this query phase, providers, in most cases, will respond with a list of
+ *  [CredentialEntry], and an optional list of [Action] entries (for the get flow), and a list
+ *  of [CreateEntry] (for the create flow). No actual credentials will be returned in this phase.
+ *  - Provider responses are aggregated and presented to the user in the form of a selector UI.
+ *  - User selects an entry on the selector.
+ *  - Android System invokes the [PendingIntent] associated with this entry, that belongs to the
+ *  corresponding provider. We call this the **final phase** of provider communication. The
+ *  [PendingIntent] contains the complete request originally created by the developer.
+ *  - Provider finishes the [Activity] invoked by the [PendingIntent] by setting the result
+ *  as the activity is finished.
+ *  - Android System sends back the result to the client app.
+ *
+ *  The flow described above minimizes the amount of time a service is bound to the system.
+ *  Calls to the service are considered stateless. If a service wishes to maintain state
+ *  between the calls, it must do its own state management.
+ *  Note: The service's process might be killed by the Android System when unbound, for cases
+ *  such as low memory on the device.
+ *
+ * ## Service Registration
+ * In order for Credential Manager to propagate requests to a given provider service, the provider
+ * must:
+ * - Extend this class and implement the abstract methods.
+ * - Declare the [CredentialProviderService.SERVICE_INTERFACE] intent as handled by the service.
+ * - Require the [android.Manifest.permission.BIND_CREDENTIAL_PROVIDER_SERVICE] permission.
+ * - Declare capabilities that the provider supports. Capabilities are essentially credential types
+ * that the provider can handle. Capabilities must be added to the metadata of the service against
+ * [CredentialProviderService.SERVICE_META_DATA].
+ */
+@RequiresApi(34)
+abstract class CredentialProviderService : CredentialProviderService() {
+
+    final override fun onBeginGetCredential(
+        request: android.service.credentials.BeginGetCredentialRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<
+            android.service.credentials.BeginGetCredentialResponse, GetCredentialException>
+    ) {
+        val structuredRequest = BeginGetCredentialUtil.convertToJetpackRequest(request)
+        val outcome = object : OutcomeReceiver<BeginGetCredentialResponse,
+            androidx.credentials.exceptions.GetCredentialException> {
+            override fun onResult(response: BeginGetCredentialResponse) {
+                callback.onResult(
+                    BeginGetCredentialUtil
+                        .convertToFrameworkResponse(response)
+                )
+            }
+
+            override fun onError(error: androidx.credentials.exceptions.GetCredentialException) {
+                super.onError(error)
+                // TODO("Change error code to provider error when ready on framework")
+                callback.onError(GetCredentialException(error.type, error.message))
+            }
+        }
+        this.onBeginGetCredentialRequest(structuredRequest, cancellationSignal, outcome)
+    }
+
+    final override fun onBeginCreateCredential(
+        request: android.service.credentials.BeginCreateCredentialRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<android.service.credentials.BeginCreateCredentialResponse,
+            android.credentials.CreateCredentialException>
+    ) {
+        val outcome = object : OutcomeReceiver<
+            BeginCreateCredentialResponse, CreateCredentialException> {
+            override fun onResult(response: BeginCreateCredentialResponse) {
+                callback.onResult(
+                    BeginCreateCredentialUtil
+                        .convertToFrameworkResponse(response)
+                )
+            }
+
+            override fun onError(error: CreateCredentialException) {
+                super.onError(error)
+                // TODO("Change error code to provider error when ready on framework")
+                callback.onError(
+                    android.credentials.CreateCredentialException(
+                        error.type, error.message
+                    )
+                )
+            }
+        }
+        onBeginCreateCredentialRequest(
+            BeginCreateCredentialUtil.convertToJetpackRequest(request),
+            cancellationSignal, outcome
+        )
+    }
+
+    final override fun onClearCredentialState(
+        request: ClearCredentialStateRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<Void, ClearCredentialStateException>
+    ) {
+        val outcome = object : OutcomeReceiver<Void?, ClearCredentialException> {
+            override fun onResult(response: Void?) {
+                callback.onResult(response)
+            }
+
+            override fun onError(error: ClearCredentialException) {
+                super.onError(error)
+                // TODO("Change error code to provider error when ready on framework")
+                callback.onError(ClearCredentialStateException(error.type, error.message))
+            }
+        }
+        onClearCredentialStateRequest(ClearCredentialUtil.convertToJetpackRequest(request),
+            cancellationSignal, outcome)
+    }
+
+    /**
+     * Called by the Android System in response to a client app calling
+     * [androidx.credentials.CredentialManager.clearCredentialState]. A client app typically
+     * calls this API on instances like sign-out when the intention is that the providers clear
+     * any state that they may have maintained for the given user.
+     *
+     * You should invoked this api after your user signs out of your app to notify all credential
+     * providers that any stored credential session for the given app should be cleared.
+     *
+     * An example scenario of a state that is maintained and is expected to be cleared on this
+     * call, is when an active credential session is being stored to limit sign-in options
+     * in the result of subsequent get-request calls. When a user explicitly signs out of the app,
+     * the next time, the client app may want their users to see all options and hence will call
+     * this API first to make sure credential providers can clear the state maintained previously.
+     *
+     * @param request the request for the credential provider to handle
+     * @param cancellationSignal signal for observing cancellation requests. The system will
+     * use this to notify you that the result is no longer needed and you should stop
+     * handling it in order to save your resources
+     * @param callback the callback object to be used to notify the response or error
+     */
+    abstract fun onClearCredentialStateRequest(
+        request: ProviderClearCredentialStateRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<Void?,
+            ClearCredentialException>
+    )
+
+    /**
+     * Called by the Android System in response to a client app calling
+     * [androidx.credentials.CredentialManager.getCredential], to get a credential
+     * sourced from a credential provider installed on the device.
+     *
+     * Credential provider services must extend this method in order to handle a
+     * [BeginGetCredentialRequest] request. Once processed, the service must call one of the
+     * [callback] methods to notify the result of the request.
+     *
+     * This API call is referred to as the **query phase** of the original get request from
+     * the client app. In this phase, provider must go over all the
+     * [android.service.credentials.BeginGetCredentialOption], and add corresponding a
+     * [CredentialEntry] to the [BeginGetCredentialResponse]. Each [CredentialEntry] should
+     * contain meta-data to be shown on the selector UI. In addition, each [CredentialEntry]
+     * must contain a [PendingIntent].
+     * Optionally, providers can also add [Action] entries for any non-credential related actions
+     * that they want to offer to the users e.g. opening app, managing credentials etc.
+     *
+     * When user selects one of the [CredentialEntry], **final phase** of the original client's
+     * get-request flow starts. The Android System attached the complete
+     * [androidx.credentials.provider.ProviderGetCredentialRequest] to an intent extra of the
+     * activity that is started by the pending intent. The request must be retrieved through
+     * [PendingIntentHandler.retrieveProviderGetCredentialRequest]. This final request
+     * will only contain a single [androidx.credentials.CredentialOption] that contains the
+     * parameters of the credential the user has requested. The provider service must retrieve this
+     * credential and return through [PendingIntentHandler.setGetCredentialResponse].
+     *
+     * **Handling locked provider apps**
+     * If the provider app is locked, and the provider cannot provide any meta-data based
+     * [CredentialEntry], provider must set an [AuthenticationAction] on the
+     * [BeginGetCredentialResponse]. The [PendingIntent] set on this entry must lead the user
+     * to an >unlock activity. Once unlocked, the provider must retrieve all credentials,
+     * and set the list of [CredentialEntry] and the list of optional [Action] as a result
+     * of the >unlock activity through [PendingIntentHandler.setBeginGetCredentialResponse].
+     *
+     * @see CredentialEntry for how an entry representing a credential must be built
+     * @see Action for how a non-credential related action should be built
+     * @see AuthenticationAction for how an entry that navigates the user to an unlock flow
+     * can be built
+     *
+     * @param [request] the [ProviderGetCredentialRequest] to handle
+     * See [BeginGetCredentialResponse] for the response to be returned
+     * @param cancellationSignal signal for observing cancellation requests. The system will
+     * use this to notify you that the result is no longer needed and you should stop
+     * handling it in order to save your resources
+     * @param callback the callback object to be used to notify the response or error
+     */
+    abstract fun onBeginGetCredentialRequest(
+        request: BeginGetCredentialRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<BeginGetCredentialResponse,
+            androidx.credentials.exceptions.GetCredentialException>
+    )
+
+    /**
+     * Called by the Android System in response to a client app calling
+     * [androidx.credentials.CredentialManager.createCredential], to create/save a credential
+     * with a credential provider installed on the device.
+     *
+     * Credential provider services must extend this method in order to handle a
+     * [BeginCreateCredentialRequest] request. Once processed, the service must call one of the
+     * [callback] methods to notify the result of the request.
+     *
+     * This API call is referred to as the **query phase** of the original create request from
+     * the client app. In this phase, provider must process the request parameters in the
+     * [BeginCreateCredentialRequest] and return a list of [CreateEntry] whereby every
+     * entry represents an account/group where the user will be storing the credential. Each
+     * [CreateEntry] must contain a [PendingIntent] that will lead the user to an activity
+     * in the credential provider's app that will complete the actual credential creation.
+     *
+     * When user selects one of the [CreateEntry], the associated [PendingIntent] will be invoked
+     * and the provider will receive the complete request as part of the extras in the resulting
+     * activity. Provider must retrieve the request through
+     * [PendingIntentHandler.retrieveProviderCreateCredentialRequest].
+     * Once the activity is complete, and the credential is created, provider must set back the
+     * response through [PendingIntentHandler.setCreateCredentialResponse].
+     *
+     * @param [request] the [BeginCreateCredentialRequest] to handle
+     * See [BeginCreateCredentialResponse] for the response to be returned
+     * @param cancellationSignal signal for observing cancellation requests. The system will
+     * use this to notify you that the result is no longer needed and you should stop
+     * handling it in order to save your resources
+     * @param callback the callback object to be used to notify the response or error
+     */
+    abstract fun onBeginCreateCredentialRequest(
+        request: BeginCreateCredentialRequest,
+        cancellationSignal: CancellationSignal,
+        callback: OutcomeReceiver<BeginCreateCredentialResponse,
+            CreateCredentialException>
+    )
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/CustomCredentialEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/CustomCredentialEntry.kt
new file mode 100644
index 0000000..836adba
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/CustomCredentialEntry.kt
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.content.Context
+import android.graphics.drawable.Icon
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.CredentialOption
+import androidx.credentials.R
+import java.time.Instant
+import java.util.Collections
+
+/**
+ * Custom credential entry for a custom credential tyoe that is displayed on the account
+ * selector UI.
+ *
+ * Each entry corresponds to an account that can provide a credential.
+ *
+ * @property title the title shown with this entry on the selector UI
+ * @property subtitle the subTitle shown with this entry on the selector UI
+ * @property lastUsedTime the last used time the credential underlying this entry was
+ * used by the user. Note that this value will only be distinguishable up to the milli
+ * second mark. If two entries have the same millisecond precision, they will be considered to
+ * have been used at the same time
+ * @property icon the icon to be displayed with this entry on the selector UI. If not set, a
+ * default icon representing a custom credential type is set by the library
+ * @property pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+ * system to attach the final request
+ * @property typeDisplayName the friendly name to be displayed on the UI for
+ * the type of the credential
+ * @property isAutoSelectAllowed whether this entry is allowed to be auto
+ * selected if it is the only one on the UI. Note that setting this value
+ * to true does not guarantee this behavior. The developer must also set this
+ * to true, and the framework must determine that only one entry is present
+ */
+@RequiresApi(28)
+class CustomCredentialEntry internal constructor(
+    override val type: String,
+    val title: CharSequence,
+    val pendingIntent: PendingIntent,
+    @get:Suppress("AutoBoxing")
+    val isAutoSelectAllowed: Boolean,
+    val subtitle: CharSequence?,
+    val typeDisplayName: CharSequence?,
+    val icon: Icon,
+    val lastUsedTime: Instant?,
+    beginGetCredentialOption: BeginGetCredentialOption,
+    private val autoSelectAllowedFromOption: Boolean = false,
+    private val isDefaultIcon: Boolean = false
+) : CredentialEntry(
+    type,
+    beginGetCredentialOption,
+    toSlice(
+        type,
+        title,
+        subtitle,
+        pendingIntent,
+        typeDisplayName,
+        lastUsedTime,
+        icon,
+        isAutoSelectAllowed,
+        beginGetCredentialOption
+    )
+) {
+    init {
+        require(type.isNotEmpty()) { "type must not be empty" }
+        require(title.isNotEmpty()) { "title must not be empty" }
+    }
+
+    /**
+     * @constructor constructs an instance of [CustomCredentialEntry]
+     *
+     * @param context the context of the calling app, required to retrieve fallback resources
+     * @param title the title shown with this entry on the selector UI
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param beginGetCredentialOption the option from the orginial [BeginGetCredentialResponse],
+     * for which this credential entry is being added
+     * @param subtitle the subTitle shown with this entry on the selector UI
+     * @param lastUsedTime the last used time the credential underlying this entry was
+     * used by the user, distinguishable up to the milli second mark only such that if two
+     * entries have the same millisecond precision, they will be considered to have been used at
+     * the same time
+     * @param typeDisplayName the friendly name to be displayed on the UI for
+     * the type of the credential
+     * @param icon the icon to be displayed with this entry on the selector UI, if not set a
+     * default icon representing a custom credential type is set by the library
+     * @param isAutoSelectAllowed whether this entry is allowed to be auto
+     * selected if it is the only one on the UI, only takes effect if the app requesting for
+     * credentials also opts for auto select
+     */
+    constructor(
+        context: Context,
+        title: CharSequence,
+        pendingIntent: PendingIntent,
+        beginGetCredentialOption: BeginGetCredentialOption,
+        subtitle: CharSequence? = null,
+        typeDisplayName: CharSequence? = null,
+        lastUsedTime: Instant? = null,
+        icon: Icon = Icon.createWithResource(context, R.drawable.ic_other_sign_in),
+        @Suppress("AutoBoxing")
+        isAutoSelectAllowed: Boolean = false
+    ) : this(
+        beginGetCredentialOption.type,
+        title,
+        pendingIntent,
+        isAutoSelectAllowed,
+        subtitle,
+        typeDisplayName,
+        icon,
+        lastUsedTime,
+        beginGetCredentialOption
+    )
+
+    internal companion object {
+        private const val TAG = "CredentialEntry"
+
+        private const val SLICE_HINT_TYPE_DISPLAY_NAME =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_TITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_USER_NAME"
+
+        private const val SLICE_HINT_SUBTITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_CREDENTIAL_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
+
+        private const val SLICE_HINT_ICON =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PROFILE_ICON"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PENDING_INTENT"
+
+        private const val SLICE_HINT_AUTO_ALLOWED =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_ALLOWED"
+
+        private const val SLICE_HINT_OPTION_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_OPTION_ID"
+
+        private const val SLICE_HINT_AUTO_SELECT_FROM_OPTION =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_SELECT_FROM_OPTION"
+
+        private const val SLICE_HINT_DEFAULT_ICON_RES_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_DEFAULT_ICON_RES_ID"
+
+        private const val AUTO_SELECT_TRUE_STRING = "true"
+
+        private const val AUTO_SELECT_FALSE_STRING = "false"
+
+        @JvmStatic
+        internal fun toSlice(
+            type: String,
+            title: CharSequence,
+            subtitle: CharSequence?,
+            pendingIntent: PendingIntent,
+            typeDisplayName: CharSequence?,
+            lastUsedTime: Instant?,
+            icon: Icon,
+            isAutoSelectAllowed: Boolean?,
+            beginGetCredentialOption: BeginGetCredentialOption
+        ): Slice {
+            // TODO("Put the right revision value")
+            val autoSelectAllowed = if (isAutoSelectAllowed == true) {
+                AUTO_SELECT_TRUE_STRING
+            } else {
+                AUTO_SELECT_FALSE_STRING
+            }
+            val sliceBuilder = Slice.Builder(
+                Uri.EMPTY, SliceSpec(
+                    type, 1
+                )
+            )
+                .addText(
+                    typeDisplayName, /*subType=*/null,
+                    listOf(SLICE_HINT_TYPE_DISPLAY_NAME)
+                )
+                .addText(
+                    title, /*subType=*/null,
+                    listOf(SLICE_HINT_TITLE)
+                )
+                .addText(
+                    subtitle, /*subType=*/null,
+                    listOf(SLICE_HINT_SUBTITLE)
+                )
+                .addText(
+                    autoSelectAllowed, /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_ALLOWED)
+                )
+                .addText(
+                    beginGetCredentialOption.id,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_OPTION_ID)
+                )
+                .addIcon(
+                    icon, /*subType=*/null,
+                    listOf(SLICE_HINT_ICON)
+                )
+
+            try {
+                if (icon.resId == R.drawable.ic_other_sign_in) {
+                    sliceBuilder.addInt(
+                        /*true=*/1,
+                        /*subType=*/null,
+                        listOf(SLICE_HINT_DEFAULT_ICON_RES_ID)
+                    )
+                }
+            } catch (_: IllegalStateException) {
+            }
+
+            if (CredentialOption.extractAutoSelectValue(
+                    beginGetCredentialOption.candidateQueryData
+                )
+            ) {
+                sliceBuilder.addInt(
+                    /*true=*/1,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_SELECT_FROM_OPTION)
+                )
+            }
+            if (lastUsedTime != null) {
+                sliceBuilder.addLong(
+                    lastUsedTime.toEpochMilli(),
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_LAST_USED_TIME_MILLIS)
+                )
+            }
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(),
+                /*subType=*/null
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [CustomCredentialEntry] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         *
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): CustomCredentialEntry? {
+            val type: String = slice.spec!!.type
+            var typeDisplayName: CharSequence? = null
+            var title: CharSequence? = null
+            var subtitle: CharSequence? = null
+            var icon: Icon? = null
+            var pendingIntent: PendingIntent? = null
+            var lastUsedTime: Instant? = null
+            var autoSelectAllowed = false
+            var beginGetCredentialOptionId: CharSequence? = null
+            var autoSelectAllowedFromOption = false
+            var isDefaultIcon = false
+
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_TYPE_DISPLAY_NAME)) {
+                    typeDisplayName = it.text
+                } else if (it.hasHint(SLICE_HINT_TITLE)) {
+                    title = it.text
+                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {
+                    subtitle = it.text
+                } else if (it.hasHint(SLICE_HINT_ICON)) {
+                    icon = it.icon
+                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                } else if (it.hasHint(SLICE_HINT_OPTION_ID)) {
+                    beginGetCredentialOptionId = it.text
+                } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
+                    lastUsedTime = Instant.ofEpochMilli(it.long)
+                } else if (it.hasHint(SLICE_HINT_AUTO_ALLOWED)) {
+                    val autoSelectValue = it.text
+                    if (autoSelectValue == AUTO_SELECT_TRUE_STRING) {
+                        autoSelectAllowed = true
+                    }
+                } else if (it.hasHint(SLICE_HINT_AUTO_SELECT_FROM_OPTION)) {
+                    autoSelectAllowedFromOption = true
+                } else if (it.hasHint(SLICE_HINT_DEFAULT_ICON_RES_ID)) {
+                    isDefaultIcon = true
+                }
+            }
+
+            return try {
+                CustomCredentialEntry(
+                    type,
+                    title!!,
+                    pendingIntent!!,
+                    autoSelectAllowed,
+                    subtitle,
+                    typeDisplayName,
+                    icon!!,
+                    lastUsedTime,
+                    BeginGetCustomCredentialOption(
+                        beginGetCredentialOptionId!!.toString(),
+                        type,
+                        Bundle()
+                    ),
+                    autoSelectAllowedFromOption,
+                    isDefaultIcon
+                )
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+
+    /**
+     * Builder for [CustomCredentialEntry]
+     *
+     * @constructor constructs an instance of [CustomCredentialEntry.Builder]
+     *
+     * @param context the context of the calling app, required to retrieve fallback resources
+     * @param type the type string that defines this custom credential
+     * @param title the title shown with this entry on the selector UI
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param beginGetCredentialOption the option from the orginial [BeginGetCredentialResponse],
+     * for which this credential entry is being added
+     *
+     * @throws NullPointerException If [context], [type], [title], [pendingIntent], or
+     * [beginGetCredentialOption] is null
+     */
+    class Builder(
+        private val context: Context,
+        private val type: String,
+        private val title: CharSequence,
+        private val pendingIntent: PendingIntent,
+        private val beginGetCredentialOption: BeginGetCredentialOption
+    ) {
+        private var subtitle: CharSequence? = null
+        private var lastUsedTime: Instant? = null
+        private var typeDisplayName: CharSequence? = null
+        private var icon: Icon? = null
+        private var autoSelectAllowed = false
+
+        /** Sets a displayName to be shown on the UI with this entry. */
+        fun setSubtitle(subtitle: CharSequence?): Builder {
+            this.subtitle = subtitle
+            return this
+        }
+
+        /** Sets the display name of this credential type, to be shown on the UI with this entry. */
+        fun setTypeDisplayName(typeDisplayName: CharSequence?): Builder {
+            this.typeDisplayName = typeDisplayName
+            return this
+        }
+
+        /**
+         * Sets the icon to be show on the UI.
+         * If no icon is set, a default icon representing a custom credential will be set.
+         */
+        fun setIcon(icon: Icon): Builder {
+            this.icon = icon
+            return this
+        }
+
+        /**
+         * Sets whether the entry should be auto-selected.
+         * The value is false by default
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setAutoSelectAllowed(autoSelectAllowed: Boolean): Builder {
+            this.autoSelectAllowed = autoSelectAllowed
+            return this
+        }
+
+        /**
+         * Sets the last used time of this account. This information will be used to sort the
+         * entries on the selector.
+         */
+        fun setLastUsedTime(lastUsedTime: Instant?): Builder {
+            this.lastUsedTime = lastUsedTime
+            return this
+        }
+
+        /** Builds an instance of [CustomCredentialEntry] */
+        fun build(): CustomCredentialEntry {
+            if (icon == null) {
+                icon = Icon.createWithResource(context, R.drawable.ic_other_sign_in)
+            }
+            return CustomCredentialEntry(
+                type,
+                title,
+                pendingIntent,
+                autoSelectAllowed,
+                subtitle,
+                typeDisplayName,
+                icon!!,
+                lastUsedTime,
+                beginGetCredentialOption
+            )
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/IntentHandlerConverters.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/IntentHandlerConverters.kt
new file mode 100644
index 0000000..f72ddd5
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/IntentHandlerConverters.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("IntentHandlerConverters")
+@file:SuppressLint("ClassVerificationFailure")
+
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.content.Intent
+import android.service.credentials.CredentialProviderService
+import androidx.annotation.RequiresApi
+import androidx.credentials.CreateCredentialResponse
+import androidx.credentials.GetCredentialResponse
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.GetCredentialException
+import androidx.credentials.provider.utils.BeginGetCredentialUtil
+
+/**
+ * IntentHandlerConverters is a util class for PendingIntentHandler
+ * that can be used for tests. It contains methods that convert the
+ * intents back into their original credential objects.
+ */
+
+/**
+ * Returns the stored create credential exception from the intent.
+ */
+@RequiresApi(34)
+fun Intent.getCreateCredentialException():
+    android.credentials.CreateCredentialException? {
+   var key = CredentialProviderService.EXTRA_CREATE_CREDENTIAL_EXCEPTION
+   if (!hasExtra(key)) {
+       return null
+   }
+
+   return getParcelableExtra(
+       key,
+       android.credentials.CreateCredentialException::class.java)
+}
+
+/**
+ * Returns the stored get credential exception from the intent.
+ */
+@RequiresApi(34)
+fun Intent.getGetCredentialException(): android.credentials.GetCredentialException? {
+   var key = CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION
+   if (!hasExtra(key)) {
+       return null
+   }
+
+   return getParcelableExtra(
+       key,
+       android.credentials.GetCredentialException::class.java)
+}
+
+/**
+ * Returns the begin get response from the intent.
+ */
+@RequiresApi(34)
+fun Intent.getBeginGetResponse(): BeginGetCredentialResponse? {
+   var key = CredentialProviderService.EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE
+   if (!hasExtra(key)) {
+       return null
+   }
+
+   var res = getParcelableExtra(
+       key,
+       android.service.credentials.BeginGetCredentialResponse::class.java)
+   if (res == null) {
+       return null
+   }
+
+   return BeginGetCredentialUtil.convertToJetpackResponse(res)
+}
+
+/**
+ * Returns the get response from the intent.
+ */
+@RequiresApi(34)
+fun Intent.getGetCredentialResponse(): android.credentials.GetCredentialResponse? {
+   var key = CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE
+   if (!hasExtra(key)) {
+       return null
+   }
+
+   return getParcelableExtra(
+      key,
+      android.credentials.GetCredentialResponse::class.java)
+}
+
+/**
+ * Returns the create response from the intent.
+ */
+@RequiresApi(34)
+fun Intent.getCreateCredentialCredentialResponse():
+    android.credentials.CreateCredentialResponse? {
+   var key = CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESPONSE
+   if (!hasExtra(key)) {
+       return null
+   }
+
+   return getParcelableExtra(
+       key,
+       android.credentials.CreateCredentialResponse::class.java)
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/PasswordCredentialEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/PasswordCredentialEntry.kt
new file mode 100644
index 0000000..01b508c
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/PasswordCredentialEntry.kt
@@ -0,0 +1,416 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.content.Context
+import android.graphics.drawable.Icon
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.CredentialOption
+import androidx.credentials.PasswordCredential
+import androidx.credentials.R
+import java.time.Instant
+import java.util.Collections
+
+/**
+ * A password credential entry that is displayed on the account selector UI. This
+ * entry denotes that a credential of type [PasswordCredential.TYPE_PASSWORD_CREDENTIAL]
+ * is available for the user to select.
+ *
+ * Once this entry is selected, the corresponding [pendingIntent] will be invoked. The provider
+ * can then show any activity they wish to. Before finishing the activity, provider must
+ * set the final [androidx.credentials.GetCredentialResponse] through the
+ * [PendingIntentHandler.setGetCredentialResponse] helper API.
+ *
+ * @property username the username of the account holding the password credential
+ * @property displayName the displayName of the account holding the password credential
+ * @property lastUsedTime the last used time of this entry, distinguishable up to the milli
+ * second mark, such that if two entries have the same millisecond precision,
+ * they will be considered to have been used at the same time
+ * @property icon the icon to be displayed with this entry on the selector. If not set, a
+ * default icon representing a password credential type is set by the library
+ * @property pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+ * system to attach the final request
+ * @property isAutoSelectAllowed whether this entry is allowed to be auto
+ * selected if it is the only one on the UI. Note that setting this value
+ * to true does not guarantee this behavior. The developer must also set this
+ * to true, and the framework must determine that this is the only entry available for the user.
+ *
+ * @throws IllegalArgumentException if [username] is empty
+ *
+ * @see CustomCredentialEntry
+ */
+@RequiresApi(28)
+class PasswordCredentialEntry internal constructor(
+    val username: CharSequence,
+    val displayName: CharSequence?,
+    val typeDisplayName: CharSequence,
+    val pendingIntent: PendingIntent,
+    val lastUsedTime: Instant?,
+    val icon: Icon,
+    val isAutoSelectAllowed: Boolean,
+    beginGetPasswordOption: BeginGetPasswordOption,
+    private val autoSelectAllowedFromOption: Boolean = false,
+    private val isDefaultIcon: Boolean = false
+) : CredentialEntry(
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    beginGetPasswordOption,
+    toSlice(
+        PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+        username,
+        displayName,
+        pendingIntent,
+        typeDisplayName,
+        lastUsedTime,
+        icon,
+        isAutoSelectAllowed,
+        beginGetPasswordOption
+    )
+) {
+    init {
+        require(username.isNotEmpty()) { "username must not be empty" }
+    }
+
+    /**
+     * @constructor constructs an instance of [PasswordCredentialEntry]
+     *
+     * @param context the context of the calling app, required to retrieve fallback resources
+     * @param username the username of the account holding the password credential
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param beginGetPasswordOption the option from the original [BeginGetCredentialResponse],
+     * for which this credential entry is being added
+     * @param displayName the displayName of the account holding the password credential
+     * @param lastUsedTime the last used time the credential underlying this entry was
+     * used by the user, distinguishable up to the milli second mark only such that if two
+     * entries have the same millisecond precision, they will be considered to have been used at
+     * the same time
+     * @param icon the icon to be displayed with this entry on the selector, if not set, a
+     * default icon representing a password credential type is set by the library
+     * @param isAutoSelectAllowed whether this entry is allowed to be auto
+     * selected if it is the only one on the UI, only takes effect if the app requesting for
+     * credentials also opts for auto select
+     *
+     * @throws IllegalArgumentException if [username] is empty
+     * @throws NullPointerException If [context], [username], [pendingIntent], or
+     * [beginGetPasswordOption] is null
+     */
+    constructor(
+        context: Context,
+        username: CharSequence,
+        pendingIntent: PendingIntent,
+        beginGetPasswordOption: BeginGetPasswordOption,
+        displayName: CharSequence? = null,
+        lastUsedTime: Instant? = null,
+        icon: Icon = Icon.createWithResource(context, R.drawable.ic_password),
+        isAutoSelectAllowed: Boolean = false
+    ) : this(
+        username,
+        displayName,
+        typeDisplayName = context.getString(
+            R.string.android_credentials_TYPE_PASSWORD_CREDENTIAL
+        ),
+        pendingIntent,
+        lastUsedTime,
+        icon,
+        isAutoSelectAllowed,
+        beginGetPasswordOption,
+    )
+
+    internal companion object {
+        private const val TAG = "PasswordCredentialEntry"
+
+        private const val SLICE_HINT_TYPE_DISPLAY_NAME =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_TITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_USER_NAME"
+
+        private const val SLICE_HINT_SUBTITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_CREDENTIAL_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_DEFAULT_ICON_RES_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_DEFAULT_ICON_RES_ID"
+
+        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
+
+        private const val SLICE_HINT_ICON =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PROFILE_ICON"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PENDING_INTENT"
+
+        private const val SLICE_HINT_OPTION_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_OPTION_ID"
+
+        private const val SLICE_HINT_AUTO_ALLOWED =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_ALLOWED"
+
+        private const val SLICE_HINT_AUTO_SELECT_FROM_OPTION =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_SELECT_FROM_OPTION"
+
+        private const val AUTO_SELECT_TRUE_STRING = "true"
+
+        private const val AUTO_SELECT_FALSE_STRING = "false"
+
+        @JvmStatic
+        internal fun toSlice(
+            type: String,
+            title: CharSequence,
+            subTitle: CharSequence?,
+            pendingIntent: PendingIntent,
+            typeDisplayName: CharSequence?,
+            lastUsedTime: Instant?,
+            icon: Icon,
+            isAutoSelectAllowed: Boolean,
+            beginGetPasswordCredentialOption: BeginGetPasswordOption
+        ): Slice {
+            // TODO("Put the right revision value")
+            val autoSelectAllowed = if (isAutoSelectAllowed) {
+                AUTO_SELECT_TRUE_STRING
+            } else {
+                AUTO_SELECT_FALSE_STRING
+            }
+            val sliceBuilder = Slice.Builder(
+                Uri.EMPTY, SliceSpec(
+                    type, 1
+                )
+            )
+                .addText(
+                    typeDisplayName, /*subType=*/null,
+                    listOf(SLICE_HINT_TYPE_DISPLAY_NAME)
+                )
+                .addText(
+                    title, /*subType=*/null,
+                    listOf(SLICE_HINT_TITLE)
+                )
+                .addText(
+                    subTitle, /*subType=*/null,
+                    listOf(SLICE_HINT_SUBTITLE)
+                )
+                .addText(
+                    autoSelectAllowed, /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_ALLOWED)
+                )
+                .addText(
+                    beginGetPasswordCredentialOption.id,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_OPTION_ID)
+                )
+                .addIcon(
+                    icon, /*subType=*/null,
+                    listOf(SLICE_HINT_ICON)
+                )
+            try {
+                if (icon.resId == R.drawable.ic_password) {
+                    sliceBuilder.addInt(
+                        /*true=*/1,
+                        /*subType=*/null,
+                        listOf(SLICE_HINT_DEFAULT_ICON_RES_ID)
+                    )
+                }
+            } catch (_: IllegalStateException) {
+            }
+
+            if (CredentialOption.extractAutoSelectValue(
+                    beginGetPasswordCredentialOption.candidateQueryData
+                )
+            ) {
+                sliceBuilder.addInt(
+                    /*true=*/1,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_SELECT_FROM_OPTION)
+                )
+            }
+            if (lastUsedTime != null) {
+                sliceBuilder.addLong(
+                    lastUsedTime.toEpochMilli(),
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_LAST_USED_TIME_MILLIS)
+                )
+            }
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(),
+                /*subType=*/null
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [CustomCredentialEntry] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         *
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY) // used from java tests
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): PasswordCredentialEntry? {
+            var typeDisplayName: CharSequence? = null
+            var title: CharSequence? = null
+            var subTitle: CharSequence? = null
+            var icon: Icon? = null
+            var pendingIntent: PendingIntent? = null
+            var lastUsedTime: Instant? = null
+            var autoSelectAllowed = false
+            var autoSelectAllowedFromOption = false
+            var beginGetPasswordOptionId: CharSequence? = null
+            var isDefaultIcon = false
+
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_TYPE_DISPLAY_NAME)) {
+                    typeDisplayName = it.text
+                } else if (it.hasHint(SLICE_HINT_TITLE)) {
+                    title = it.text
+                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {
+                    subTitle = it.text
+                } else if (it.hasHint(SLICE_HINT_ICON)) {
+                    icon = it.icon
+                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                } else if (it.hasHint(SLICE_HINT_OPTION_ID)) {
+                    beginGetPasswordOptionId = it.text
+                } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
+                    lastUsedTime = Instant.ofEpochMilli(it.long)
+                } else if (it.hasHint(SLICE_HINT_AUTO_ALLOWED)) {
+                    val autoSelectValue = it.text
+                    if (autoSelectValue == AUTO_SELECT_TRUE_STRING) {
+                        autoSelectAllowed = true
+                    }
+                } else if (it.hasHint(SLICE_HINT_AUTO_SELECT_FROM_OPTION)) {
+                    autoSelectAllowedFromOption = true
+                } else if (it.hasHint(SLICE_HINT_DEFAULT_ICON_RES_ID)) {
+                    isDefaultIcon = true
+                }
+            }
+
+            return try {
+                PasswordCredentialEntry(
+                    title!!,
+                    subTitle,
+                    typeDisplayName!!,
+                    pendingIntent!!,
+                    lastUsedTime,
+                    icon!!,
+                    autoSelectAllowed,
+                    BeginGetPasswordOption.createFromEntrySlice(
+                        Bundle(),
+                        beginGetPasswordOptionId!!.toString()
+                    ),
+                    autoSelectAllowedFromOption,
+                    isDefaultIcon
+                )
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+
+    /**
+     * Builder for [PasswordCredentialEntry]
+     *
+     * @constructor constructs an instance of [PasswordCredentialEntry.Builder]
+     *
+     * @param context the context of the calling app, required to retrieve fallback resources
+     * @param username the username of the account holding the password credential
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param beginGetPasswordOption the option from the original [BeginGetCredentialResponse],
+     * for which this credential entry is being added
+     *
+     * @throws NullPointerException If [context], [username], [pendingIntent], or
+     * [beginGetPasswordOption] is null
+     * @throws IllegalArgumentException if [username] is empty
+     */
+    class Builder(
+        private val context: Context,
+        private val username: CharSequence,
+        private val pendingIntent: PendingIntent,
+        private val beginGetPasswordOption: BeginGetPasswordOption
+    ) {
+        private var displayName: CharSequence? = null
+        private var lastUsedTime: Instant? = null
+        private var icon: Icon? = null
+        private var autoSelectAllowed = false
+
+        /** Sets a displayName to be shown on the UI with this entry */
+        fun setDisplayName(displayName: CharSequence?): Builder {
+            this.displayName = displayName
+            return this
+        }
+
+        /** Sets the icon to be shown on the UI with this entry */
+        fun setIcon(icon: Icon): Builder {
+            this.icon = icon
+            return this
+        }
+
+        /**
+         * Sets whether the entry should be auto-selected.
+         * The value is false by default
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setAutoSelectAllowed(autoSelectAllowed: Boolean): Builder {
+            this.autoSelectAllowed = autoSelectAllowed
+            return this
+        }
+
+        /**
+         * Sets the last used time of this account. This information will be used to sort the
+         * entries on the selector.
+         */
+        fun setLastUsedTime(lastUsedTime: Instant?): Builder {
+            this.lastUsedTime = lastUsedTime
+            return this
+        }
+
+        /** Builds an instance of [PasswordCredentialEntry] */
+        fun build(): PasswordCredentialEntry {
+            if (icon == null) {
+                icon = Icon.createWithResource(context, R.drawable.ic_password)
+            }
+            val typeDisplayName = context.getString(
+                R.string.android_credentials_TYPE_PASSWORD_CREDENTIAL
+            )
+            return PasswordCredentialEntry(
+                username,
+                displayName,
+                typeDisplayName,
+                pendingIntent,
+                lastUsedTime,
+                icon!!,
+                autoSelectAllowed,
+                beginGetPasswordOption
+            )
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/PendingIntentHandler.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/PendingIntentHandler.kt
new file mode 100644
index 0000000..e6e8f55
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/PendingIntentHandler.kt
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.app.Activity
+import android.app.PendingIntent
+import android.content.Intent
+import android.service.credentials.BeginCreateCredentialResponse
+import android.service.credentials.CreateCredentialRequest
+import android.service.credentials.CredentialEntry
+import android.service.credentials.CredentialProviderService
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.credentials.CreateCredentialResponse
+import androidx.credentials.CredentialOption
+import androidx.credentials.GetCredentialResponse
+import androidx.credentials.exceptions.CreateCredentialException
+import androidx.credentials.exceptions.GetCredentialException
+import androidx.credentials.provider.utils.BeginGetCredentialUtil
+import java.util.stream.Collectors
+
+/**
+ * PendingIntentHandler to be used by credential providers to extract requests from a given intent,
+ * or to set back a response or an exception to a given intent while dealing with activities
+ * invoked by pending intents set on a [CreateEntry] for the create flow, or on a
+ * [CredentialEntry], [AuthenticationAction], [Action], or a [RemoteEntry] set for a get flow.
+ *
+ * When user selects one of the entries mentioned above, the credential provider's corresponding
+ * activity is invoked. The intent associated with this activity must be extracted and passed
+ * into the utils in this class to extract the required requests.
+ *
+ * When user interaction is complete, credential providers must set the activity result by calling
+ * [android.app.Activity.setResult] by setting an appropriate result code and data of type
+ * [Intent]. This data should also be prepared by using the utils in this class to populate
+ * the required response/exception.
+ *
+ * See extension functions for [Intent] in IntentHandlerConverters.kt to help test intents that are
+ * set on pending intents in different entry classes.
+ */
+@RequiresApi(34)
+class PendingIntentHandler {
+    companion object {
+        private const val TAG = "PendingIntentHandler"
+
+        /**
+         * Extracts the [ProviderCreateCredentialRequest] from the provider's
+         * [PendingIntent] invoked by the Android system.
+         *
+         * @param intent the intent associated with the [Activity] invoked through the
+         * [PendingIntent]
+         *
+         * @throws NullPointerException If [intent] is null
+         */
+        @JvmStatic
+        fun retrieveProviderCreateCredentialRequest(intent: Intent):
+            ProviderCreateCredentialRequest? {
+            val frameworkReq: CreateCredentialRequest? =
+                intent.getParcelableExtra(
+                    CredentialProviderService
+                        .EXTRA_CREATE_CREDENTIAL_REQUEST, CreateCredentialRequest::class.java
+                )
+            if (frameworkReq == null) {
+                Log.i(TAG, "Request not found in pendingIntent")
+                return frameworkReq
+            }
+            return ProviderCreateCredentialRequest(
+                androidx.credentials.CreateCredentialRequest
+                    .createFrom(
+                        frameworkReq.type,
+                        frameworkReq.data,
+                        frameworkReq.data,
+                        requireSystemProvider = false,
+                        frameworkReq.callingAppInfo.origin
+                    ) ?: return null,
+                CallingAppInfo(
+                    frameworkReq.callingAppInfo.packageName,
+                    frameworkReq.callingAppInfo.signingInfo,
+                    frameworkReq.callingAppInfo.origin
+                )
+            )
+        }
+
+        /**
+         * Extracts the [BeginGetCredentialRequest] from the provider's
+         * [PendingIntent] invoked by the Android system when the user
+         * selects an [AuthenticationAction].
+         *
+         * @param intent the intent associated with the [Activity] invoked through the
+         * [PendingIntent]
+         *
+         * @throws NullPointerException If [intent] is null
+         */
+        @JvmStatic
+        fun retrieveBeginGetCredentialRequest(intent: Intent): BeginGetCredentialRequest? {
+            val request = intent.getParcelableExtra(
+                "android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST",
+                android.service.credentials.BeginGetCredentialRequest::class.java
+            )
+            return request?.let { BeginGetCredentialUtil.convertToJetpackRequest(it) }
+        }
+
+        /**
+         * Sets the [CreateCredentialResponse] on the intent passed in. This intent is then
+         * set as the data associated with the result of the activity invoked by the
+         * [PendingIntent] set on a [CreateEntry]. The intent is set using the
+         * [Activity.setResult] method that takes in the intent, as well as a result code.
+         *
+         * A credential provider must set the result code to [Activity.RESULT_OK] if a valid
+         * response, or a valid exception is being set as the data to the result. However,
+         * if the credential provider is unable to resolve to a valid response or exception,
+         * the result code must be set to [Activity.RESULT_CANCELED]. Note that setting the
+         * result code to [Activity.RESULT_CANCELED] will re-surface the account selection
+         * bottom sheet that displayed the original [CredentialEntry], hence allowing the user
+         * to re-select.
+         *
+         * @param intent the intent to be set on the result of the [Activity] invoked through the
+         * [PendingIntent]
+         * @param response the response to be set as an extra on the [intent]
+         *
+         * @throws NullPointerException If [intent], or [response] is null
+         */
+        @JvmStatic
+        fun setCreateCredentialResponse(
+            intent: Intent,
+            response: CreateCredentialResponse
+        ) {
+            intent.putExtra(
+                CredentialProviderService.EXTRA_CREATE_CREDENTIAL_RESPONSE,
+                android.credentials.CreateCredentialResponse(response.data)
+            )
+        }
+
+        /**
+         * Extracts the [ProviderGetCredentialRequest] from the provider's
+         * [PendingIntent] invoked by the Android system, when the user selects a
+         * [CredentialEntry].
+         *
+         * @param intent the intent associated with the [Activity] invoked through the
+         * [PendingIntent]
+         *
+         * @throws NullPointerException If [intent] is null
+         */
+        @JvmStatic
+        fun retrieveProviderGetCredentialRequest(intent: Intent):
+            ProviderGetCredentialRequest? {
+            val frameworkReq = intent.getParcelableExtra(
+                CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
+                android.service.credentials.GetCredentialRequest::class.java
+            )
+            if (frameworkReq == null) {
+                Log.i(TAG, "Get request from framework is null")
+                return null
+            }
+
+            return ProviderGetCredentialRequest.createFrom(
+                frameworkReq.credentialOptions.stream()
+                    .map { option ->
+                        CredentialOption.createFrom(
+                            option.type,
+                            option.credentialRetrievalData,
+                            option.candidateQueryData,
+                            option.isSystemProviderRequired,
+                            option.allowedProviders,
+                        )
+                    }
+                    .collect(Collectors.toList()),
+                CallingAppInfo(
+                    frameworkReq.callingAppInfo.packageName,
+                    frameworkReq.callingAppInfo.signingInfo,
+                    frameworkReq.callingAppInfo.origin
+                )
+            )
+        }
+
+        /**
+         * Sets the [android.credentials.GetCredentialResponse] on the intent passed in. This
+         * intent is then set as the data associated with the result of the activity invoked by
+         * the [PendingIntent], set on a [CredentialEntry]. The intent is set using the
+         * [Activity.setResult] method that takes in the intent, as well as a result code.
+         *
+         * A credential provider must set the result code to [Activity.RESULT_OK] if a valid
+         * credential, or a valid exception is being set as the data to the result. However,
+         * if the credential provider is unable to resolve to a valid response or exception,
+         * the result code must be set to [Activity.RESULT_CANCELED]. Note that setting the
+         * result code to [Activity.RESULT_CANCELED] will re-surface the account selection
+         * bottom sheet that displayed the original [CredentialEntry], hence allowing the user
+         * to re-select.
+         *
+         * @param intent the intent to be set on the result of the [Activity] invoked through the
+         * [PendingIntent]
+         * @param response the response to be set as an extra on the [intent]
+         *
+         * @throws NullPointerException If [intent], or [response] is null
+         */
+        @JvmStatic
+        fun setGetCredentialResponse(
+            intent: Intent,
+            response: GetCredentialResponse
+        ) {
+            intent.putExtra(
+                CredentialProviderService.EXTRA_GET_CREDENTIAL_RESPONSE,
+                android.credentials.GetCredentialResponse(
+                    android.credentials.Credential(
+                        response.credential.type,
+                        response.credential.data
+                    )
+                )
+            )
+        }
+
+        /**
+         * Sets the [android.service.credentials.BeginGetCredentialResponse] on the intent passed
+         * in. This intent is then set as the data associated with the result of the activity
+         * invoked by the [PendingIntent], set on an [AuthenticationAction]. The intent is set
+         * using the [Activity.setResult] method that takes in the intent, as well as a result code.
+         *
+         * A credential provider must set the result code to [Activity.RESULT_OK] if a valid
+         * response, or a valid exception is being set as part of the data to the result. However,
+         * if the credential provider is unable to resolve to a valid response or exception,
+         * the result code must be set to [Activity.RESULT_CANCELED]. Note that setting the
+         * result code to [Activity.RESULT_CANCELED] will re-surface the account selection
+         * bottom sheet that displayed the original [CredentialEntry], hence allowing the user to
+         * re-select.
+         *
+         * @param intent the intent to be set on the result of the [Activity] invoked through the
+         * [PendingIntent]
+         * @param response the response to be set as an extra on the [intent]
+         *
+         * @throws NullPointerException If [intent], or [response] is null
+         */
+        @JvmStatic
+        fun setBeginGetCredentialResponse(
+            intent: Intent,
+            response: BeginGetCredentialResponse
+        ) {
+            intent.putExtra(
+                CredentialProviderService.EXTRA_BEGIN_GET_CREDENTIAL_RESPONSE,
+                BeginGetCredentialUtil.convertToFrameworkResponse(response)
+            )
+        }
+
+        /**
+         * Sets the [androidx.credentials.exceptions.GetCredentialException] if an error is
+         * encountered during the final phase of the get credential flow.
+         *
+         * A credential provider service returns a list of [CredentialEntry] as part of
+         * the [BeginGetCredentialResponse] to the query phase of the get-credential flow.
+         * If the user selects one of these entries, the corresponding [PendingIntent]
+         * is fired and the provider's activity is invoked.
+         * If there is an error encountered during the lifetime of that activity, the provider
+         * must use this API to set an exception on the given intent before finishing the
+         * activity in question.
+         *
+         * The intent is set using the [Activity.setResult] method that takes in the intent,
+         * as well as a result code. A credential provider must set the result code to
+         * [Activity.RESULT_OK] if a valid credential, or a valid exception is being set as
+         * the data to the result. However, if the credential provider is unable to resolve to a
+         * valid response or exception, the result code must be set to [Activity.RESULT_CANCELED].
+         *
+         * Note that setting the result code to [Activity.RESULT_CANCELED] will re-surface the
+         * account selection bottom sheet that displayed the original [CredentialEntry], hence
+         * allowing the user to re-select.
+         *
+         * @param intent the intent to be set on the result of the [Activity] invoked through the
+         * [PendingIntent]
+         * @param exception the exception to be set as an extra to the [intent]
+         *
+         * @throws NullPointerException If [intent], or [exception] is null
+         */
+        @JvmStatic
+        fun setGetCredentialException(
+            intent: Intent,
+            exception: GetCredentialException
+        ) {
+            intent.putExtra(
+                CredentialProviderService.EXTRA_GET_CREDENTIAL_EXCEPTION,
+                android.credentials.GetCredentialException(exception.type, exception.message)
+            )
+        }
+
+        /**
+         * Sets the [androidx.credentials.exceptions.CreateCredentialException] if an error is
+         * encountered during the final phase of the create credential flow.
+         *
+         * A credential provider service returns a list of [CreateEntry] as part of
+         * the [BeginCreateCredentialResponse] to the query phase of the get-credential flow.
+         *
+         * If the user selects one of these entries, the corresponding [PendingIntent]
+         * is fired and the provider's activity is invoked. If there is an error encountered
+         * during the lifetime of that activity, the provider must use this API to set
+         * an exception before finishing the activity.
+         *
+         * The intent is set using the [Activity.setResult] method that takes in the intent,
+         * as well as a result code. A credential provider must set the result code to
+         * [Activity.RESULT_OK] if a valid credential, or a valid exception is being set as
+         * the data to the result. However, if the credential provider is unable to resolve to a
+         * valid response or exception, the result code must be set to [Activity.RESULT_CANCELED].
+         *
+         * Note that setting the result code to [Activity.RESULT_CANCELED] will re-surface the
+         * account selection bottom sheet that displayed the original [CreateEntry], hence allowing
+         * the user to re-select.
+         *
+         * @param intent the intent to be set on the result of the [Activity] invoked through the
+         * [PendingIntent]
+         * @param exception the exception to be set as an extra to the [intent]
+         *
+         * @throws NullPointerException If [intent], or [exception] is null
+         */
+        @JvmStatic
+        fun setCreateCredentialException(
+            intent: Intent,
+            exception: CreateCredentialException
+        ) {
+            intent.putExtra(
+                CredentialProviderService.EXTRA_CREATE_CREDENTIAL_EXCEPTION,
+                android.credentials.CreateCredentialException(exception.type, exception.message)
+            )
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderClearCredentialStateRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderClearCredentialStateRequest.kt
new file mode 100644
index 0000000..c796764
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderClearCredentialStateRequest.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.credentials.provider
+
+/**
+ * Request class for clearing a user's credential state from the credential providers.
+ *
+ * @constructor constructs an instance of [ProviderClearCredentialStateRequest]
+ *
+ * @param callingAppInfo info pertaining to the calling app that's making the request
+ *
+ * @throws NullPointerException If [callingAppInfo] is null
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ */
+class ProviderClearCredentialStateRequest constructor(val callingAppInfo: CallingAppInfo)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderCreateCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderCreateCredentialRequest.kt
new file mode 100644
index 0000000..2bc48ee
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderCreateCredentialRequest.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import androidx.credentials.CreateCredentialRequest
+
+/**
+ * Final request received by the provider after the user has selected a given [CreateEntry]
+ * on the UI.
+ *
+ * This request contains the actual request coming from the calling app,
+ * and the application information associated with the calling app.
+ *
+ * @constructor constructs an instance of [ProviderCreateCredentialRequest]
+ *
+ * @param callingRequest the complete [CreateCredentialRequest] coming from
+ * the calling app that is requesting for credential creation
+ * @param callingAppInfo information pertaining to the calling app making
+ * the request
+ *
+ * @throws NullPointerException If [callingRequest], or [callingAppInfo] is null
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ */
+class ProviderCreateCredentialRequest constructor(
+    val callingRequest: CreateCredentialRequest,
+    val callingAppInfo: CallingAppInfo
+)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderGetCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderGetCredentialRequest.kt
new file mode 100644
index 0000000..ae27fd3
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/ProviderGetCredentialRequest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.app.PendingIntent
+import androidx.credentials.CredentialOption
+
+/**
+ * Request received by the provider after the query phase of the get flow is complete i.e. the user
+ * was presented with a list of credentials, and the user has now made a selection from the list of
+ * [CredentialEntry] presented on the selector UI.
+ *
+ * This request will be added to the intent extras of the activity invoked by the [PendingIntent]
+ * set on the [CredentialEntry] that the user selected. The request
+ * must be extracted using the [PendingIntentHandler.retrieveProviderGetCredentialRequest] helper
+ * API.
+ *
+ * @constructor constructs an instance of [ProviderGetCredentialRequest]
+ *
+ * @param credentialOptions the list of credential retrieval options containing the
+ * required parameters, expected  to contain a single [CredentialOption] when this
+ * request is retrieved from the [android.app.Activity] invoked by the [android.app.PendingIntent]
+ * set on a [PasswordCredentialEntry] or a [PublicKeyCredentialEntry], or expected to contain
+ * multiple [CredentialOption] when this request is retrieved
+ * from the [android.app.Activity] invoked by the [android.app.PendingIntent]
+ * set on a [RemoteEntry]
+ * @param callingAppInfo information pertaining to the calling application
+ *
+ * Note : Credential providers are not expected to utilize the constructor in this class for any
+ * production flow. This constructor must only be used for testing purposes.
+ */
+class ProviderGetCredentialRequest constructor(
+    val credentialOptions: List<CredentialOption>,
+    val callingAppInfo: CallingAppInfo
+) {
+    internal companion object {
+        @JvmStatic
+        internal fun createFrom(
+            options: List<CredentialOption>,
+            callingAppInfo: CallingAppInfo
+        ): ProviderGetCredentialRequest {
+            return ProviderGetCredentialRequest(
+                options,
+                callingAppInfo)
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/PublicKeyCredentialEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/PublicKeyCredentialEntry.kt
new file mode 100644
index 0000000..b1a333f
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/PublicKeyCredentialEntry.kt
@@ -0,0 +1,405 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.content.Context
+import android.graphics.drawable.Icon
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.CredentialOption
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.R
+import java.time.Instant
+import java.util.Collections
+
+/**
+ * A public key credential entry that is displayed on the account selector UI. This
+ * entry denotes that a credential of type [PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL]
+ * is available for the user to select.
+ *
+ * Once this entry is selected, the corresponding [pendingIntent] will be invoked. The provider
+ * can then show any activity they wish to. Before finishing the activity, provider must
+ * set the final [androidx.credentials.GetCredentialResponse] through the
+ * [PendingIntentHandler.setGetCredentialResponse] helper API.
+ *
+ * @property username the username of the account holding the public key credential
+ * @property displayName the displayName of the account holding the public key credential
+ * @property lastUsedTime the last used time of this entry. Note that this value will only be
+ * distinguishable up to the milli second mark. If two entries have the same millisecond precision,
+ * they will be considered to have been used at the same time
+ * @property icon the icon to be displayed with this entry on the selector. If not set, a
+ * default icon representing a public key credential type is set by the library
+ * @property pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * authentication entry on the UI, must be created with flag [PendingIntent.FLAG_MUTABLE] so
+ * that the system can add the complete request to the extras of the associated intent
+ * @property isAutoSelectAllowed whether this entry is allowed to be auto
+ * selected if it is the only one on the UI. Note that setting this value
+ * to true does not guarantee this behavior. The developer must also set this
+ * to true, and the framework must determine that it is safe to auto select.
+ *
+ * @throws IllegalArgumentException if [username] is empty
+ */
+@RequiresApi(28)
+class PublicKeyCredentialEntry internal constructor(
+    val username: CharSequence,
+    val displayName: CharSequence?,
+    val typeDisplayName: CharSequence,
+    val pendingIntent: PendingIntent,
+    val icon: Icon,
+    val lastUsedTime: Instant?,
+    val isAutoSelectAllowed: Boolean,
+    beginGetPublicKeyCredentialOption: BeginGetPublicKeyCredentialOption,
+    private val autoSelectAllowedFromOption: Boolean = false,
+    private val isDefaultIcon: Boolean = false
+) : CredentialEntry(
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    beginGetPublicKeyCredentialOption,
+    toSlice(
+        PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+        username,
+        displayName,
+        pendingIntent,
+        typeDisplayName,
+        lastUsedTime,
+        icon,
+        isAutoSelectAllowed,
+        beginGetPublicKeyCredentialOption
+    )
+) {
+
+    init {
+        require(username.isNotEmpty()) { "username must not be empty" }
+        require(typeDisplayName.isNotEmpty()) { "typeDisplayName must not be empty" }
+    }
+
+    /**
+     * @constructor constructs an instance of [PublicKeyCredentialEntry]
+     *
+     * @param context the context of the calling app, required to retrieve fallback resources
+     * @param username the username of the account holding the public key credential
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     * @param beginGetPublicKeyCredentialOption the option from the original
+     * [BeginGetCredentialResponse], for which this credential entry is being added
+     * @param displayName the displayName of the account holding the public key credential
+     * @param lastUsedTime the last used time the credential underlying this entry was
+     * used by the user, distinguishable up to the milli second mark only such that if two
+     * entries have the same millisecond precision, they will be considered to have been used at
+     * the same time
+     * @param icon the icon to be displayed with this entry on the selector, if not set, a
+     * default icon representing a public key credential type is set by the library
+     * @param isAutoSelectAllowed whether this entry is allowed to be auto
+     * selected if it is the only one on the UI, only takes effect if the app requesting for
+     * credentials also opts for auto select
+     *
+     * @throws NullPointerException If [context], [username], [pendingIntent], or
+     * [beginGetPublicKeyCredentialOption] is null
+     * @throws IllegalArgumentException if [username] is empty
+     */
+    constructor(
+        context: Context,
+        username: CharSequence,
+        pendingIntent: PendingIntent,
+        beginGetPublicKeyCredentialOption: BeginGetPublicKeyCredentialOption,
+        displayName: CharSequence? = null,
+        lastUsedTime: Instant? = null,
+        icon: Icon = Icon.createWithResource(context, R.drawable.ic_passkey),
+        isAutoSelectAllowed: Boolean = false,
+    ) : this(
+        username,
+        displayName,
+        context.getString(
+            R.string.androidx_credentials_TYPE_PUBLIC_KEY_CREDENTIAL
+        ),
+        pendingIntent,
+        icon,
+        lastUsedTime,
+        isAutoSelectAllowed,
+        beginGetPublicKeyCredentialOption
+    )
+
+    internal companion object {
+        private const val TAG = "PublicKeyCredEntry"
+
+        private const val SLICE_HINT_TYPE_DISPLAY_NAME =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_TITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_USER_NAME"
+
+        private const val SLICE_HINT_SUBTITLE =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_CREDENTIAL_TYPE_DISPLAY_NAME"
+
+        private const val SLICE_HINT_LAST_USED_TIME_MILLIS =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_LAST_USED_TIME_MILLIS"
+
+        private const val SLICE_HINT_ICON =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PROFILE_ICON"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_PENDING_INTENT"
+
+        private const val SLICE_HINT_AUTO_ALLOWED =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_ALLOWED"
+
+        private const val SLICE_HINT_OPTION_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_OPTION_ID"
+
+        private const val SLICE_HINT_AUTO_SELECT_FROM_OPTION =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_AUTO_SELECT_FROM_OPTION"
+
+        private const val SLICE_HINT_DEFAULT_ICON_RES_ID =
+            "androidx.credentials.provider.credentialEntry.SLICE_HINT_DEFAULT_ICON_RES_ID"
+
+        private const val AUTO_SELECT_TRUE_STRING = "true"
+
+        private const val AUTO_SELECT_FALSE_STRING = "false"
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @JvmStatic
+        fun toSlice(
+            type: String,
+            title: CharSequence,
+            subTitle: CharSequence?,
+            pendingIntent: PendingIntent,
+            typeDisplayName: CharSequence?,
+            lastUsedTime: Instant?,
+            icon: Icon,
+            isAutoSelectAllowed: Boolean,
+            beginGetPublicKeyCredentialOption: BeginGetPublicKeyCredentialOption
+        ): Slice {
+            // TODO("Put the right revision value")
+            val autoSelectAllowed = if (isAutoSelectAllowed) {
+                AUTO_SELECT_TRUE_STRING
+            } else {
+                AUTO_SELECT_FALSE_STRING
+            }
+            val sliceBuilder = Slice.Builder(
+                Uri.EMPTY, SliceSpec(
+                    type, 1
+                )
+            )
+                .addText(
+                    typeDisplayName, /*subType=*/null,
+                    listOf(SLICE_HINT_TYPE_DISPLAY_NAME)
+                )
+                .addText(
+                    title, /*subType=*/null,
+                    listOf(SLICE_HINT_TITLE)
+                )
+                .addText(
+                    subTitle, /*subType=*/null,
+                    listOf(SLICE_HINT_SUBTITLE)
+                )
+                .addText(
+                    autoSelectAllowed, /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_ALLOWED)
+                )
+                .addText(
+                    beginGetPublicKeyCredentialOption.id,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_OPTION_ID)
+                )
+                .addIcon(
+                    icon, /*subType=*/null,
+                    listOf(SLICE_HINT_ICON)
+                )
+            try {
+                if (icon.resId == R.drawable.ic_passkey) {
+                    sliceBuilder.addInt(
+                        /*true=*/1,
+                        /*subType=*/null,
+                        listOf(SLICE_HINT_DEFAULT_ICON_RES_ID)
+                    )
+                }
+            } catch (_: IllegalStateException) {
+            }
+
+            if (CredentialOption.extractAutoSelectValue(
+                    beginGetPublicKeyCredentialOption.candidateQueryData
+                )
+            ) {
+                sliceBuilder.addInt(
+                    /*true=*/1,
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_AUTO_SELECT_FROM_OPTION)
+                )
+            }
+            if (lastUsedTime != null) {
+                sliceBuilder.addLong(
+                    lastUsedTime.toEpochMilli(),
+                    /*subType=*/null,
+                    listOf(SLICE_HINT_LAST_USED_TIME_MILLIS)
+                )
+            }
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(),
+                /*subType=*/null
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [CustomCredentialEntry] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): PublicKeyCredentialEntry? {
+            var typeDisplayName: CharSequence? = null
+            var title: CharSequence? = null
+            var subTitle: CharSequence? = null
+            var icon: Icon? = null
+            var pendingIntent: PendingIntent? = null
+            var lastUsedTime: Instant? = null
+            var autoSelectAllowed = false
+            var beginGetPublicKeyCredentialOptionId: CharSequence? = null
+            var autoSelectAllowedFromOption = false
+            var isDefaultIcon = false
+
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_TYPE_DISPLAY_NAME)) {
+                    typeDisplayName = it.text
+                } else if (it.hasHint(SLICE_HINT_TITLE)) {
+                    title = it.text
+                } else if (it.hasHint(SLICE_HINT_SUBTITLE)) {
+                    subTitle = it.text
+                } else if (it.hasHint(SLICE_HINT_ICON)) {
+                    icon = it.icon
+                } else if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                } else if (it.hasHint(SLICE_HINT_OPTION_ID)) {
+                    beginGetPublicKeyCredentialOptionId = it.text
+                } else if (it.hasHint(SLICE_HINT_LAST_USED_TIME_MILLIS)) {
+                    lastUsedTime = Instant.ofEpochMilli(it.long)
+                } else if (it.hasHint(SLICE_HINT_AUTO_ALLOWED)) {
+                    val autoSelectValue = it.text
+                    if (autoSelectValue == AUTO_SELECT_TRUE_STRING) {
+                        autoSelectAllowed = true
+                    }
+                } else if (it.hasHint(SLICE_HINT_AUTO_SELECT_FROM_OPTION)) {
+                    autoSelectAllowedFromOption = true
+                } else if (it.hasHint(SLICE_HINT_DEFAULT_ICON_RES_ID)) {
+                    isDefaultIcon = true
+                }
+            }
+
+            return try {
+                PublicKeyCredentialEntry(
+                    title!!,
+                    subTitle,
+                    typeDisplayName!!,
+                    pendingIntent!!,
+                    icon!!,
+                    lastUsedTime,
+                    autoSelectAllowed,
+                    BeginGetPublicKeyCredentialOption.createFromEntrySlice(
+                        Bundle(),
+                        beginGetPublicKeyCredentialOptionId!!.toString()
+                    ),
+                    autoSelectAllowedFromOption,
+                    isDefaultIcon
+                )
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+
+    /**
+     * Builder for [PublicKeyCredentialEntry]
+     */
+    class Builder(
+        private val context: Context,
+        private val username: CharSequence,
+        private val pendingIntent: PendingIntent,
+        private val beginGetPublicKeyCredentialOption: BeginGetPublicKeyCredentialOption
+    ) {
+        private var displayName: CharSequence? = null
+        private var lastUsedTime: Instant? = null
+        private var icon: Icon? = null
+        private var autoSelectAllowed: Boolean = false
+
+        /** Sets a displayName to be shown on the UI with this entry */
+        fun setDisplayName(displayName: CharSequence?): Builder {
+            this.displayName = displayName
+            return this
+        }
+
+        /** Sets the icon to be shown on the UI with this entry */
+        fun setIcon(icon: Icon): Builder {
+            this.icon = icon
+            return this
+        }
+
+        /**
+         * Sets whether the entry should be auto-selected.
+         * The value is false by default
+         */
+        @Suppress("MissingGetterMatchingBuilder")
+        fun setAutoSelectAllowed(autoSelectAllowed: Boolean): Builder {
+            this.autoSelectAllowed = autoSelectAllowed
+            return this
+        }
+
+        /**
+         * Sets the last used time of this account
+         *
+         * This information will be used to sort the entries on the selector.
+         */
+        fun setLastUsedTime(lastUsedTime: Instant?): Builder {
+            this.lastUsedTime = lastUsedTime
+            return this
+        }
+
+        /** Builds an instance of [PublicKeyCredentialEntry] */
+        fun build(): PublicKeyCredentialEntry {
+            if (icon == null) {
+                icon = Icon.createWithResource(context, R.drawable.ic_passkey)
+            }
+            val typeDisplayName = context.getString(
+                R.string.androidx_credentials_TYPE_PUBLIC_KEY_CREDENTIAL
+            )
+            return PublicKeyCredentialEntry(
+                username,
+                displayName,
+                typeDisplayName,
+                pendingIntent,
+                icon!!,
+                lastUsedTime,
+                autoSelectAllowed,
+                beginGetPublicKeyCredentialOption
+            )
+        }
+    }
+}
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/RemoteEntry.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/RemoteEntry.kt
new file mode 100644
index 0000000..dae3848
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/RemoteEntry.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.credentials.provider
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.app.slice.Slice
+import android.app.slice.SliceSpec
+import android.net.Uri
+import android.util.Log
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import java.util.Collections
+
+/**
+ * An entry on the selector, denoting that the credential request will be completed on a remote
+ * device.
+ *
+ * Once this entry is selected, the corresponding [pendingIntent] will be invoked. The provider
+ * can then show any activity they wish to while establishing a connection with a different
+ * device and retrieving a credential. Before finishing the activity, provider must
+ * set the final [androidx.credentials.GetCredentialResponse] through the
+ * [PendingIntentHandler.setGetCredentialResponse] helper API, or a
+ * [androidx.credentials.CreateCredentialResponse] through the
+ * [PendingIntentHandler.setCreateCredentialResponse] helper API depending on whether it is a get
+ * or create flow.
+ *
+ * See [android.service.credentials.BeginGetCredentialResponse] for usage details.
+ *
+ * @constructor constructs an instance of [RemoteEntry]
+ *
+ * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+ * authentication entry on the UI, must be created with flag [PendingIntent.FLAG_MUTABLE] so
+ * that the system can add the complete request to the extras of the associated intent
+ *
+ * @throws NullPointerException If [pendingIntent] is null
+ */
+class RemoteEntry constructor(
+    val pendingIntent: PendingIntent
+) {
+    /**
+     * A builder for [RemoteEntry]
+     *
+     * @param pendingIntent the [PendingIntent] that will get invoked when the user selects this
+     * entry, must be created with flag [PendingIntent.FLAG_MUTABLE] to allow the Android
+     * system to attach the final request
+     */
+    class Builder constructor(
+        private val pendingIntent: PendingIntent
+    ) {
+        /**
+         * Builds an instance of [RemoteEntry]
+         */
+        fun build(): RemoteEntry {
+            return RemoteEntry(pendingIntent)
+        }
+    }
+
+    internal companion object {
+        private const val TAG = "RemoteEntry"
+
+        private const val SLICE_HINT_PENDING_INTENT =
+            "androidx.credentials.provider.remoteEntry.SLICE_HINT_PENDING_INTENT"
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @JvmStatic
+        fun toSlice(
+            remoteEntry: RemoteEntry
+        ): Slice {
+            val pendingIntent = remoteEntry.pendingIntent
+            // TODO("Put the right spec and version value")
+            val sliceBuilder = Slice.Builder(Uri.EMPTY, SliceSpec("type", 1))
+            sliceBuilder.addAction(
+                pendingIntent,
+                Slice.Builder(sliceBuilder)
+                    .addHints(Collections.singletonList(SLICE_HINT_PENDING_INTENT))
+                    .build(), /*subType=*/null
+            )
+            return sliceBuilder.build()
+        }
+
+        /**
+         * Returns an instance of [RemoteEntry] derived from a [Slice] object.
+         *
+         * @param slice the [Slice] object constructed through [toSlice]
+         *
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @RequiresApi(28)
+        @SuppressLint("WrongConstant") // custom conversion between jetpack and framework
+        @JvmStatic
+        fun fromSlice(slice: Slice): RemoteEntry? {
+            var pendingIntent: PendingIntent? = null
+            slice.items.forEach {
+                if (it.hasHint(SLICE_HINT_PENDING_INTENT)) {
+                    pendingIntent = it.action
+                }
+            }
+            return try {
+                RemoteEntry(pendingIntent!!)
+            } catch (e: Exception) {
+                Log.i(TAG, "fromSlice failed with: " + e.message)
+                null
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginCreateCredentialUtil.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginCreateCredentialUtil.kt
new file mode 100644
index 0000000..dc17de7
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginCreateCredentialUtil.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider.utils
+
+import android.annotation.SuppressLint
+import androidx.annotation.RequiresApi
+import androidx.credentials.PasswordCredential
+import androidx.credentials.PublicKeyCredential
+import androidx.credentials.internal.FrameworkClassParsingException
+import androidx.credentials.provider.BeginCreateCredentialRequest
+import androidx.credentials.provider.BeginCreateCredentialResponse
+import androidx.credentials.provider.BeginCreateCustomCredentialRequest
+import androidx.credentials.provider.BeginCreatePasswordCredentialRequest
+import androidx.credentials.provider.BeginCreatePublicKeyCredentialRequest
+import androidx.credentials.provider.CallingAppInfo
+import androidx.credentials.provider.CreateEntry
+import androidx.credentials.provider.RemoteEntry
+import java.util.stream.Collectors
+
+@RequiresApi(34)
+internal class BeginCreateCredentialUtil {
+    internal companion object {
+        @JvmStatic
+        internal fun convertToJetpackRequest(
+            request: android.service.credentials.BeginCreateCredentialRequest
+        ):
+            BeginCreateCredentialRequest {
+            return try {
+                when (request.type) {
+                    PasswordCredential.TYPE_PASSWORD_CREDENTIAL -> {
+                        BeginCreatePasswordCredentialRequest.createFrom(
+                            request.data, request.callingAppInfo?.let {
+                                CallingAppInfo(it.packageName,
+                                    it.signingInfo, it.origin)
+                            }
+                        )
+                    }
+
+                    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL -> {
+                        BeginCreatePublicKeyCredentialRequest.createFrom(
+                            request.data,
+                            request.callingAppInfo?.let {
+                                CallingAppInfo(it.packageName,
+                                    it.signingInfo, it.origin)
+                            }
+                        )
+                    }
+
+                    else -> {
+                        BeginCreateCustomCredentialRequest(
+                            request.type, request.data,
+                            request.callingAppInfo?.let {
+                                CallingAppInfo(it.packageName,
+                                    it.signingInfo, it.origin)
+                            }
+                        )
+                    }
+                }
+            } catch (e: FrameworkClassParsingException) {
+                BeginCreateCustomCredentialRequest(
+                    request.type,
+                    request.data,
+                    request.callingAppInfo?.let {
+                        CallingAppInfo(it.packageName,
+                            it.signingInfo, it.origin)
+                    }
+                )
+            }
+        }
+
+        fun convertToFrameworkResponse(
+            response: BeginCreateCredentialResponse
+        ): android.service.credentials.BeginCreateCredentialResponse {
+            val frameworkBuilder = android.service.credentials.BeginCreateCredentialResponse
+                .Builder()
+            populateCreateEntries(frameworkBuilder, response.createEntries)
+            populateRemoteEntry(frameworkBuilder, response.remoteEntry)
+            return frameworkBuilder.build()
+        }
+
+        @SuppressLint("MissingPermission") // This is an internal util. Actual permission check
+        // happens at the framework level
+        private fun populateRemoteEntry(
+            frameworkBuilder: android.service.credentials.BeginCreateCredentialResponse.Builder,
+            remoteEntry: RemoteEntry?
+        ) {
+            if (remoteEntry == null) {
+                return
+            }
+            frameworkBuilder.setRemoteCreateEntry(
+                android.service.credentials.RemoteEntry(
+                    RemoteEntry.toSlice(remoteEntry)
+                )
+            )
+        }
+
+        private fun populateCreateEntries(
+            frameworkBuilder: android.service.credentials.BeginCreateCredentialResponse.Builder,
+            createEntries: List<CreateEntry>
+        ) {
+            createEntries.forEach {
+                frameworkBuilder.addCreateEntry(
+                    android.service.credentials.CreateEntry(
+                        CreateEntry.toSlice(it)
+                    )
+                )
+            }
+        }
+
+        fun convertToFrameworkRequest(request: BeginCreateCredentialRequest):
+            android.service.credentials.BeginCreateCredentialRequest {
+            var callingAppInfo: android.service.credentials.CallingAppInfo? = null
+            if (request.callingAppInfo != null) {
+                callingAppInfo = android.service.credentials.CallingAppInfo(
+                    request.callingAppInfo.packageName,
+                    request.callingAppInfo.signingInfo,
+                    request.callingAppInfo.origin
+                )
+            }
+            return android.service.credentials.BeginCreateCredentialRequest(
+                request.type, request.candidateQueryData, callingAppInfo)
+        }
+
+        fun convertToJetpackResponse(
+            frameworkResponse: android.service.credentials.BeginCreateCredentialResponse
+        ): BeginCreateCredentialResponse {
+            return BeginCreateCredentialResponse(
+                createEntries = frameworkResponse.createEntries.stream()
+                    .map { entry -> CreateEntry.fromSlice(entry.slice) }
+                    .filter { entry -> entry != null }
+                    .map { entry -> entry!! }
+                    .collect(Collectors.toList()),
+                remoteEntry =
+                frameworkResponse.remoteCreateEntry?.let { RemoteEntry.fromSlice(it.slice) }
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginGetCredentialUtil.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginGetCredentialUtil.kt
new file mode 100644
index 0000000..8752bcc
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/BeginGetCredentialUtil.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider.utils
+
+import android.annotation.SuppressLint
+import android.os.Bundle
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.provider.Action
+import androidx.credentials.provider.AuthenticationAction
+import androidx.credentials.provider.BeginGetCredentialOption
+import androidx.credentials.provider.BeginGetCredentialRequest
+import androidx.credentials.provider.BeginGetCredentialResponse
+import androidx.credentials.provider.CallingAppInfo
+import androidx.credentials.provider.CredentialEntry
+import androidx.credentials.provider.RemoteEntry
+import java.util.stream.Collectors
+
+@RequiresApi(34)
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class BeginGetCredentialUtil {
+    companion object {
+        @JvmStatic
+        internal fun convertToJetpackRequest(
+            request: android.service.credentials.BeginGetCredentialRequest
+        ): BeginGetCredentialRequest {
+            val beginGetCredentialOptions: MutableList<BeginGetCredentialOption> =
+                mutableListOf()
+            request.beginGetCredentialOptions.forEach {
+                beginGetCredentialOptions.add(
+                    BeginGetCredentialOption.createFrom(
+                        it.id, it.type, it.candidateQueryData
+                    )
+                )
+            }
+            return BeginGetCredentialRequest(
+                callingAppInfo = request.callingAppInfo?.let {
+                    CallingAppInfo(it.packageName, it.signingInfo, it.origin)
+                },
+                beginGetCredentialOptions = beginGetCredentialOptions
+            )
+        }
+
+        fun convertToFrameworkResponse(response: BeginGetCredentialResponse):
+            android.service.credentials.BeginGetCredentialResponse {
+            val frameworkBuilder = android.service.credentials.BeginGetCredentialResponse.Builder()
+            populateCredentialEntries(frameworkBuilder, response.credentialEntries)
+            populateActionEntries(frameworkBuilder, response.actions)
+            populateAuthenticationEntries(frameworkBuilder, response.authenticationActions)
+            populateRemoteEntry(frameworkBuilder, response.remoteEntry)
+            return frameworkBuilder.build()
+        }
+
+        @SuppressLint("MissingPermission") // This is an internal util. Actual permission check
+        // happens at the framework level
+        private fun populateRemoteEntry(
+            frameworkBuilder: android.service.credentials.BeginGetCredentialResponse.Builder,
+            remoteEntry: RemoteEntry?
+        ) {
+            if (remoteEntry == null) {
+                return
+            }
+            frameworkBuilder.setRemoteCredentialEntry(
+                android.service.credentials.RemoteEntry(RemoteEntry.toSlice(remoteEntry))
+            )
+        }
+
+        private fun populateAuthenticationEntries(
+            frameworkBuilder: android.service.credentials.BeginGetCredentialResponse.Builder,
+            authenticationActions: List<AuthenticationAction>
+        ) {
+            authenticationActions.forEach {
+                frameworkBuilder.addAuthenticationAction(
+                    android.service.credentials.Action(
+                        AuthenticationAction.toSlice(it)
+                    )
+                )
+            }
+        }
+
+        private fun populateActionEntries(
+            builder: android.service.credentials.BeginGetCredentialResponse.Builder,
+            actionEntries: List<Action>
+        ) {
+            actionEntries.forEach {
+                builder.addAction(
+                    android.service.credentials.Action(
+                        Action.toSlice(it)
+                    )
+                )
+            }
+        }
+
+        private fun populateCredentialEntries(
+            builder: android.service.credentials.BeginGetCredentialResponse.Builder,
+            credentialEntries: List<CredentialEntry>
+        ) {
+            credentialEntries.forEach {
+                builder.addCredentialEntry(
+                    android.service.credentials.CredentialEntry(
+                        android.service.credentials.BeginGetCredentialOption(
+                            it.beginGetCredentialOption.id,
+                            it.type,
+                            Bundle.EMPTY
+                        ),
+                        it.slice
+                    )
+                )
+            }
+        }
+
+        fun convertToFrameworkRequest(request: BeginGetCredentialRequest):
+            android.service.credentials.BeginGetCredentialRequest {
+            val builder = android.service.credentials.BeginGetCredentialRequest.Builder()
+            if (request.callingAppInfo != null) {
+                builder.setCallingAppInfo(
+                    android.service.credentials.CallingAppInfo(
+                        request.callingAppInfo.packageName,
+                        request.callingAppInfo.signingInfo,
+                        request.callingAppInfo.origin
+                    )
+                )
+            }
+            return builder.setBeginGetCredentialOptions(request.beginGetCredentialOptions.stream()
+                    .map { option -> convertToJetpackBeginOption(option) }
+                    .collect(Collectors.toList()))
+                .build()
+        }
+
+        private fun convertToJetpackBeginOption(option: BeginGetCredentialOption):
+            android.service.credentials.BeginGetCredentialOption {
+            return android.service.credentials.BeginGetCredentialOption(option.id, option.type,
+                option.candidateQueryData)
+        }
+
+        fun convertToJetpackResponse(
+            response: android.service.credentials.BeginGetCredentialResponse
+        ): BeginGetCredentialResponse {
+            return BeginGetCredentialResponse(
+                credentialEntries = response.credentialEntries.stream()
+                    .map { entry -> CredentialEntry.createFrom(entry.slice) }
+                    .filter { entry -> entry != null }
+                    .map { entry -> entry!! }
+                    .collect(Collectors.toList()),
+                actions = response.actions.stream()
+                    .map { entry -> Action.fromSlice(entry.slice) }
+                    .filter { entry -> entry != null }
+                    .map { entry -> entry!! }
+                    .collect(Collectors.toList()),
+                authenticationActions = response.authenticationActions.stream()
+                    .map { entry -> AuthenticationAction.fromSlice(entry.slice) }
+                    .filter { entry -> entry != null }
+                    .map { entry -> entry!! }
+                    .collect(Collectors.toList()),
+                remoteEntry =
+                response.remoteCredentialEntry?.let { RemoteEntry.fromSlice(it.slice) }
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/utils/ClearCredentialUtil.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/ClearCredentialUtil.kt
new file mode 100644
index 0000000..0ee7924
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/ClearCredentialUtil.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.credentials.provider.utils
+
+import android.service.credentials.ClearCredentialStateRequest
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.credentials.provider.CallingAppInfo
+import androidx.credentials.provider.ProviderClearCredentialStateRequest
+
+@RequiresApi(34)
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class ClearCredentialUtil {
+    companion object {
+        @JvmStatic
+        internal fun convertToJetpackRequest(request: ClearCredentialStateRequest):
+            ProviderClearCredentialStateRequest {
+
+            return ProviderClearCredentialStateRequest(
+                CallingAppInfo(
+                    request.callingAppInfo.packageName,
+                    request.callingAppInfo.signingInfo,
+                    request.callingAppInfo.origin))
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/provider/utils/RequestValidationUtil.kt b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/RequestValidationUtil.kt
new file mode 100644
index 0000000..308115f
--- /dev/null
+++ b/credentials/credentials/src/main/java/androidx/credentials/provider/utils/RequestValidationUtil.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.credentials.provider.utils
+
+import androidx.annotation.RestrictTo
+import org.json.JSONObject
+
+internal class RequestValidationUtil {
+    companion object {
+        /**
+         * Determines whether the given string is a valid JSON.
+         */
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @JvmStatic
+        fun isValidJSON(jsonString: String): Boolean {
+            if (jsonString.isEmpty()) {
+                return false
+            }
+            return try {
+                JSONObject(jsonString)
+                true
+            } catch (ex: Exception) {
+                false
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/res/values-ky/strings.xml b/credentials/credentials/src/main/res/values-ky/strings.xml
index 3366129..240c775 100644
--- a/credentials/credentials/src/main/res/values-ky/strings.xml
+++ b/credentials/credentials/src/main/res/values-ky/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"Мүмкүндүк алуу ачкычы"</string>
+    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"Киргизүүчү ачкыч"</string>
     <string name="android.credentials.TYPE_PASSWORD_CREDENTIAL" msgid="8397015543330865059">"Сырсөз"</string>
 </resources>
diff --git a/credentials/credentials/src/main/res/values-ta/strings.xml b/credentials/credentials/src/main/res/values-ta/strings.xml
index 458bcb4..d3f9b1f 100644
--- a/credentials/credentials/src/main/res/values-ta/strings.xml
+++ b/credentials/credentials/src/main/res/values-ta/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"கடவுக்குறியீடு"</string>
+    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"கடவுச்சாவி"</string>
     <string name="android.credentials.TYPE_PASSWORD_CREDENTIAL" msgid="8397015543330865059">"கடவுச்சொல்"</string>
 </resources>
diff --git a/credentials/credentials/src/main/res/values-vi/strings.xml b/credentials/credentials/src/main/res/values-vi/strings.xml
index 28a4e5a..23321ed 100644
--- a/credentials/credentials/src/main/res/values-vi/strings.xml
+++ b/credentials/credentials/src/main/res/values-vi/strings.xml
@@ -17,6 +17,6 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"Mã xác thực"</string>
+    <string name="androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL" msgid="3929015085059320822">"Khoá truy cập"</string>
     <string name="android.credentials.TYPE_PASSWORD_CREDENTIAL" msgid="8397015543330865059">"Mật khẩu"</string>
 </resources>
diff --git a/datastore/datastore-core-okio/api/current.txt b/datastore/datastore-core-okio/api/current.txt
index 08053b5..696e22b 100644
--- a/datastore/datastore-core-okio/api/current.txt
+++ b/datastore/datastore-core-okio/api/current.txt
@@ -2,10 +2,10 @@
 package androidx.datastore.core.okio {
 
   public interface OkioSerializer<T> {
-    method public T! getDefaultValue();
+    method public T getDefaultValue();
     method public suspend Object? readFrom(okio.BufferedSource source, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? writeTo(T? t, okio.BufferedSink sink, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public abstract T! defaultValue;
+    method public suspend Object? writeTo(T t, okio.BufferedSink sink, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract T defaultValue;
   }
 
   public final class OkioStorage<T> implements androidx.datastore.core.Storage<T> {
diff --git a/datastore/datastore-core-okio/api/restricted_current.txt b/datastore/datastore-core-okio/api/restricted_current.txt
index 08053b5..696e22b 100644
--- a/datastore/datastore-core-okio/api/restricted_current.txt
+++ b/datastore/datastore-core-okio/api/restricted_current.txt
@@ -2,10 +2,10 @@
 package androidx.datastore.core.okio {
 
   public interface OkioSerializer<T> {
-    method public T! getDefaultValue();
+    method public T getDefaultValue();
     method public suspend Object? readFrom(okio.BufferedSource source, kotlin.coroutines.Continuation<? super T>);
-    method public suspend Object? writeTo(T? t, okio.BufferedSink sink, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public abstract T! defaultValue;
+    method public suspend Object? writeTo(T t, okio.BufferedSink sink, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public abstract T defaultValue;
   }
 
   public final class OkioStorage<T> implements androidx.datastore.core.Storage<T> {
diff --git a/datastore/datastore-core-okio/build.gradle b/datastore/datastore-core-okio/build.gradle
index 99bb8ec..555b3db 100644
--- a/datastore/datastore-core-okio/build.gradle
+++ b/datastore/datastore-core-okio/build.gradle
@@ -17,6 +17,7 @@
 
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
 
@@ -32,6 +33,8 @@
     linux()
     ios()
 
+    defaultPlatform(PlatformIdentifier.JVM)
+
     sourceSets {
         all {
             languageSettings.optIn("kotlin.RequiresOptIn")
diff --git a/datastore/datastore-core/build.gradle b/datastore/datastore-core/build.gradle
index 67e6e17..9679678 100644
--- a/datastore/datastore-core/build.gradle
+++ b/datastore/datastore-core/build.gradle
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
 
@@ -63,6 +63,8 @@
     ios()
     android()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         all {
             languageSettings.optIn("kotlin.RequiresOptIn")
diff --git a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/SimpleActorTest.kt b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/SimpleActorTest.kt
index e6446b5..154e868 100644
--- a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/SimpleActorTest.kt
+++ b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/SimpleActorTest.kt
@@ -73,6 +73,7 @@
         assertThat(msgs).isEqualTo(listOf(1, 2, 3, 4))
     }
 
+    @Ignore("b/281516026")
     @Test
     fun testOnCompleteIsCalledWhenScopeIsCancelled() = runBlocking<Unit> {
         val scope = CoroutineScope(Job())
diff --git a/datastore/datastore-preferences-core/build.gradle b/datastore/datastore-preferences-core/build.gradle
index 9567f6b..968d4ae 100644
--- a/datastore/datastore-preferences-core/build.gradle
+++ b/datastore/datastore-preferences-core/build.gradle
@@ -18,6 +18,7 @@
 import androidx.build.BundleInsideHelper
 import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
 
@@ -36,6 +37,8 @@
     linux()
     ios()
 
+    defaultPlatform(PlatformIdentifier.JVM)
+
     sourceSets {
         all {
             languageSettings.optIn("kotlin.RequiresOptIn")
diff --git a/datastore/datastore-preferences/build.gradle b/datastore/datastore-preferences/build.gradle
index 0bbbbe6..f8de5a6 100644
--- a/datastore/datastore-preferences/build.gradle
+++ b/datastore/datastore-preferences/build.gradle
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+
+import androidx.build.PlatformIdentifier
 import androidx.build.Publish
 
 plugins {
@@ -33,6 +35,9 @@
     linux()
     ios()
     android()
+
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/datastore/datastore/build.gradle b/datastore/datastore/build.gradle
index 8b4451d..474f8c8 100644
--- a/datastore/datastore/build.gradle
+++ b/datastore/datastore/build.gradle
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-
-import androidx.build.KmpPlatformsKt
 import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -33,6 +32,9 @@
     ios()
     linux()
     android()
+
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/development/auto-version-updater/update_versions_for_release.py b/development/auto-version-updater/update_versions_for_release.py
index 008f4846b..1199ccb 100755
--- a/development/auto-version-updater/update_versions_for_release.py
+++ b/development/auto-version-updater/update_versions_for_release.py
@@ -408,17 +408,6 @@
         version_checker_lines = f.readlines()
     num_lines = len(version_checker_lines)
 
-    for i in range(num_lines):
-        cur_line = version_checker_lines[i]
-        # Skip any line that doesn't declare the compiler/compose version
-        if 'const val compilerVersion: String = ' not in cur_line: continue
-        current_version = cur_line.split('const val compilerVersion: String = ')[1].strip('"\n')
-        # Only update if we have a higher version.
-        version_to_keep = get_higher_version(current_version, updated_compose_version)
-        new_version_line = '        const val compilerVersion: String = "%s"\n' % version_to_keep
-        version_checker_lines[i] = new_version_line
-        break
-
     old_runtime_version = compose_to_runtime_version_map[old_version]["runtime_version"]
     if "alpha" in updated_compose_version or "beta" in updated_compose_version:
         new_compose_runtime_version = old_runtime_version + 100
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index 4dda2bb..1804337 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -102,6 +102,18 @@
 Encountered duplicate path "androidx/test/espresso/remote/.*.java" during copy operation configured with DuplicatesStrategy.WARN
 # > Task :docs-public:dackkaDocs
 ERROR: An attempt to write .*
+WARNING: no common sourceSet for androidx\.compose\..*, falling back to \.single\(\) when resolving @sample androidx\.compose\..*
+WARNING: no common( or jvm)? source set for DParameter .*
+WARNING: no common( or jvm)? source set for DTypeAlias .*
+WARNING: no common( or jvm)? source set for DClass .*Kt//.*
+WARNING: no common or jvm source set for DClass androidx\.datastore\.preferences/PreferenceDataStoreFile///PointingToDeclaration/! Falling back to androidMain sourceSet! This is only defensible if every usable sourceSet depends on androidMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common source set for DPackage androidx\.compose\.ui\.test\.junit[0-9]+////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every usable sourceSet depends on jvmMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common or jvm source set for DPackage androidx\.compose\.ui\.text\.platform////PointingToDeclaration/! Falling back to androidMain sourceSet! This is only defensible if every usable sourceSet depends on androidMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common source set for DPackage androidx\.compose\.ui\.tooling////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every usable sourceSet depends on jvmMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common source set for DPackage androidx\.compose\.ui\.test\.junit[0-9]+////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every sourceSet depends onjvmMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common source set for DPackage androidx\.compose\.ui\.tooling////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every sourceSet depends onjvmMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common or jvm source set for DPackage androidx\.datastore\.preferences////PointingToDeclaration/! Falling back to androidMain sourceSet! This is only defensible if every usable sourceSet depends on androidMain! This is a bug in dackka: b/[0-9]+
+WARNING: no common or jvm source set for DPackage androidx\.compose\.ui\.res////PointingToDeclaration/! Falling back to androidMain sourceSet! This is only defensible if every usable sourceSet depends on androidMain! This is a bug in dackka: b/[0-9]+
 WARN: Missing @param tag for parameter `activity` of function androidx\.appcompat\.app/AppCompatDelegate/create/\#android\.app\.Activity\#androidx\.appcompat\.app\.AppCompatCallback/PointingToDeclaration/
 WARN: Missing @param tag for parameter `dialog` of function androidx\.appcompat\.app/AppCompatDelegate/create/\#android\.app\.Dialog\#androidx\.appcompat\.app\.AppCompatCallback/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.appcompat\.app/AppCompatDelegate/create/\#android\.content\.Context\#android\.view\.Window\#androidx\.appcompat\.app\.AppCompatCallback/PointingToDeclaration/
@@ -116,97 +128,17 @@
 WARN: Missing @param tag for parameter `shouldRunMigration` of function androidx\.datastore\.migrations/SharedPreferencesMigration/SharedPreferencesMigration/\#android\.content\.Context\#kotlin\.String\#kotlin\.collections\.Set\[kotlin\.String\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Boolean\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.datastore\.migrations\.SharedPreferencesView,TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `alpha` of function androidx\.compose\.ui\.graphics/Color\.Companion/hsl/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.colorspace\.Rgb/PointingToDeclaration/
 WARN: Missing @param tag for parameter `alpha` of function androidx\.compose\.ui\.graphics/Color\.Companion/hsv/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.colorspace\.Rgb/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/linearGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.LinearGradientSample\. b/[0-9]+
 WARN: Multiple sources exist for OffsetEffect\. Artifact ID metadata will not be displayed
 WARN: Missing @param tag for parameter `v` of function androidx\.compose\.ui\.graphics/ColorMatrix/set/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/ImageBitmap/toPixelMap/androidx\.compose\.ui\.graphics\.ImageBitmap\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.IntArray\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.ImageBitmapToPixelMapSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/horizontalGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `operation` of function androidx\.compose\.ui\.graphics/Path/op/\#androidx\.compose\.ui\.graphics\.Path\#androidx\.compose\.ui\.graphics\.Path\#androidx\.compose\.ui\.graphics\.PathOperation/PointingToDeclaration/
 WARN: Multiple sources exist for RenderEffect\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics//graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.RenderEffect\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.CompositingStrategy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ChangeOpacity\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/linearGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics//graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.RenderEffect\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.CompositingStrategy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CompositingStrategyModulateAlpha\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/radialGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.RadialBrushColorStopSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/radialGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/radialGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.RadialBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics//graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AnimateFadeIn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/radialGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/sweepGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.SweepGradientColorStopSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/sweepGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/sweepGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.SweepGradientSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/sweepGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#androidx\.compose\.ui\.geometry\.Offset/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `radians` of function androidx\.compose\.ui\.graphics/Canvas/rotateRad/androidx\.compose\.ui\.graphics\.Canvas\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `density` of function androidx\.compose\.ui\.graphics\.drawscope/CanvasDrawScope/draw/\#androidx\.compose\.ui\.unit\.Density\#androidx\.compose\.ui\.unit\.LayoutDirection\#androidx\.compose\.ui\.graphics\.Canvas\#androidx\.compose\.ui\.geometry\.Size\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `layoutDirection` of function androidx\.compose\.ui\.graphics\.drawscope/CanvasDrawScope/draw/\#androidx\.compose\.ui\.unit\.Density\#androidx\.compose\.ui\.unit\.LayoutDirection\#androidx\.compose\.ui\.graphics\.Canvas\#androidx\.compose\.ui\.geometry\.Size\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawOval/\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Size\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\#androidx\.compose\.ui\.graphics\.ColorFilter\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.DrawScopeOvalBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/withTransform/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawTransform,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.DrawScopeBatchedTransformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawOval/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Size\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\#androidx\.compose\.ui\.graphics\.ColorFilter\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.DrawScopeOvalColorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope//withTransform/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawTransform,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.DrawScopeBatchedTransformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#androidx\.compose\.ui\.text\.AnnotatedString\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.AnnotatedString\.Range\[androidx\.compose\.ui\.text\.Placeholder\]\]\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextAnnotatedStringSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#kotlin\.String\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#kotlin\.String\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextStyledSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextLayoutResult\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextMeasureInLayoutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope/drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextLayoutResult\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextDrawWithCacheSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `pathFillType` of function androidx\.compose\.ui\.graphics\.vector//path/androidx\.compose\.ui\.graphics\.vector\.ImageVector\.Builder\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.StrokeCap\#androidx\.compose\.ui\.graphics\.StrokeJoin\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.PathFillType\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.vector\.PathBuilder,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `autoMirror` of function androidx\.compose\.ui\.graphics\.vector//rememberVectorPainter/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Float\#kotlin\.Float\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.BlendMode\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//isAltPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsAltPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//onInterceptKeyBeforeSoftKeyboard/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEventType\.Companion/KeyDown/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/isAltPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsAltPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//isCtrlPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsCtrlPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEventType\.Companion/KeyUp/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//onKeyEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/isCtrlPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsCtrlPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//onPreInterceptKeyBeforeSoftKeyboard/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEventType\.Companion/Unknown/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/isMetaPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsMetaPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//isMetaPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsMetaPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//onPreviewKeyEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//isShiftPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsShiftPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/isShiftPressed/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsShiftPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//key/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsAltPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/key/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsAltPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent/type/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key//type/androidx\.compose\.ui\.input\.key\.KeyEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
 WARN: Multiple sources exist for Key\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.nestedscroll//nestedScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollDispatcher\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.NestedScrollConnectionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.nestedscroll//nestedScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollDispatcher\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.NestedScrollDispatcherSample\. b/[0-9]+
 WARN: Multiple sources exist for PointerEvent\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerEvent/calculateCentroid/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateCentroidSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerInputScope/detectDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerEvent/calculateCentroidSize/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateCentroidSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitHorizontalDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitHorizontalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerInputScope/detectDragGesturesAfterLongPress/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectDragWithLongPressGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerEvent/calculatePan/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculatePan\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitHorizontalTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitHorizontalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerEvent/calculateRotation/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateRotation\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerHoverIcon/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.pointer\.PointerIcon\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PointerIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerInputScope/detectHorizontalDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectHorizontalDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerEvent/calculateZoom/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateZoom\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitLongPressOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitLongPressOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerInputScope/detectVerticalDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectVerticalDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitVerticalDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitVerticalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/PointerInputScope/detectTransformGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectTransformGestures\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer//pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/awaitVerticalTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitVerticalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/drag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DragSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/horizontalDrag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HorizontalDragSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.pointer/AwaitPointerEventScope/verticalDrag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.VerticalDragSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.rotary//onPreRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PreRotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.rotary//onRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.rotary//onRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PreRotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//Layout/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.MeasurePolicy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//layoutId/androidx\.compose\.ui\.layout\.Measurable\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutTagChildrenUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/Measurable/layoutId/androidx\.compose\.ui\.layout\.Measurable\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutTagChildrenUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/Placeable\.PlacementScope/coordinates/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PlacementScopeCoordinatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//intermediateLayout/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.IntermediateMeasureScope,androidx\.compose\.ui\.layout\.Measurable,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.IntermediateLayoutSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `trimPathEnd` of function androidx\.compose\.ui\.graphics\.vector/ImageVector\.Builder/addPath/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.vector\.PathNode\]\#androidx\.compose\.ui\.graphics\.PathFillType\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.StrokeCap\#androidx\.compose\.ui\.graphics\.StrokeJoin\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `pathFillType` of function androidx\.compose\.ui\.graphics\.vector/ImageVector\.Builder/path/androidx\.compose\.ui\.graphics\.vector\.ImageVector\.Builder\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.StrokeCap\#androidx\.compose\.ui\.graphics\.StrokeJoin\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.PathFillType\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.vector\.PathBuilder,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Failed to resolve `@see SdkSandboxManager\.startSdkSandboxActivity`!
@@ -218,48 +150,19 @@
 WARN: Failed to resolve `@see SdkSandboxController\.unregisterSdkSandboxActivityHandler`!
 Did you mean SdkSandboxController\#unregisterSdkSandboxActivityHandler\?
 WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable/placeAt/\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//layoutId/androidx\.compose\.ui\.Modifier\#kotlin\.Any/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutTagChildrenUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LookaheadScope/onPlaced/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LookaheadLayoutCoordinates,androidx\.compose\.ui\.layout\.LookaheadLayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LookaheadLayoutCoordinatesSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `x` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/place/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `y` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/place/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//layout/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.MeasureScope,androidx\.compose\.ui\.layout\.Measurable,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ConvenienceLayoutModifierSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/place/androidx\.compose\.ui\.layout\.Placeable\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LookaheadLayoutScope/onPlaced/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LookaheadLayoutCoordinates,androidx\.compose\.ui\.layout\.LookaheadLayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LookaheadLayoutCoordinatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LookaheadLayoutScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LookaheadLayoutCoordinatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LookaheadScope/intermediateLayout/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.MeasureScope,androidx\.compose\.ui\.layout\.Measurable,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.IntermediateLayoutSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelative/androidx\.compose\.ui\.layout\.Placeable\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `x` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelative/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `y` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelative/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelativeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//onGloballyPositioned/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnGloballyPositioned\. b/[0-9]+
 WARN: Missing @param tag for parameter `x` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelativeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `y` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeRelativeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `x` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//Layout/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.MeasurePolicy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutWithProvidedIntrinsicsUsage\. b/[0-9]+
 WARN: Missing @param tag for parameter `y` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//onSizeChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnSizeChangedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//Layout/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.MeasurePolicy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//Layout/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.MeasurePolicy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutWithProvidedIntrinsicsUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//Layout/\#kotlin\.collections\.List\[kotlin\.Function[0-9]+\[kotlin\.Unit\]\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.MultiContentMeasurePolicy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutWithMultipleContentsUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//LookaheadScope/\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LookaheadScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LookaheadLayoutCoordinatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//SubcomposeLayout/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.SubcomposeIntermediateMeasureScope,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.SubcomposeMeasureScope,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SubcomposeLayoutWithIntermediateMeasurePolicySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//SubcomposeLayout/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.SubcomposeMeasureScope,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SubcomposeLayoutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//SubcomposeLayout/\#androidx\.compose\.ui\.layout\.SubcomposeLayoutState\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.SubcomposeMeasureScope,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SubcomposeLayoutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.modifier//modifierLocalOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierLocalParentChildCommunicationWithinLayoutNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.modifier//modifierLocalOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierLocalChildParentCommunicationWithinLayoutNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.modifier//modifierLocalOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierLocalParentChildCommunicationInterLayoutNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.modifier//modifierLocalOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierLocalChildParentCommunicationInterLayoutNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/CompositionLocalConsumerModifierNode/currentValueOf/androidx\.compose\.ui\.node\.CompositionLocalConsumerModifierNode\#androidx\.compose\.runtime\.CompositionLocal\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CompositionLocalConsumingModifierObserverNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node//currentValueOf/androidx\.compose\.ui\.node\.CompositionLocalConsumerModifierNode\#androidx\.compose\.runtime\.CompositionLocal\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CompositionLocalConsumingModifierObserverNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.platform//debugInspectorInfo/\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectableModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.platform/SoftwareKeyboardController/hide/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SoftwareKeyboardControllerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.platform//rememberNestedScrollInteropConnection/\#android\.view\.View/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ComposeInCooperatingViewNestedScrollInteropSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.platform//inspectable/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectableModifierSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/placeWithLayer/androidx\.compose\.ui\.layout\.Placeable\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout//onPlaced/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnPlaced\. b/[0-9]+
 WARN: Missing @param tag for parameter `onSelectAllRequested` of function androidx\.compose\.ui\.platform/TextToolbar/showMenu/\#androidx\.compose\.ui\.geometry\.Rect\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.platform/SoftwareKeyboardController/show/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SoftwareKeyboardControllerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.res//painterResource/\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PainterResourceSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `block` of function androidx\.compose\.ui\.test//runAndroidComposeUiTest/\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.AndroidComposeUiTest\[TypeParam\(bounds=\[androidx\.activity\.ComponentActivity\]\)\],kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `activityClass` of function androidx\.compose\.ui\.test//runAndroidComposeUiTest/\#java\.lang\.Class\[TypeParam\(bounds=\[androidx\.activity\.ComponentActivity\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.AndroidComposeUiTest\[TypeParam\(bounds=\[androidx\.activity\.ComponentActivity\]\)\],kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.compose\.ui\.test//runAndroidComposeUiTest/\#java\.lang\.Class\[TypeParam\(bounds=\[androidx\.activity\.ComponentActivity\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.AndroidComposeUiTest\[TypeParam\(bounds=\[androidx\.activity\.ComponentActivity\]\)\],kotlin\.Unit\]/PointingToDeclaration/
@@ -269,59 +172,23 @@
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.ui\.test//onNodeWithContentDescription/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `testTag` of function androidx\.compose\.ui\.test//onNodeWithTag/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.test//onNodeWithText/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performGesture/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.GestureScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.gestureClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performMouseInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.MouseInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performMouseInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.MouseInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputScrollWhileDown\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputSwipeUp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputClickOffCenter\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputAssertDuringClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test//performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputClickAndDrag\. b/[0-9]+
-WARNING: no common source set for DParameter androidx\.compose\.ui\.test\.junit[0-9]+//createComposeRule/\#kotlin\.coroutines\.CoroutineContext/PointingToCallableParameters\([0-9]+\)/! Falling back to jvmMain sourceSet! This is only defensible if every sourceSet depends onjvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/addStringAnnotation/\#kotlin\.String\#kotlin\.String\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringAddStringAnnotationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString/AnnotatedString/\#kotlin\.String\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.AnnotatedString\.Range\[androidx\.compose\.ui\.text\.SpanStyle\]\]\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.AnnotatedString\.Range\[androidx\.compose\.ui\.text\.ParagraphStyle\]\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringConstructorSample\. b/[0-9]+
 WARN: Multiple sources exist for Paragraph\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/TextMeasurer/measure/\#kotlin\.String\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Constraints\#androidx\.compose\.ui\.unit\.LayoutDirection\#androidx\.compose\.ui\.unit\.Density\#androidx\.compose\.ui\.text\.font\.FontFamily\.Resolver\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.measureTextStringWithConstraints\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/withStyle/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#androidx\.compose\.ui\.text\.SpanStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.AnnotatedString\.Builder,TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderWithStyleSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `matcher` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onAllNodes/\#androidx\.compose\.ui\.test\.SemanticsMatcher\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `matcher` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onNode/\#androidx\.compose\.ui\.test\.SemanticsMatcher\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `condition` of function androidx\.compose\.ui\.test/MainTestClock/advanceTimeUntil/\#kotlin\.Long\#kotlin\.Function[0-9]+\[kotlin\.Boolean\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performMouseInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.MouseInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performMouseInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.MouseInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputScrollWhileDown\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/GestureScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.gestureClick\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onAllNodesWithContentDescription/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/GestureScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.gestureSwipeUp\. b/[0-9]+
 WARN: Missing @param tag for parameter `testTag` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onAllNodesWithTag/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/GestureScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.gestureLShape\. b/[0-9]+
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onAllNodesWithText/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onNodeWithContentDescription/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `testTag` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onNodeWithTag/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.test/SemanticsNodeInteractionsProvider/onNodeWithText/androidx\.compose\.ui\.test\.SemanticsNodeInteractionsProvider\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputSwipeUp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputClickOffCenter\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputAssertDuringClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performTouchInput/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.TouchInjectionScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputClickAndDrag\. b/[0-9]+
 WARN: Missing @param tag for parameter `matcher` of function androidx\.compose\.ui\.test\.junit[0-9]+/AndroidComposeTestRule/onAllNodes/\#androidx\.compose\.ui\.test\.SemanticsMatcher\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `matcher` of function androidx\.compose\.ui\.test\.junit[0-9]+/AndroidComposeTestRule/onNode/\#androidx\.compose\.ui\.test\.SemanticsMatcher\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `variationSettings` of function androidx\.compose\.ui\.text\.font/AndroidFont/AndroidFont/\#androidx\.compose\.ui\.text\.font\.FontLoadingStrategy\#androidx\.compose\.ui\.text\.font\.AndroidFont\.TypefaceLoader\#androidx\.compose\.ui\.text\.font\.FontVariation\.Settings/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontFamily\.Companion/Monospace/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilyMonospaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontFamily\.Companion/SansSerif/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilySansSerifSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontFamily\.Companion/Serif/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilySerifSample\. b/[0-9]+
 WARN: Multiple sources exist for PlatformTextInputPlugin\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.input/PasswordVisualTransformation/filter/\#androidx\.compose\.ui\.text\.AnnotatedString/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.passwordFilter\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.input/VisualTransformation/filter/\#androidx\.compose\.ui\.text\.AnnotatedString/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.passwordFilter\. b/[0-9]+
 WARN: Multiple sources exist for PlatformTextInputAdapter\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.input/PasswordVisualTransformation/filter/\#androidx\.compose\.ui\.text\.AnnotatedString/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.creditCardFilter\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.input/VisualTransformation/filter/\#androidx\.compose\.ui\.text\.AnnotatedString/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.creditCardFilter\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextDecoration\.Companion/LineThrough/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextDecorationLineThroughSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextDecoration\.Companion/combine/\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.style\.TextDecoration\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextDecorationCombinedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextOverflow\.Companion/Clip/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextOverflowClipSample\. b/[0-9]+
 WARN: Multiple sources exist for LineBreak\. Artifact ID metadata will not be displayed
 WARN: Multiple sources exist for TextMotion\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextDecoration/plus/\#androidx\.compose\.ui\.text\.style\.TextDecoration/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextDecorationCombinedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextDecoration\.Companion/Underline/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextDecorationUnderlineSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextOverflow\.Companion/Ellipsis/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextOverflowEllipsisSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextOverflow\.Companion/Visible/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextOverflowVisibleFixedSizeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextOverflow\.Companion/Visible/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextOverflowVisibleMinHeightSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `motionScene` of function androidx\.constraintlayout\.compose//MotionCarousel/\#androidx\.constraintlayout\.compose\.MotionScene\#kotlin\.Int\#kotlin\.Int\#kotlin\.String\#kotlin\.String\#kotlin\.String\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.constraintlayout\.compose\.MotionCarouselScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.glance\.appwidget//AndroidRemoteViews/\#android\.widget\.RemoteViews\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `output` of function androidx\.glance\.appwidget\.proto/LayoutProtoSerializer/writeTo/\#androidx\.glance\.appwidget\.proto\.LayoutProto\.LayoutConfig\#java\.io\.OutputStream/PointingToDeclaration/
@@ -379,99 +246,7 @@
 Did you make a typo\? Are you trying to refer to something not visible to users\? in declaration of UserStyle in file \$OUT_DIR\/androidx\/docs\-public\/build\/unzippedJvmSources\/androidx\/wear\/watchface\/style\/CurrentUserStyleRepository\.kt at line [0-9]+\.
 Did you make a typo\? Are you trying to refer to something not visible to users\? in declaration of UserStyle in file \$OUT_DIR\/androidx\/docs\-tip\-of\-tree\/build\/unzippedJvmSources\/androidx\/wear\/watchface\/style\/CurrentUserStyleRepository\.kt at line [0-9]+\.
 WARN: Missing @param tag for parameter `matchHeightConstraintsFirst` of function androidx\.compose\.ui/Modifier/aspectRatio/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/background/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DrawBackgroundShapedBrush\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicMarqueeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicFocusableMarqueeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicMarqueeWithFadedEdgesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.BlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ImageBlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.BlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ImageBlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.BorderStroke\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithDataClass\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithBrush\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithDynamicData\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/bringIntoViewRequester/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.relocation\.BringIntoViewRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/bringIntoViewResponder/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.relocation\.BringIntoViewResponder/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/clickable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/clickable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/combinedClickable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.String\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/combinedClickable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.String\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/draggable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.DraggableState\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?\#kotlin\.Boolean\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlinx\.coroutines\.CoroutineScope,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlinx\.coroutines\.CoroutineScope,kotlin\.Float,kotlin\.Unit\]\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DraggableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheModifierStateParameterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onFocusChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusTarget/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSampleUsingLowerLevelFocusTarget\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusOrder/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusOrder,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusProperties/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusProperties,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusPropertiesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusRequester/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.focus\.FocusRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusOrder/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.focus\.FocusRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusGroup/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusGroup/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusableFocusGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/focusable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.RenderEffect\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.CompositingStrategy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ChangeOpacity\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.RenderEffect\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.CompositingStrategy/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CompositingStrategyModulateAlpha\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/graphicsLayer/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AnimateFadeIn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/hoverable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HoverableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/indication/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.InteractionSource\#androidx\.compose\.foundation\.Indication\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.IndicationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/inspectable/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectableModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.MatchParentDividerForText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.MatchParentDividerForAspectRatio\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SameWidthBoxes\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SameWidthTextBoxes\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onKeyEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onPreviewKeyEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/layoutId/androidx\.compose\.ui\.Modifier\#kotlin\.Any/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutTagChildrenUsage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/layout/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.MeasureScope,androidx\.compose\.ui\.layout\.Measurable,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ConvenienceLayoutModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/intermediateLayout/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.IntermediateMeasureScope,androidx\.compose\.ui\.layout\.Measurable,androidx\.compose\.ui\.unit\.Constraints,androidx\.compose\.ui\.layout\.MeasureResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.IntermediateLayoutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/magnifier/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.geometry\.Offset\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.geometry\.Offset\]\#kotlin\.Float\#androidx\.compose\.foundation\.MagnifierStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.DpSize,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.MagnifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/nestedScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollDispatcher\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.NestedScrollConnectionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/nestedScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollDispatcher\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.NestedScrollDispatcherSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/absoluteOffset/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsoluteOffsetModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/absoluteOffset/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsoluteOffsetPxModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/offset/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.OffsetModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/offset/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.OffsetPxModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onGloballyPositioned/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnGloballyPositioned\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onPlaced/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.LayoutCoordinates,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnPlaced\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onSizeChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnSizeChangedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/overscroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.OverscrollEffect/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/absolutePadding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsolutePaddingModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SymmetricPaddingModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingAllModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingValuesModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/paint/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.painter\.Painter\#kotlin\.Boolean\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PainterModifierSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `painter` of function androidx\.compose\.ui/Modifier/paint/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.painter\.Painter\#kotlin\.Boolean\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerHoverIcon/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.input\.pointer\.PointerIcon\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PointerIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/progressSemantics/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DeterminateProgressSemanticsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/progressSemantics/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.IndeterminateProgressSemanticsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pullRefreshIndicatorTransform/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.pullrefresh\.PullRefreshState\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshIndicatorTransformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pullRefresh/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.pullrefresh\.PullRefreshState\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pullRefresh/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlin\.Float,kotlin\.Float\]\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CustomPullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onPreRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PreRotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onRotaryScrollEvent/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.rotary\.RotaryScrollEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PreRotaryEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/rotate/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RotateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/scale/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ScaleNonUniformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/scale/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ScaleUniformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/horizontalScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.ScrollState\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HorizontalScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/verticalScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.ScrollState\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.VerticalScrollExample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/scrollable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.ScrollableState\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ScrollableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/scrollable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.ScrollableState\#androidx\.compose\.foundation\.gestures\.Orientation\#androidx\.compose\.foundation\.OverscrollEffect\?\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ScrollableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/selectable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SelectableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/selectable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SelectableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ShadowSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `cookieManager` of function androidx\.webkit/CookieManagerCompat/getCookieInfo/\#android\.webkit\.CookieManager\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `settings` of function androidx\.webkit/WebSettingsCompat/setAlgorithmicDarkeningAllowed/\#android\.webkit\.WebSettings\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `settings` of function androidx\.webkit/WebSettingsCompat/setDisabledActionModeMenuItems/\#android\.webkit\.WebSettings\#int/PointingToDeclaration/
@@ -484,61 +259,6 @@
 WARN: Missing @param tag for parameter `webview` of function androidx\.webkit/WebViewCompat/removeWebMessageListener/\#android\.webkit\.WebView\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `ambientColor` of function androidx\.compose\.ui/Modifier/shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
 WARN: Missing @param tag for parameter `spotColor` of function androidx\.compose\.ui/Modifier/shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/defaultMinSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.DefaultMinSizeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxHeight/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxHeight/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxSize/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxSize/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxWidth/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/fillMaxWidth/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/requiredHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/requiredSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/requiredWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifierWithDpSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/wrapContentHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentVerticallyAlignedModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/wrapContentSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentAlignedModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/wrapContentWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentHorizontallyAlignedModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onInterceptKeyBeforeSoftKeyboard/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onPreInterceptKeyBeforeSoftKeyboard/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.key\.KeyEvent,kotlin\.Boolean\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.keyedPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/pointerInput/androidx\.compose\.ui\.Modifier\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.rememberedUpdatedParameterPointerInputModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/swipeable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.SwipeableState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.collections\.Map\[kotlin\.Float,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),androidx\.compose\.material\.ThresholdConfig\]\#androidx\.compose\.material\.ResistanceConfig\?\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SwipeableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/toggleable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/toggleable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/triStateToggleable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.state\.ToggleableState\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TriStateToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/triStateToggleable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.state\.ToggleableState\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TriStateToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/transformable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.TransformableState\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TransformableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/transformable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.TransformableState\#kotlin\.Function[0-9]+\[kotlin\.Boolean\]\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TransformableSampleInsideScroll\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/imeNestedScroll/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.windowInsetsNestedScrollDemo\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/captionBarPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.captionBarPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/consumeWindowInsets/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.consumedInsetsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/consumeWindowInsets/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.consumedInsetsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/displayCutoutPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.displayCutoutPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/imePadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.imePaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/mandatorySystemGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.mandatorySystemGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/navigationBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.statusBarsAndNavigationBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/onConsumedWindowInsetsChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.WindowInsets,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.withConsumedInsetsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/safeContentPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeContentPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/safeDrawingPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeDrawingPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/safeGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/statusBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.statusBarsAndNavigationBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/systemBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.systemBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/systemGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.systemGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/waterfallPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.waterfallPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/windowInsetsPadding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/windowInsetsBottomHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsBottomHeightSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/windowInsetsEndWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsEndWidthSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/windowInsetsStartWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsStartWidthSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/windowInsetsTopHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsTopHeightSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/zIndex/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ZIndexModifierSample\. b/[0-9]+
 @param copySelectedOptions
 in DClass Builder
 Did you make a typo\? Are you trying to refer to something not visible to users\? in declaration of Builder in file \$OUT_DIR\/androidx\/docs\-public\/build\/unzippedJvmSources\/androidx\/wear\/watchface\/ComplicationSlot\.kt at line [0-9]+\.
@@ -552,108 +272,15 @@
 WARNING: link to @throws type ComposeTimeoutException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name,  e\.g\.`@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root=CustomDocTag\(children=\[P\(children=\[Text\(body=If the condition is not satisfied after , children=\[\], params=\{\}\), DocumentationLink\(dri=androidx\.compose\.ui\.test\.junit[0-9]+/AndroidComposeTestRule/waitUntil/\#kotlin\.Long\#kotlin\.Function[0-9]+\[kotlin\.Boolean\]/PointingToCallableParameters\([0-9]+\)/, children=\[Text\(body=timeoutMillis, children=\[\], params=\{\}\)\], params=\{href=\[timeoutMillis\]\}\), Text\(body=\., children=\[\], params=\{\}\)\], params=\{\}\)\], params=\{\}, name=MARKDOWN_FILE\), name=ComposeTimeoutException, exceptionAddress=null\)\.`
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.text//AnnotatedString/\#kotlin\.String\#androidx\.compose\.ui\.text\.SpanStyle\#androidx\.compose\.ui\.text\.ParagraphStyle\?/PointingToDeclaration/
 WARN: Multiple sources exist for PlatformSpanStyle\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextLayoutResult\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextMeasureInLayoutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle/SpanStyle/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.PlatformSpanStyle\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.SpanStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/addTtsAnnotation/\#androidx\.compose\.ui\.text\.TtsAnnotation\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringAddStringAnnotationSample\. b/[0-9]+
 WARN: Multiple sources exist for PlatformTextStyle\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle/SpanStyle/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.PlatformSpanStyle\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextLayoutResult\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.geometry\.Offset\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextDrawWithCacheSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/addUrlAnnotation/\#androidx\.compose\.ui\.text\.UrlAnnotation\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringAddStringAnnotationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/TextStyle/TextStyle/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.text\.style\.TextAlign\?\#androidx\.compose\.ui\.text\.style\.TextDirection\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.TextIndent\?\#androidx\.compose\.ui\.text\.PlatformTextStyle\?\#androidx\.compose\.ui\.text\.style\.LineHeightStyle\?\#androidx\.compose\.ui\.text\.style\.LineBreak\?\#androidx\.compose\.ui\.text\.style\.Hyphens\?\#androidx\.compose\.ui\.text\.style\.TextMotion\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#androidx\.compose\.ui\.text\.AnnotatedString\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.AnnotatedString\.Range\[androidx\.compose\.ui\.text\.Placeholder\]\]\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextAnnotatedStringSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle/SpanStyle/\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.PlatformSpanStyle\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.SpanStyleBrushSample\. b/[0-9]+
 WARN: Multiple sources exist for PlatformParagraphStyle\. Artifact ID metadata will not be displayed
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.text//AnnotatedString/\#kotlin\.String\#androidx\.compose\.ui\.text\.ParagraphStyle/PointingToDeclaration/
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.text/AnnotatedString\.Builder/append/\#kotlin\.CharSequence\?\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/TextStyle/TextStyle/\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?\#androidx\.compose\.ui\.text\.style\.TextAlign\?\#androidx\.compose\.ui\.text\.style\.TextDirection\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.TextIndent\?\#androidx\.compose\.ui\.text\.PlatformTextStyle\?\#androidx\.compose\.ui\.text\.style\.LineHeightStyle\?\#androidx\.compose\.ui\.text\.style\.LineBreak\?\#androidx\.compose\.ui\.text\.style\.Hyphens\?\#androidx\.compose\.ui\.text\.style\.TextMotion\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextStyleBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/TextMeasurer/measure/\#androidx\.compose\.ui\.text\.AnnotatedString\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.collections\.List\[androidx\.compose\.ui\.text\.AnnotatedString\.Range\[androidx\.compose\.ui\.text\.Placeholder\]\]\#androidx\.compose\.ui\.unit\.Constraints\#androidx\.compose\.ui\.unit\.LayoutDirection\#androidx\.compose\.ui\.unit\.Density\#androidx\.compose\.ui\.text\.font\.FontFamily\.Resolver\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.measureTextAnnotatedString\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#kotlin\.String\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextStyledSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/pushStringAnnotation/\#kotlin\.String\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderPushStringAnnotationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/withStyle/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#androidx\.compose\.ui\.text\.ParagraphStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.AnnotatedString\.Builder,TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderWithStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//buildAnnotatedString/\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.AnnotatedString\.Builder,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderLambdaSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/appendInlineContent/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#kotlin\.String\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.InlineTextContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle/SpanStyle/\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.font\.FontWeight\?\#androidx\.compose\.ui\.text\.font\.FontStyle\?\#androidx\.compose\.ui\.text\.font\.FontSynthesis\?\#androidx\.compose\.ui\.text\.font\.FontFamily\?\#kotlin\.String\?\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.text\.style\.BaselineShift\?\#androidx\.compose\.ui\.text\.style\.TextGeometricTransform\?\#androidx\.compose\.ui\.text\.intl\.LocaleList\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.text\.style\.TextDecoration\?\#androidx\.compose\.ui\.graphics\.Shadow\?\#androidx\.compose\.ui\.text\.PlatformSpanStyle\?\#androidx\.compose\.ui\.graphics\.drawscope\.DrawStyle\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//withStyle/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#androidx\.compose\.ui\.text\.ParagraphStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.AnnotatedString\.Builder,TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderWithStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/pushStyle/\#androidx\.compose\.ui\.text\.ParagraphStyle/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderPushParagraphStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//withStyle/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#androidx\.compose\.ui\.text\.SpanStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.AnnotatedString\.Builder,TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderWithStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/pushStyle/\#androidx\.compose\.ui\.text\.SpanStyle/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderPushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/pushTtsAnnotation/\#androidx\.compose\.ui\.text\.TtsAnnotation/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderPushStringAnnotationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder/pushUrlAnnotation/\#androidx\.compose\.ui\.text\.UrlAnnotation/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderPushStringAnnotationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontFamily\.Companion/Cursive/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilyCursiveSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `text` of function androidx\.compose\.ui\.text/AnnotatedString\.Builder/append/\#androidx\.compose\.ui\.text\.AnnotatedString\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.text//drawText/androidx\.compose\.ui\.graphics\.drawscope\.DrawScope\#androidx\.compose\.ui\.text\.TextMeasurer\#kotlin\.String\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Boolean\#kotlin\.Int\#androidx\.compose\.ui\.geometry\.Size\#androidx\.compose\.ui\.graphics\.BlendMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.DrawTextSample\. b/[0-9]+
 WARNING: link to @throws type Renderer\.GlesException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name,  e\.g\.`@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root=CustomDocTag\(children=\[P\(children=\[Text\(body=If any GL calls fail during initialization\., children=\[\], params=\{\}\)\], params=\{\}\)\], params=\{\}, name=MARKDOWN_FILE\), name=Renderer\.GlesException, exceptionAddress=null\)\.`
 WARNING: link to @throws type ServiceStartFailureException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name,  e\.g\.`@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root=CustomDocTag\(children=\[P\(children=\[Text\(body=if the watchface dies during startup\., children=\[\], params=\{\}\)\], params=\{\}\)\], params=\{\}, name=MARKDOWN_FILE\), name=ServiceStartFailureException, exceptionAddress=null\)\.`
 WARN: Sources for .+ is empty
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyItemScope/animateItemPlacement/androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ItemPlacementAnimationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy//LazyColumn/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.LazyListState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.ui\.Alignment\.Horizontal\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.LazyListScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListScope/stickyHeader/\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.LazyItemScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.StickyHeaderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListState/firstVisibleItemIndex/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingListScrollPositionForSideEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy//LazyRow/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.LazyListState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.ui\.Alignment\.Vertical\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.LazyListScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListState/firstVisibleItemIndex/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingListScrollPositionInCompositionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy/LazyListState/layoutInfo/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingListLayoutInfoForSideEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/IntrinsicMeasureScope/isLookingAhead/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.animateContentSizeAfterLookaheadPass\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//HorizontalPager/\#androidx\.compose\.foundation\.pager\.PagerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.pager\.PageSize\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.Alignment\.Vertical\#androidx\.compose\.foundation\.gestures\.snapping\.SnapFlingBehavior\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Any\]\?\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.pager\.PagerScope,kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HorizontalPagerWithScrollableContent\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation//BringIntoViewRequester/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewRequester/bringIntoView/\#androidx\.compose\.ui\.geometry\.Rect\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation//bringIntoViewRequester/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.relocation\.BringIntoViewRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation//BringIntoViewRequester/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringPartOfComposableIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewRequester/bringIntoView/\#androidx\.compose\.ui\.geometry\.Rect\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringPartOfComposableIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation//bringIntoViewResponder/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.relocation\.BringIntoViewResponder/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//selectable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SelectableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//selectable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SelectableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//toggleable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//toggleable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//triStateToggleable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.state\.ToggleableState\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TriStateToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.selection//triStateToggleable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.state\.ToggleableState\#kotlin\.Boolean\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TriStateToggleableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.PlaceholderBasicTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TextFieldWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicTextFieldWithStringSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.PlaceholderBasicTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TextFieldWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//BasicTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Brush\#kotlin\.Function[0-9]+\[kotlin\.Function[0-9]+\[kotlin\.Unit\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CreditCardSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//ClickableText/\#androidx\.compose\.ui\.text\.AnnotatedString\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//ClickableText/\#androidx\.compose\.ui\.text\.AnnotatedString\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LongClickableText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/MaterialTheme/typography/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ThemeTextStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/ButtonDefaults/IconSpacing/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ButtonWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/TextFieldDefaults/TextFieldDecorationBox/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.interaction\.InteractionSource\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.TextFieldColors\#androidx\.compose\.foundation\.layout\.PaddingValues/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CustomTextFieldBasedOnDecorationBox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//BackdropScaffold/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.BackdropScaffoldState\#kotlin\.Boolean\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.BackdropScaffoldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//BadgedBox/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.BottomNavigationItemWithBadge\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//BottomAppBar/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleBottomAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//BottomDrawer/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.BottomDrawerState\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.BottomDrawerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//BottomNavigation/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.BottomNavigationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Checkbox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.CheckboxColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CheckboxSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ClickableCardSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Chip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//IconToggleButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.IconToggleButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DatePicker/\#androidx\.compose\.material[0-9]+\.DatePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DatePickerFormatter\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.DatePickerColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DatePickerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DatePicker/\#androidx\.compose\.material[0-9]+\.DatePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DatePickerFormatter\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.DatePickerColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DateInputSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DatePicker/\#androidx\.compose\.material[0-9]+\.DatePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DatePickerFormatter\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.DatePickerColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DatePickerWithDateSelectableDatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DatePickerDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.material[0-9]+\.DatePickerColors\#androidx\.compose\.ui\.window\.DialogProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DatePickerDialogSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DateRangePicker/\#androidx\.compose\.material[0-9]+\.DateRangePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DatePickerFormatter\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.DatePickerColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DateRangePickerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DismissibleNavigationDrawer/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DrawerState\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DismissibleNavigationDrawerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DockedSearchBar/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SearchBarColors\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.DockedSearchBarSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Any\?\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
 WARN: Multiple sources exist for ComposableLambda\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ViewInComposeNestedScrollInteropSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AndroidViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ViewInComposeNestedScrollInteropSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AndroidViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ReusableAndroidViewInLazyColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.viewinterop//AndroidView/\#kotlin\.Function[0-9]+\[android\.content\.Context,TypeParam\(bounds=\[android\.view\.View\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[android\.view\.View\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AndroidViewWithReleaseSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.window//Dialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.window\.DialogProperties\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DialogSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.window//Popup/\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PopupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.window//Popup/\#androidx\.compose\.ui\.window\.PopupPositionProvider\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PopupSample\. b/[0-9]+
 WARNING: link to @throws type UnsupportedDeviceOperationException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name,  e\.g\.`@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root=CustomDocTag\(children=\[P\(children=\[Text\(body=if used on a real device\., children=\[\], params=\{\}\)\], params=\{\}\)\], params=\{\}, name=MARKDOWN_FILE\), name=UnsupportedDeviceOperationException, exceptionAddress=null\)\.`
 WARNING: link to @throws type DeviceControllerOperationException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name,  e\.g\.`@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root=CustomDocTag\(children=\[P\(children=\[Text\(body=when called on a non\-foldable Emulator\., children=\[\], params=\{\}\)\], params=\{\}\)\], params=\{\}, name=MARKDOWN_FILE\), name=DeviceControllerOperationException, exceptionAddress=null\)\.`
 WARN\: Multiple sources exist for IOException\. Artifact ID metadata will not be displayed
@@ -693,70 +320,23 @@
 WARN: Missing @param tag for parameter `toJSON` of function androidx\.constraintlayout\.core\.state/CoreMotionScene/setTransitionContent/\#java\.lang\.String\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `currentProgress` of function androidx\.constraintlayout\.core\.state/Transition/dragToProgress/\#float\#int\#int\#float\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `flags` of function androidx\.constraintlayout\.core\.widgets/ConstraintWidgetContainer/updateChildrenFromSolver/\#androidx\.constraintlayout\.core\.LinearSystem\#boolean\[\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation/EnterTransition/togetherWith/androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/EnterTransition/plus/\#androidx\.compose\.animation\.EnterTransition/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FullyLoadedTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/AnimatedVisibilityScope/animateEnterExit/androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimateEnterExitPartialContent\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/AnimatedContentTransitionScope/slideIntoContainer/\#androidx\.compose\.animation\.AnimatedContentTransitionScope\.SlideDirection\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideIntoContainerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//Animatable/\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatableColor\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/ExitTransition\.Companion/None/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AVScopeAnimateEnterExit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/ExitTransition/plus/\#androidx\.compose\.animation\.ExitTransition/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FullyLoadedTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedContent/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentTransitionScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.ContentTransform\]\#androidx\.compose\.ui\.Alignment\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.TransitionExtensionAnimatedContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedContent/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentTransitionScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.ContentTransform\]\#androidx\.compose\.ui\.Alignment\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SimpleAnimatedContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/AnimatedContentTransitionScope/slideOutOfContainer/\#androidx\.compose\.animation\.AnimatedContentTransitionScope\.SlideDirection\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideIntoContainerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/AnimatedContentTransitionScope/using/androidx\.compose\.animation\.ContentTransform\#androidx\.compose\.animation\.SizeTransform\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedContent/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentTransitionScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.ContentTransform\]\#androidx\.compose\.ui\.Alignment\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimateIncrementDecrementSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AddAnimatedVisibilityToGenericTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedVisibilityLazyColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AVColumnScopeWithMutableTransitionState\. b/[0-9]+
 WARN: Missing @param tag for parameter `widgets` of function androidx\.constraintlayout\.core\.widgets/Chain/applyChainConstraints/\#androidx\.constraintlayout\.core\.widgets\.ConstraintWidgetContainer\#androidx\.constraintlayout\.core\.LinearSystem\#java\.util\.ArrayList<androidx\.constraintlayout\.core\.widgets\.ConstraintWidget>\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `len` of function androidx\.constraintlayout\.motion\.widget/DesignTool/getAnimationPath/\#java\.lang\.Object\#float\[\]\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `type` of function androidx\.constraintlayout\.motion\.widget/DesignTool/getKeyFrameInfo/\#java\.lang\.Object\#int\#int\[\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `type` of function androidx\.constraintlayout\.motion\.widget/MotionController/getKeyFrameInfo/\#int\#int\[\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//updateTransition/\#androidx\.compose\.animation\.core\.MutableTransitionState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.DoubleTapToLikeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.graphics\.res//animatedVectorResource/androidx\.compose\.animation\.graphics\.vector\.AnimatedImageVector\.Companion\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.graphics\.samples\.AnimatedVectorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.graphics\.res//rememberAnimatedVectorPainter/\#androidx\.compose\.animation\.graphics\.vector\.AnimatedImageVector\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.graphics\.samples\.AnimatedVectorSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `margin` of function androidx\.constraintlayout\.widget/ConstraintSet/createBarrier/\#int\#int\#int\#int\.\.\./PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//draggable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.DraggableState\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?\#kotlin\.Boolean\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlinx\.coroutines\.CoroutineScope,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlinx\.coroutines\.CoroutineScope,kotlin\.Float,kotlin\.Unit\]\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DraggableSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `viewId` of function androidx\.constraintlayout\.widget/ConstraintSet/setApplyElevation/\#int\#boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//horizontalDrag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HorizontalDragSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//scrollable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.ScrollableState\#androidx\.compose\.foundation\.gestures\.Orientation\#androidx\.compose\.foundation\.OverscrollEffect\?\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ScrollableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//scrollable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.ScrollableState\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ScrollableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//transformable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.TransformableState\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TransformableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//transformable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.gestures\.TransformableState\#kotlin\.Function[0-9]+\[kotlin\.Boolean\]\#kotlin\.Boolean\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.TransformableSampleInsideScroll\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//verticalDrag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.VerticalDragSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.interaction/InteractionSource/interactions/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.InteractionSourceFlowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//Box/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleBox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/align/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Horizontal/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAlignInColumn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/RowScope/align/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Vertical/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAlignInRow\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/RowScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedFloatingActionButton\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/WindowInsets/asPaddingValues/androidx\.compose\.foundation\.layout\.WindowInsets\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.paddingValuesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ColumnAnimatedVisibilitySample\. b/[0-9]+
 WARN: Missing @param tag for parameter `activity` of function androidx\.core\.app/ActivityCompat/requestDragAndDropPermissions/\#android\.app\.Activity\#android\.view\.DragEvent/PointingToDeclaration/
 WARN: Missing @param tag for parameter `activity` of function androidx\.core\.app/ActivityCompat/requireViewById/\#android\.app\.Activity\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `activity` of function androidx\.core\.app/ActivityCompat/setEnterSharedElementCallback/\#android\.app\.Activity\#androidx\.core\.app\.SharedElementCallback/PointingToDeclaration/
 WARN: Missing @param tag for parameter `activity` of function androidx\.core\.app/ActivityCompat/setExitSharedElementCallback/\#android\.app\.Activity\#androidx\.core\.app\.SharedElementCallback/PointingToDeclaration/
 WARN: Missing @param tag for parameter `activity` of function androidx\.core\.app/ActivityCompat/setLocusContext/\#android\.app\.Activity\#androidx\.core\.content\.LocusIdCompat\#android\.os\.Bundle/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid/LazyGridState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid//LazyHorizontalGrid/\#androidx\.compose\.foundation\.lazy\.grid\.GridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.grid\.LazyGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.grid\.LazyGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyHorizontalGridSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid/LazyGridState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid/LazyGridState/firstVisibleItemIndex/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingGridScrollPositionForSideEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid/LazyGridState/firstVisibleItemIndex/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingGridScrollPositionInCompositionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid//LazyHorizontalGrid/\#androidx\.compose\.foundation\.lazy\.grid\.GridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.grid\.LazyGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.grid\.LazyGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyHorizontalGridSpanSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid//LazyVerticalGrid/\#androidx\.compose\.foundation\.lazy\.grid\.GridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.grid\.LazyGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.grid\.LazyGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyVerticalGridSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid/LazyGridState/layoutInfo/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.UsingGridLayoutInfoForSideEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.grid//LazyVerticalGrid/\#androidx\.compose\.foundation\.lazy\.grid\.GridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.grid\.LazyGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.grid\.LazyGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyVerticalGridSpanSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `service` of function androidx\.core\.app/ServiceCompat/stopForeground/\#android\.app\.Service\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.core\.content//withStyledAttributes/android\.content\.Context\#android\.util\.AttributeSet\?\#kotlin\.IntArray\#kotlin\.Int\#kotlin\.Int\#kotlin\.Function[0-9]+\[android\.content\.res\.TypedArray,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content/ContextCompat/checkSelfPermission/\#android\.content\.Context\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content/ContextCompat/getColor/\#android\.content\.Context\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content/ContextCompat/getColorStateList/\#android\.content\.Context\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content/ContextCompat/getDrawable/\#android\.content\.Context\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid/LazyStaggeredGridState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid//LazyHorizontalStaggeredGrid/\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.StaggeredGridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyHorizontalStaggeredGridSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid/LazyStaggeredGridState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid//LazyHorizontalStaggeredGrid/\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.StaggeredGridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyHorizontalStaggeredGridSpanSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid//LazyVerticalStaggeredGrid/\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.StaggeredGridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyVerticalStaggeredGridSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.lazy\.staggeredgrid//LazyVerticalStaggeredGrid/\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.StaggeredGridCells\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridState\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Boolean\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.gestures\.FlingBehavior\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.staggeredgrid\.LazyStaggeredGridScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LazyVerticalStaggeredGridSpanSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `block` of function androidx\.core\.content/ContextKt/withStyledAttributes/android\.content\.Context\#android\.util\.AttributeSet\?\#kotlin\.IntArray\#kotlin\.Int\#kotlin\.Int\#kotlin\.Function[0-9]+\[android\.content\.res\.TypedArray,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `resourceId` of function androidx\.core\.content/ContextKt/withStyledAttributes/android\.content\.Context\#kotlin\.Int\#kotlin\.IntArray\#kotlin\.Function[0-9]+\[android\.content\.res\.TypedArray,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.core\.content/ContextKt/withStyledAttributes/android\.content\.Context\#kotlin\.Int\#kotlin\.IntArray\#kotlin\.Function[0-9]+\[android\.content\.res\.TypedArray,kotlin\.Unit\]/PointingToDeclaration/
@@ -766,25 +346,11 @@
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content\.pm/ShortcutManagerCompat/createShortcutResultIntent/\#android\.content\.Context\#androidx\.core\.content\.pm\.ShortcutInfoCompat/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content\.pm/ShortcutManagerCompat/getShortcuts/\#android\.content\.Context\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.content\.pm/ShortcutManagerCompat/requestPinShortcut/\#android\.content\.Context\#androidx\.core\.content\.pm\.ShortcutInfoCompat\#android\.content\.IntentSender/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/animateScrollToPage/\#kotlin\.Int\#kotlin\.Float\#androidx\.compose\.animation\.core\.AnimationSpec\[kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AnimateScrollPageSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//HorizontalPager/\#androidx\.compose\.foundation\.pager\.PagerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.pager\.PageSize\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.Alignment\.Vertical\#androidx\.compose\.foundation\.gestures\.snapping\.SnapFlingBehavior\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Any\]\?\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.pager\.PagerScope,kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SimpleHorizontalPagerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/currentPage/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ObservingStateChangesInPagerStateSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `res` of function androidx\.core\.content\.res/ResourcesCompat/getColor/\#android\.content\.res\.Resources\#int\#android\.content\.res\.Resources\.Theme/PointingToDeclaration/
 WARN: Missing @param tag for parameter `res` of function androidx\.core\.content\.res/ResourcesCompat/getColorStateList/\#android\.content\.res\.Resources\#int\#android\.content\.res\.Resources\.Theme/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/scrollToPage/\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ScrollToPageSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `res` of function androidx\.core\.content\.res/ResourcesCompat/getDrawable/\#android\.content\.res\.Resources\#int\#android\.content\.res\.Resources\.Theme/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/currentPageOffsetFraction/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ObservingStateChangesInPagerStateSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `res` of function androidx\.core\.content\.res/ResourcesCompat/getDrawableForDensity/\#android\.content\.res\.Resources\#int\#int\#android\.content\.res\.Resources\.Theme/PointingToDeclaration/
 WARN: Missing @param tag for parameter `res` of function androidx\.core\.content\.res/ResourcesCompat/getFloat/\#android\.content\.res\.Resources\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/settledPage/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ObservingStateChangesInPagerStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PagerState/targetPage/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ObservingStateChangesInPagerStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//HorizontalPager/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.pager\.PagerState\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.pager\.PageSize\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.Alignment\.Vertical\#androidx\.compose\.foundation\.gestures\.snapping\.SnapFlingBehavior\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Any\]\?\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.pager\.PagerScope,kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SimpleHorizontalPagerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//VerticalPager/\#androidx\.compose\.foundation\.pager\.PagerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.pager\.PageSize\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.Alignment\.Horizontal\#androidx\.compose\.foundation\.gestures\.snapping\.SnapFlingBehavior\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Any\]\?\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.pager\.PagerScope,kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SimpleVerticalPagerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//VerticalPager/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.pager\.PagerState\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.pager\.PageSize\#kotlin\.Int\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.Alignment\.Horizontal\#androidx\.compose\.foundation\.gestures\.snapping\.SnapFlingBehavior\#kotlin\.Boolean\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Any\]\?\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollConnection\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.pager\.PagerScope,kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SimpleVerticalPagerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//rememberPagerState/\#kotlin\.Int\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.PagerWithStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager//rememberPagerState/\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.PagerWithStateSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `body` of function androidx\.core\.database\.sqlite//transaction/android\.database\.sqlite\.SQLiteDatabase\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[android\.database\.sqlite\.SQLiteDatabase,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `body` of function androidx\.core\.database\.sqlite/SQLiteDatabaseKt/transaction/android\.database\.sqlite\.SQLiteDatabase\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[android\.database\.sqlite\.SQLiteDatabase,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.core\.graphics/TypefaceCompat/create/\#android\.content\.Context\#android\.graphics\.Typeface\#int\#boolean/PointingToDeclaration/
@@ -796,7 +362,6 @@
 WARN: Missing @param tag for parameter `right` of function androidx\.core\.graphics\.drawable/DrawableCompat/setHotspotBounds/\#android\.graphics\.drawable\.Drawable\#int\#int\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `bottom` of function androidx\.core\.graphics\.drawable/DrawableCompat/setHotspotBounds/\#android\.graphics\.drawable\.Drawable\#int\#int\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `drawable` of function androidx\.core\.graphics\.drawable/DrawableCompat/setLayoutDirection/\#android\.graphics\.drawable\.Drawable\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//appendInlineContent/androidx\.compose\.ui\.text\.AnnotatedString\.Builder\#kotlin\.String\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.InlineTextContentSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `uptimeMillis` of function androidx\.core\.os//postAtTime/android\.os\.Handler\#kotlin\.Long\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `action` of function androidx\.core\.os//postAtTime/android\.os\.Handler\#kotlin\.Long\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `callback` of function androidx\.core\.os/HandlerCompat/createAsync/\#android\.os\.Looper\#android\.os\.Handler\.Callback/PointingToDeclaration/
@@ -804,20 +369,10 @@
 WARN: Missing @param tag for parameter `action` of function androidx\.core\.os/HandlerKt/postAtTime/android\.os\.Handler\#kotlin\.Long\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `handler` of function androidx\.core\.os/HandlerCompat/postDelayed/\#android\.os\.Handler\#java\.lang\.Runnable\#java\.lang\.Object\#long/PointingToDeclaration/
 WARN: Missing @param tag for parameter `message` of function androidx\.core\.os/MessageCompat/setAsynchronous/\#android\.os\.Message\#boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//ClickableText/\#androidx\.compose\.ui\.text\.AnnotatedString\#kotlin\.Function[0-9]+\[kotlin\.Int\?,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text//ClickableText/\#androidx\.compose\.ui\.text\.AnnotatedString\#kotlin\.Function[0-9]+\[kotlin\.Int\?,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.style\.TextOverflow\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.TextLayoutResult,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.LongClickableText\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.core\.provider/DocumentsContractCompat/createDocument/\#android\.content\.ContentResolver\#android\.net\.Uri\#java\.lang\.String\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.core\.provider/DocumentsContractCompat/removeDocument/\#android\.content\.ContentResolver\#android\.net\.Uri\#android\.net\.Uri/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text\.selection//DisableSelection/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DisableSelectionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text\.selection//SelectionContainer/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SelectionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/ButtonDefaults/IconSize/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ButtonWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//LocalAbsoluteElevation/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.AbsoluteElevationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//swipeable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.SwipeableState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.collections\.Map\[kotlin\.Float,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.foundation\.gestures\.Orientation\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),androidx\.compose\.material\.ThresholdConfig\]\#androidx\.compose\.material\.ResistanceConfig\?\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SwipeableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/SnackbarHostState/showSnackbar/\#kotlin\.String\#kotlin\.String\?\#androidx\.compose\.material\.SnackbarDuration/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithCoroutinesSnackbar\. b/[0-9]+
 WARN: Missing @param tag for parameter `transformFilter` of function androidx\.core\.text\.util/LinkifyCompat/addLinks/\#android\.widget\.TextView\#java\.util\.regex\.Pattern\#java\.lang\.String\#android\.text\.util\.Linkify\.MatchFilter\#android\.text\.util\.Linkify\.TransformFilter/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//BottomSheetScaffold/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.BottomSheetScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.BottomSheetScaffoldSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `listener` of function androidx\.core\.view/DragStartHelper/DragStartHelper/\#android\.view\.View\#androidx\.core\.view\.DragStartHelper\.OnDragStartListener/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//LinearProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.LinearProgressIndicatorSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `payload` of function androidx\.core\.view/ContentInfoCompat/partition/\#android\.view\.ContentInfo\#java\.util\.function\.Predicate<android\.content\.ClipData\.Item>/PointingToDeclaration/
 WARN: Missing @param tag for parameter `lp` of function androidx\.core\.view/MarginLayoutParamsCompat/setLayoutDirection/\#android\.view\.ViewGroup\.MarginLayoutParams\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `item` of function androidx\.core\.view/MenuItemCompat/setAlphabeticShortcut/\#android\.view\.MenuItem\#char\#int/PointingToDeclaration/
@@ -829,7 +384,6 @@
 WARN: Missing @param tag for parameter `type` of function androidx\.core\.view/NestedScrollingChildHelper/startNestedScroll/\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `event` of function androidx\.core\.view/MotionEventCompat/getAxisValue/\#android\.view\.MotionEvent\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `event` of function androidx\.core\.view/MotionEventCompat/getAxisValue/\#android\.view\.MotionEvent\#int\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ListItem/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.OneLineListItems\. b/[0-9]+
 WARN: Missing @param tag for parameter `event` of function androidx\.core\.view/MotionEventCompat/isFromSource/\#android\.view\.MotionEvent\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `scaleGestureDetector` of function androidx\.core\.view/ScaleGestureDetectorCompat/setQuickScaleEnabled/\#java\.lang\.Object\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `scaleGestureDetector` of function androidx\.core\.view/ScaleGestureDetectorCompat/setQuickScaleEnabled/\#android\.view\.ScaleGestureDetector\#boolean/PointingToDeclaration/
@@ -838,7 +392,6 @@
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedPreFling/\#android\.view\.ViewParent\#android\.view\.View\#float\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedPreScroll/\#android\.view\.ViewParent\#android\.view\.View\#int\#int\#int\[\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedPreScroll/\#android\.view\.ViewParent\#android\.view\.View\#int\#int\#int\[\]\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ListItem/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TwoLineListItems\. b/[0-9]+
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedScroll/\#android\.view\.ViewParent\#android\.view\.View\#int\#int\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedScroll/\#android\.view\.ViewParent\#android\.view\.View\#int\#int\#int\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `parent` of function androidx\.core\.view/ViewParentCompat/onNestedScroll/\#android\.view\.ViewParent\#android\.view\.View\#int\#int\#int\#int\#int\#int\[\]/PointingToDeclaration/
@@ -856,38 +409,31 @@
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/computeSystemWindowInsets/\#android\.view\.View\#androidx\.core\.view\.WindowInsetsCompat\#android\.graphics\.Rect/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchApplyWindowInsets/\#android\.view\.View\#androidx\.core\.view\.WindowInsetsCompat/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedFling/\#android\.view\.View\#float\#float\#boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ListItem/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ThreeLineListItems\. b/[0-9]+
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedPreFling/\#android\.view\.View\#float\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedPreScroll/\#android\.view\.View\#int\#int\#int\[\]\#int\[\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedPreScroll/\#android\.view\.View\#int\#int\#int\[\]\#int\[\]\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedScroll/\#android\.view\.View\#int\#int\#int\#int\#int\[\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedScroll/\#android\.view\.View\#int\#int\#int\#int\#int\[\]\#int\#int\[\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ListItem/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ClickableListItems\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//MaterialTheme/\#androidx\.compose\.material\.Colors\#androidx\.compose\.material\.Typography\#androidx\.compose\.material\.Shapes\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.MaterialThemeSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/dispatchNestedScroll/\#android\.view\.View\#int\#int\#int\#int\#int\[\]\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/hasNestedScrollingParent/\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/keyboardNavigationClusterSearch/\#android\.view\.View\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/offsetLeftAndRight/\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/offsetTopAndBottom/\#android\.view\.View\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ModalDrawer/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.DrawerState\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ModalDrawerSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/performAccessibilityAction/\#android\.view\.View\#int\#android\.os\.Bundle/PointingToDeclaration/
 WARN: Missing @param tag for parameter `v` of function androidx\.core\.view/ViewCompat/removeOnUnhandledKeyEventListener/\#android\.view\.View\#androidx\.core\.view\.ViewCompat\.OnUnhandledKeyEventListenerCompat/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/requireViewById/\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `childMeasuredState` of function androidx\.core\.view/ViewCompat/resolveSizeAndState/\#int\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/saveAttributeDataForStyleable/\#android\.view\.View\#android\.content\.Context\#int\[\]\#android\.util\.AttributeSet\#android\.content\.res\.TypedArray\#int\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//NavigationRail/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.NavigationRailSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `v` of function androidx\.core\.view/ViewCompat/setAccessibilityDelegate/\#android\.view\.View\#androidx\.core\.view\.AccessibilityDelegateCompat/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setActivated/\#android\.view\.View\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setAlpha/\#android\.view\.View\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `v` of function androidx\.core\.view/ViewCompat/setAutofillHints/\#android\.view\.View\#java\.lang\.String\.\.\./PointingToDeclaration/
 WARN: Missing @param tag for parameter `viewGroup` of function androidx\.core\.view/ViewCompat/setChildrenDrawingOrderEnabled/\#android\.view\.ViewGroup\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setFocusedByDefault/\#android\.view\.View\#boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//OutlinedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.OutlinedButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `v` of function androidx\.core\.view/ViewCompat/setImportantForAutofill/\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setKeyboardNavigationCluster/\#android\.view\.View\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setNestedScrollingEnabled/\#android\.view\.View\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setNextClusterForwardId/\#android\.view\.View\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//OutlinedTextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.OutlinedTextFieldSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setPivotX/\#android\.view\.View\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setPivotY/\#android\.view\.View\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setPointerIcon/\#android\.view\.View\#androidx\.core\.view\.PointerIconCompat/PointingToDeclaration/
@@ -905,7 +451,6 @@
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setTooltipText/\#android\.view\.View\#java\.lang\.CharSequence/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setTranslationX/\#android\.view\.View\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setTranslationY/\#android\.view\.View\#float/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//OutlinedTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleOutlinedTextFieldSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setWindowInsetsAnimationCallback/\#android\.view\.View\#androidx\.core\.view\.WindowInsetsAnimationCompat\.Callback/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setX/\#android\.view\.View\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/setY/\#android\.view\.View\#float/PointingToDeclaration/
@@ -913,22 +458,6 @@
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/startNestedScroll/\#android\.view\.View\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/startNestedScroll/\#android\.view\.View\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `view` of function androidx\.core\.view/ViewCompat/stopNestedScroll/\#android\.view\.View\#int/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//RadioButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.RadioButtonColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.RadioButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//RadioButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.RadioButtonColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.RadioGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.RangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.StepRangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Scaffold/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.ScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleScaffoldWithTopBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Scaffold/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.ScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithBottomBarAndCutout\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Scaffold/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.ScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.StepsSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Snackbar/\#androidx\.compose\.material\.SnackbarData\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Snackbar/\#androidx\.compose\.material\.SnackbarData\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Snackbar/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Snackbar/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//SnackbarHost/\#androidx\.compose\.material\.SnackbarHostState\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarData,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//SnackbarHost/\#androidx\.compose\.material\.SnackbarHostState\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarData,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Surface/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SurfaceSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `manager` of function androidx\.core\.view\.accessibility/AccessibilityManagerCompat/addTouchExplorationStateChangeListener/\#android\.view\.accessibility\.AccessibilityManager\#androidx\.core\.view\.accessibility\.AccessibilityManagerCompat\.TouchExplorationStateChangeListener/PointingToDeclaration/
 WARN: Missing @param tag for parameter `manager` of function androidx\.core\.view\.accessibility/AccessibilityManagerCompat/removeTouchExplorationStateChangeListener/\#android\.view\.accessibility\.AccessibilityManager\#androidx\.core\.view\.accessibility\.AccessibilityManagerCompat\.TouchExplorationStateChangeListener/PointingToDeclaration/
 WARN: Missing @param tag for parameter `event` of function androidx\.core\.view\.accessibility/AccessibilityEventCompat/appendRecord/\#android\.view\.accessibility\.AccessibilityEvent\#androidx\.core\.view\.accessibility\.AccessibilityRecordCompat/PointingToDeclaration/
@@ -968,9 +497,7 @@
 WARN: Missing @param tag for parameter `horizontalGravity` of function androidx\.core\.widget/RemoteViewsCompat/setRelativeLayoutHorizontalGravity/android\.widget\.RemoteViews\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `verticalGravity` of function androidx\.core\.widget/RemoteViewsCompat/setRelativeLayoutVerticalGravity/android\.widget\.RemoteViews\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `night` of function androidx\.core\.widget/RemoteViewsCompat/setSwitchThumbIcon/android\.widget\.RemoteViews\#kotlin\.Int\#android\.graphics\.drawable\.Icon\?\#android\.graphics\.drawable\.Icon\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyIndicatorContainerTabs\. b/[0-9]+
 WARN: Missing @param tag for parameter `night` of function androidx\.core\.widget/RemoteViewsCompat/setSwitchTrackIcon/android\.widget\.RemoteViews\#kotlin\.Int\#android\.graphics\.drawable\.Icon\?\#android\.graphics\.drawable\.Icon\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//TextButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `c` of function androidx\.cursoradapter\.widget/ResourceCursorAdapter/ResourceCursorAdapter/\#android\.content\.Context\#int\#android\.database\.Cursor/PointingToDeclaration/
 WARN: Missing @param tag for parameter `listener` of function androidx\.customview\.poolingcontainer/PoolingContainer/addPoolingContainerListener/android\.view\.View\#androidx\.customview\.poolingcontainer\.PoolingContainerListener/PointingToDeclaration/
 WARN: Missing @param tag for parameter `listener` of function androidx\.customview\.poolingcontainer//addPoolingContainerListener/android\.view\.View\#androidx\.customview\.poolingcontainer\.PoolingContainerListener/PointingToDeclaration/
@@ -987,38 +514,11 @@
 WARN: Missing @param tag for parameter `context` of function androidx\.documentfile\.provider/DocumentFile/fromTreeUri/\#android\.content\.Context\#android\.net\.Uri/PointingToDeclaration/
 WARNING\: link to \@throws type kotlin\.IllegalArgumentException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function\, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name\,  e\.g\.\`\@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root\=CustomDocTag\(children\=\[P\(children\=\[Text\(body\=if this enum type has no constant with the specified name\, children\=\[\]\, params\=\{\}\)\]\, params\=\{\}\)\]\, params\=\{\}\, name\=MARKDOWN_FILE\)\, name\=kotlin\.IllegalArgumentException\, exceptionAddress\=null\)\.\`
 WARN: Failed to resolve `@see <a href="https://developer\.android\.com/guide/topics/ui/drag\-drop">Drag and drop</a>`!
-WARNING: no common sourceSet for androidx\.compose\.material\.pullrefresh//pullRefresh/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.pullrefresh\.PullRefreshState\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.pullrefresh//PullRefreshIndicator/\#kotlin\.Boolean\#androidx\.compose\.material\.pullrefresh\.PullRefreshState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.pullrefresh//rememberPullRefreshState/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.pullrefresh//pullRefresh/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float\]\#kotlin\.coroutines\.SuspendFunction[0-9]+\[kotlin\.Float,kotlin\.Float\]\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CustomPullRefreshSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.pullrefresh//pullRefreshIndicatorTransform/androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.pullrefresh\.PullRefreshState\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PullRefreshIndicatorTransformSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `useEmojiAsDefaultStyle` of function androidx\.emoji\.text/EmojiCompat\.Config/setUseEmojiAsDefaultStyle/\#boolean\#java\.util\.List<java\.lang\.Integer>/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.foundation\.ScrollState\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.MenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.foundation\.ScrollState\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.MenuWithScrollStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//DropdownMenuItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.MenuItemColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.MenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedAssistChip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ChipColors\#androidx\.compose\.material[0-9]+\.ChipElevation\?\#androidx\.compose\.material[0-9]+\.ChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ElevatedAssistChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ElevatedButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `useEmojiAsDefaultStyle` of function androidx\.emoji[0-9]+\.text/EmojiCompat\.Config/setUseEmojiAsDefaultStyle/\#boolean\#java\.util\.List<java\.lang\.Integer>/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+\.windowsizeclass//calculateWindowSizeClass/\#android\.app\.Activity/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.windowsizeclass\.samples\.AndroidWindowSizeClassSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/CompositionLocal/current/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.consumeCompositionLocal\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/MutableState/setValue/androidx\.compose\.runtime\.MutableState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Any\?\#kotlin\.reflect\.KProperty\[\*\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DelegatedStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/ProduceStateScope/awaitDispose/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/SnapshotMutationPolicy/merge/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#TypeParam\(bounds=\[kotlin\.Any\?\]\)/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.counterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/State/getValue/androidx\.compose\.runtime\.State\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Any\?\#kotlin\.reflect\.KProperty\[\*\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DelegatedReadOnlyStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.SkippableUpdater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//collectAsState/kotlinx\.coroutines\.flow\.Flow\[TypeParam\(bounds=\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.coroutines\.CoroutineContext/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.FlowWithInitialSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
 WARN: Missing @param tag for parameter `inflater` of function androidx\.fragment\.app/Fragment/onCreateOptionsMenu/\#android\.view\.Menu\#android\.view\.MenuInflater/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//produceState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.runtime\.ProduceStateScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.ProduceStateAwaitDispose\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//rememberUpdatedState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.rememberUpdatedStateSampleWithDisposableEffect\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//rememberUpdatedState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.rememberUpdatedStateSampleWithLaunchedEffect\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//snapshotFlow/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.snapshotFlowSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `hardwareBuffer` of function androidx\.graphics\.lowlatency/FrameBuffer/FrameBuffer/\#androidx\.graphics\.opengl\.egl\.EGLSpec\#android\.hardware\.HardwareBuffer/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.graphics\.opengl\.egl/EGLSpec/eglMakeCurrent/\#android\.opengl\.EGLContext\#android\.opengl\.EGLSurface\#android\.opengl\.EGLSurface/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.runtime\.snapshots/Snapshot/asContextElement/androidx\.compose\.runtime\.snapshots\.Snapshot\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.snapshotAsContextElementSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.snapshots//asContextElement/androidx\.compose\.runtime\.snapshots\.Snapshot\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.snapshotAsContextElementSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `context` of function androidx\.health\.connect\.client/HealthConnectClient\.Companion/getOrCreate/\#android\.content\.Context\#kotlin\.collections\.List\[kotlin\.String\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.health\.connect\.client/HealthConnectClient\.Companion/isAvailable/\#android\.content\.Context\#kotlin\.collections\.List\[kotlin\.String\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.health\.connect\.client/HealthConnectClient\.Companion/isProviderAvailable/\#android\.content\.Context\#kotlin\.collections\.List\[kotlin\.String\]/PointingToDeclaration/
@@ -1026,17 +526,7 @@
 Did you mean androidx\.health\.data\.client\.HealthDataClient\#getChanges\?
 WARN: Missing @param tag for parameter `query` of function androidx\.leanback\.app/SearchFragment/createArgs/\#android\.os\.Bundle\#java\.lang\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `query` of function androidx\.leanback\.app/SearchSupportFragment/createArgs/\#android\.os\.Bundle\#java\.lang\.String/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//alpha/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AlphaSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.BlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ImageBlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.BlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//blur/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.draw\.BlurredEdgeTreatment/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ImageBlurSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheModifierStateParameterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//drawWithCache/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.draw\.CacheDrawScope,androidx\.compose\.ui\.draw\.DrawResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawWithCacheContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//paint/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.painter\.Painter\#kotlin\.Boolean\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PainterModifierSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `detailsPresenter` of function androidx\.leanback\.widget/DetailsOverviewRowPresenter\.ViewHolder/ViewHolder/\#android\.view\.View\#androidx\.leanback\.widget\.Presenter/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.res//painterResource/\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AndroidDrawableInDrawScopeSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `detailsPresenter` of function androidx\.leanback\.widget/FullWidthDetailsOverviewRowPresenter\.ViewHolder/ViewHolder/\#android\.view\.View\#androidx\.leanback\.widget\.Presenter\#androidx\.leanback\.widget\.DetailsOverviewLogoPresenter/PointingToDeclaration/
 WARN: Missing @param tag for parameter `logoPresenter` of function androidx\.leanback\.widget/FullWidthDetailsOverviewRowPresenter\.ViewHolder/ViewHolder/\#android\.view\.View\#androidx\.leanback\.widget\.Presenter\#androidx\.leanback\.widget\.DetailsOverviewLogoPresenter/PointingToDeclaration/
 WARN: Missing @param tag for parameter `parent` of function androidx\.leanback\.widget/GridLayoutManager/requestChildRectangleOnScreen/\#androidx\.recyclerview\.widget\.RecyclerView\#android\.view\.View\#android\.graphics\.Rect\#boolean/PointingToDeclaration/
@@ -1046,7 +536,6 @@
 WARN: Missing @param tag for parameter `outlineIconIndex` of function androidx\.leanback\.widget/PlaybackControlsRow\.ThumbsAction/ThumbsAction/\#int\#android\.content\.Context\#int\#int/PointingToDeclaration/
 WARN: Multiple sources exist for MouseButton\. Artifact ID metadata will not be displayed
 WARN: Multiple sources exist for ComposeUiTest\. Artifact ID metadata will not be displayed
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction/performGesture/androidx\.compose\.ui\.test\.SemanticsNodeInteraction\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.test\.GestureScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.gestureClick\. b/[0-9]+
 WARN: Missing @param tag for parameter `name` of function androidx\.leanback\.widget/RecyclerViewParallax/createProperty/\#java\.lang\.String\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `publisher` of function androidx\.lifecycle/LiveDataReactiveStreams/fromPublisher/\#org\.reactivestreams\.Publisher<T>/PointingToDeclaration/
 WARN: Missing @param tag for parameter `coroutineDispatcher` of function androidx\.lifecycle\.testing/TestLifecycleOwner/TestLifecycleOwner/\#androidx\.lifecycle\.Lifecycle\.State\#kotlinx\.coroutines\.CoroutineDispatcher/PointingToDeclaration/
@@ -1094,139 +583,23 @@
 WARN: Missing @param tag for parameter `builder` of function androidx\.navigation\.dynamicfeatures\.fragment/DynamicFragmentNavigatorDestinationBuilderKt/fragment/androidx\.navigation\.dynamicfeatures\.DynamicNavGraphBuilder\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.navigation\.dynamicfeatures\.fragment\.DynamicFragmentNavigatorDestinationBuilder,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `builder` of function androidx\.navigation\.dynamicfeatures\.fragment/DynamicFragmentNavigatorDestinationBuilderKt/fragment/androidx\.navigation\.dynamicfeatures\.DynamicNavGraphBuilder\#kotlin\.String\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.navigation\.dynamicfeatures\.fragment\.DynamicFragmentNavigatorDestinationBuilder,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//expandHorizontally/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.HorizontalTransitionSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//SizeTransform/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedFloatingActionButton\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//animateColorAsState/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.animation\.core\.AnimationSpec\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.Color,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ColorAnimationSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ColumnAnimatedVisibilitySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//Crossfade/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.CrossfadeSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `contentKey` of function androidx\.compose\.animation//Crossfade/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//animateColor/androidx\.compose\.animation\.core\.InfiniteTransition\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.InfiniteTransitionSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.animation//Crossfade/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//expandIn/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntSize\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ExpandInShrinkOutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//animateColor/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Transition\.Segment\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),androidx\.compose\.ui\.graphics\.Color\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.GestureAnimationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//expandVertically/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ExpandShrinkVerticallySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//fadeIn/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FadeTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//animateContentSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntSize,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimateContent\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//fadeOut/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FadeTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//togetherWith/androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//scaleIn/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ScaledEnterExit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//scaleOut/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TransformOrigin/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ScaledEnterExit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//shrinkHorizontally/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.HorizontalTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//shrinkOut/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntSize\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ExpandInShrinkOutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//shrinkVertically/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.ExpandShrinkVerticallySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//slideIn/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideInOutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//slideInHorizontally/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//slideInVertically/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FullyLoadedTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//slideOut/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideInOutSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//slideOutHorizontally/\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.Function[0-9]+\[kotlin\.Int,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideTransition\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation//AnimatedVisibility/\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.FullyLoadedTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation//AnimatedVisibility/\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedVisibilityWithBooleanVisibleParamNoReceiver\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.animation//Crossfade/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `initialValue` of function androidx\.compose\.animation\.core//animate/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.AnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateTo/androidx\.compose\.animation\.core\.AnimationState\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.AnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.AnimationScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.animateToOnAnimationState\. b/[0-9]+
 WARN: Missing @param tag for parameter `targetValue` of function androidx\.compose\.animation\.core//animate/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.AnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateDpAsState/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.animation\.core\.AnimationSpec\[androidx\.compose\.ui\.unit\.Dp\]\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Dp,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.DpAnimationSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `initialValue` of function androidx\.compose\.animation\.core//animateDecay/\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.FloatDecayAnimationSpec\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `initialVelocity` of function androidx\.compose\.animation\.core//animateDecay/\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.FloatDecayAnimationSpec\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateValue/androidx\.compose\.animation\.core\.InfiniteTransition\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.TwoWayConverter\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionAnimateValueSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateFloatAsState/\#kotlin\.Float\#androidx\.compose\.animation\.core\.AnimationSpec\[kotlin\.Float\]\#kotlin\.Float\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AlphaAnimationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateIntOffsetAsState/\#androidx\.compose\.ui\.unit\.IntOffset\#androidx\.compose\.animation\.core\.AnimationSpec\[androidx\.compose\.ui\.unit\.IntOffset\]\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntOffset,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimateOffsetSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//createChildTransition/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.CreateChildTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateOffsetAsState/\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.animation\.core\.AnimationSpec\[androidx\.compose\.ui\.geometry\.Offset\]\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimateOffsetSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition/createChildTransition/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.CreateChildTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateValueAsState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.TwoWayConverter\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#androidx\.compose\.animation\.core\.AnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.ArbitraryValueTypeTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//infiniteRepeatable/\#androidx\.compose\.animation\.core\.DurationBasedAnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.animation\.core\.RepeatMode\#androidx\.compose\.animation\.core\.StartOffset/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteProgressIndicator\. b/[0-9]+
 WARN: Missing @param tag for parameter `typeConverter` of function androidx\.compose\.animation\.core//animateValueAsState/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.TwoWayConverter\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#androidx\.compose\.animation\.core\.AnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//keyframes/\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.KeyframesSpec\.KeyframesSpecConfig\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.FloatKeyframesBuilderInline\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//keyframes/\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.KeyframesSpec\.KeyframesSpecConfig\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.KeyframesBuilderWithEasing\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//rememberInfiniteTransition/\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//updateTransition/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.String\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.GestureAnimationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//updateTransition/\#androidx\.compose\.animation\.core\.MutableTransitionState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InitialStateSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.animation\.core/Animatable/Animatable/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.TwoWayConverter\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\#kotlin\.String/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Animatable/animateDecay/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.DecayAnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Animatable\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\],kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimatableDecayAndAnimateToSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/MutableTransitionState/isIdle/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.TransitionStateIsIdleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//Animatable/\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimatableFadeIn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/InfiniteTransition/animateFloat/androidx\.compose\.animation\.core\.InfiniteTransition\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[kotlin\.Float\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateFloat/androidx\.compose\.animation\.core\.InfiniteTransition\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[kotlin\.Float\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/InfiniteTransition/animateValue/androidx\.compose\.animation\.core\.InfiniteTransition\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.TwoWayConverter\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionAnimateValueSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Animatable/animateTo/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.AnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Animatable\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\],kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimatableFadeIn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animateFloat/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Transition\.Segment\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimateFloatSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition/AnimatedContent/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentTransitionScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.ContentTransform\]\#androidx\.compose\.ui\.Alignment\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedContentScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.TransitionExtensionAnimatedContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/KeyframesSpec\.KeyframesSpecConfig/with/androidx\.compose\.animation\.core\.KeyframesSpec\.KeyframeEntity\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.animation\.core\.Easing/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.KeyframesBuilderWithEasing\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/InfiniteTransition/animateColor/androidx\.compose\.animation\.core\.InfiniteTransition\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.animation\.core\.InfiniteRepeatableSpec\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.String/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.InfiniteTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/AnimationState/animateTo/androidx\.compose\.animation\.core\.AnimationState\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.animation\.core\.AnimationSpec\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.AnimationScope\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[androidx\.compose\.animation\.core\.AnimationVector\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.animateToOnAnimationState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition/AnimatedVisibility/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AddAnimatedVisibilityToGenericTransitionSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `contentKey` of function androidx\.compose\.animation\.core/Transition/Crossfade/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.animation\.core/Transition/Crossfade/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition/animateColor/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Transition\.Segment\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),androidx\.compose\.ui\.graphics\.Color\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.GestureAnimationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core//animate/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.animation\.core\.AnimationSpec\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.suspendAnimateFloatVariant\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition/animateFloat/androidx\.compose\.animation\.core\.Transition\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.core\.Transition\.Segment\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],androidx\.compose\.animation\.core\.FiniteAnimationSpec\[kotlin\.Float\]\]\#kotlin\.String\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimateFloatSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `animatedImageVector` of function androidx\.compose\.animation\.graphics\.res//rememberAnimatedVectorPainter/\#androidx\.compose\.animation\.graphics\.vector\.AnimatedImageVector\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.animation\.graphics\.vector/AnimatedImageVector\.Companion/animatedVectorResource/androidx\.compose\.animation\.graphics\.vector\.AnimatedImageVector\.Companion\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.graphics\.samples\.AnimatedVectorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/ScrollState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/MutatorMutex/mutateWith/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.foundation\.MutatePriority\#kotlin\.coroutines\.SuspendFunction[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.mutatorMutexStateObjectWithReceiver\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/OverscrollEffect/applyToFling/\#androidx\.compose\.ui\.unit\.Velocity\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.unit\.Velocity,androidx\.compose\.ui\.unit\.Velocity\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollWithDraggable_Before\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//background/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DrawBackgroundShapedBrush\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//Canvas/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanvasSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/ScrollState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/OverscrollEffect/applyToFling/\#androidx\.compose\.ui\.unit\.Velocity\#kotlin\.coroutines\.SuspendFunction[0-9]+\[androidx\.compose\.ui\.unit\.Velocity,androidx\.compose\.ui\.unit\.Velocity\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollWithDraggable_After\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//background/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DrawBackgroundColor\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicMarqueeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/OverscrollEffect/applyToScroll/\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollSource\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,androidx\.compose\.ui\.geometry\.Offset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollWithDraggable_Before\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//Canvas/\#androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.drawscope\.DrawScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanvasPieChartSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/OverscrollEffect/applyToScroll/\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.input\.nestedscroll\.NestedScrollSource\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,androidx\.compose\.ui\.geometry\.Offset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollWithDraggable_After\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicFocusableMarqueeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//Image/\#androidx\.compose\.ui\.graphics\.ImageBitmap\#kotlin\.String\?\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?\#androidx\.compose\.ui\.graphics\.FilterQuality/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ImageSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//basicMarquee/androidx\.compose\.ui\.Modifier\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeAnimationMode\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.MarqueeSpacing\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BasicMarqueeWithFadedEdgesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//Image/\#androidx\.compose\.ui\.graphics\.ImageBitmap\#kotlin\.String\?\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?\#androidx\.compose\.ui\.graphics\.FilterQuality/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BitmapPainterSubsectionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.BorderStroke\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//Image/\#androidx\.compose\.ui\.graphics\.painter\.Painter\#kotlin\.String\?\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BitmapPainterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithBrush\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Brush\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithDynamicData\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//isSystemInDarkTheme/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DarkThemeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//rememberScrollState/\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ControlledScrollableRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//border/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BorderSampleWithDataClass\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//clickable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//clickable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//combinedClickable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.String\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//combinedClickable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.String\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ClickableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//focusGroup/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//focusGroup/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusableFocusGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//focusable/androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//horizontalScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.ScrollState\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HorizontalScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//hoverable/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.HoverableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//indication/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.InteractionSource\#androidx\.compose\.foundation\.Indication\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.IndicationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//magnifier/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.geometry\.Offset\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.geometry\.Offset\]\#kotlin\.Float\#androidx\.compose\.foundation\.MagnifierStyle\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.DpSize,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.MagnifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//overscroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.OverscrollEffect/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//progressSemantics/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.IndeterminateProgressSemanticsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//progressSemantics/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DeterminateProgressSemanticsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation//verticalScroll/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.ScrollState\#kotlin\.Boolean\#androidx\.compose\.foundation\.gestures\.FlingBehavior\?\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.VerticalScrollExample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures/ScrollableState/canScrollBackward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures/ScrollableState/canScrollForward/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CanScrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitHorizontalDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitHorizontalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitHorizontalTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitHorizontalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitLongPressOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitLongPressOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitVerticalDragOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitVerticalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//awaitVerticalTouchSlopOrCancellation/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.AwaitVerticalDragOrCancellationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//calculateCentroid/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateCentroidSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//calculateCentroidSize/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateCentroidSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//calculatePan/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculatePan\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//calculateRotation/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateRotation\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//calculateZoom/androidx\.compose\.ui\.input\.pointer\.PointerEvent\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CalculateZoom\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//detectDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//detectDragGesturesAfterLongPress/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectDragWithLongPressGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//detectHorizontalDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectHorizontalDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//detectTransformGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,androidx\.compose\.ui\.geometry\.Offset,kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectTransformGestures\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//detectVerticalDragGestures/androidx\.compose\.ui\.input\.pointer\.PointerInputScope\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.geometry\.Offset,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DetectVerticalDragGesturesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures//drag/androidx\.compose\.ui\.input\.pointer\.AwaitPointerEventScope\#androidx\.compose\.ui\.input\.pointer\.PointerId\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.input\.pointer\.PointerInputChange,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DragSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `requestedInitialKey` of function androidx\.paging/ItemKeyedDataSource\.LoadInitialParams/LoadInitialParams/\#TypeParam\(bounds=\[kotlin\.Any\]\)\?\#kotlin\.Int\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `requestedLoadSize` of function androidx\.paging/ItemKeyedDataSource\.LoadInitialParams/LoadInitialParams/\#TypeParam\(bounds=\[kotlin\.Any\]\)\?\#kotlin\.Int\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `placeholdersEnabled` of function androidx\.paging/ItemKeyedDataSource\.LoadInitialParams/LoadInitialParams/\#TypeParam\(bounds=\[kotlin\.Any\]\)\?\#kotlin\.Int\#kotlin\.Boolean/PointingToDeclaration/
@@ -1240,91 +613,13 @@
 WARN: Missing @param tag for parameter `requestedLoadSize` of function androidx\.paging/PageKeyedDataSource\.LoadInitialParams/LoadInitialParams/\#kotlin\.Int\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `placeholdersEnabled` of function androidx\.paging/PageKeyedDataSource\.LoadInitialParams/LoadInitialParams/\#kotlin\.Int\#kotlin\.Boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.foundation\.layout//Column/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//FlowColumn/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.FlowColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFlowColumn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/weight/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleColumn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//asPaddingValues/androidx\.compose\.foundation\.layout\.WindowInsets\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.paddingValuesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//asPaddingValues/androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.ui\.unit\.Density/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.paddingValuesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//FlowColumn/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.FlowColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFlowColumnWithWeights\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//aspectRatio/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAspectRatio\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//FlowRow/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.FlowRowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFlowRow\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.foundation\.layout//Row/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//defaultMinSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.DefaultMinSizeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//Spacer/\#androidx\.compose\.ui\.Modifier/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SpacerExample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//displayCutoutPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.displayCutoutPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//WindowInsets/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsDp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxHeight/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//WindowInsets/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsInt\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxHeight/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxSize/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxSize/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxWidth/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFillWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//fillMaxWidth/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.FillHalfWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.MatchParentDividerForText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.MatchParentDividerForAspectRatio\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//height/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//imeNestedScroll/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.windowInsetsNestedScrollDemo\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//imePadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.imePaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//mandatorySystemGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.mandatorySystemGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//navigationBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.statusBarsAndNavigationBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//offset/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.OffsetModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//offset/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.OffsetPxModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//onConsumedWindowInsetsChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.WindowInsets,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.withConsumedInsetsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingValuesModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SymmetricPaddingModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//padding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingAllModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//paddingFrom/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.AlignmentLine\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//paddingFrom/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.AlignmentLine\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.unit\.TextUnit/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//paddingFromBaseline/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromBaselineSampleDp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//paddingFromBaseline/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.unit\.TextUnit/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromBaselineSampleTextUnit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//requiredHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredHeightModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//requiredSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//requiredWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRequiredWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//safeContentPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeContentPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//safeDrawingPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeDrawingPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//safeGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.safeGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//size/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleSizeModifierWithDpSize\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//statusBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.statusBarsAndNavigationBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//systemBarsPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.systemBarsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//systemGesturesPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.systemGesturesPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//waterfallPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.waterfallPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SameWidthBoxes\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.IntrinsicSize/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SameWidthTextBoxes\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//width/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWidthModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//windowInsetsBottomHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsBottomHeightSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//windowInsetsEndWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsEndWidthSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//windowInsetsPadding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//windowInsetsStartWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsStartWidthSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//windowInsetsTopHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.insetsTopHeightSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//wrapContentHeight/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentVerticallyAlignedModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//wrapContentSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentAlignedModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//wrapContentWidth/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleWrapContentHorizontallyAlignedModifier\. b/[0-9]+
 WARN: Missing @param tag for parameter `matchHeightConstraintsFirst` of function androidx\.compose\.foundation\.layout//aspectRatio/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Boolean/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//captionBarPadding/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.captionBarPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//FlowRow/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.FlowRowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleFlowRowWithWeights\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//consumeWindowInsets/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.PaddingValues/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.consumedInsetsPaddingSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//consumeWindowInsets/androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.consumedInsetsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//Row/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Horizontal\#androidx\.compose\.ui\.Alignment\.Vertical\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRow\. b/[0-9]+
 WARN: Missing @param tag for parameter `target` of function androidx\.palette\.graphics/Palette/getColorForTarget/\#androidx\.palette\.graphics\.Target\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.foundation\.layout/ColumnScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.foundation\.layout/ColumnScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//BoxWithConstraints/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.Alignment\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxWithConstraintsScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.BoxWithConstraintsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/RowScope/alignBy/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.HorizontalAlignmentLine/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAlignByInRow\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//absoluteOffset/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.Density,androidx\.compose\.ui\.unit\.IntOffset\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsoluteOffsetPxModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/alignBy/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.Measured,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRelativeToSiblings\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/RowScope/alignBy/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.layout\.Measured,kotlin\.Int\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAlignByInRow\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/RowScope/alignByBaseline/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAlignByInRow\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//Column/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.layout\.Arrangement\.Vertical\#androidx\.compose\.ui\.Alignment\.Horizontal\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleColumn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//absolutePadding/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsolutePaddingModifier\. b/[0-9]+
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.foundation\.layout/RowScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `label` of function androidx\.compose\.foundation\.layout/RowScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.RowScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/AnimatedVisibility/androidx\.compose\.foundation\.layout\.ColumnScope\#androidx\.compose\.animation\.core\.MutableTransitionState\[kotlin\.Boolean\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AVColumnScopeWithMutableTransitionState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//absoluteOffset/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.AbsoluteOffsetModifier\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/ColumnScope/alignBy/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.VerticalAlignmentLine/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleRelativeToSiblingsInColumn\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/WindowInsets/asPaddingValues/androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.ui\.unit\.Density/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.paddingValuesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout//Box/\#androidx\.compose\.ui\.Modifier/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleBox\. b/[0-9]+
 WARN: Missing @param tag for parameter `block` of function androidx\.compose\.foundation\.lazy\.layout/MutableIntervalList/forEach/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.layout\.IntervalList\.Interval\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.compose\.foundation\.lazy\.layout/IntervalList/forEach/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.lazy\.layout\.IntervalList\.Interval\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `properties` of function androidx\.privacysandbox\.tools\.core\.generator/KotlinPoetSpecsKt/primaryConstructor/com\.squareup\.kotlinpoet\.TypeSpec\.Builder\#kotlin\.collections\.List\[com\.squareup\.kotlinpoet\.PropertySpec\]\#kotlin\.Array\[com\.squareup\.kotlinpoet\.KModifier\]/PointingToDeclaration/
@@ -1350,79 +645,30 @@
 WARN: Missing @param tag for parameter `payload` of function androidx\.recyclerview\.widget/SortedListAdapterCallback/onChanged/\#int\#int\#java\.lang\.Object/PointingToDeclaration/
 WARN: Missing @param tag for parameter `backgroundColor` of function androidx\.compose\.material//BottomSheetScaffold/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.BottomSheetScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `contentColor` of function androidx\.compose\.material//BottomSheetScaffold/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.BottomSheetScaffoldState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.SnackbarHostState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.FabPosition\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ButtonWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Card/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ClickableCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Card/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Chip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.OutlinedChipWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Chip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ChipGroupSingleLineSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Chip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ChipGroupReflowSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `shape` of function androidx\.compose\.material//Chip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//CircularProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CircularProgressIndicatorSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//CircularProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//CircularProgressIndicator/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//Divider/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.foundation\.ScrollState\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.MenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.foundation\.ScrollState\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.MenuWithScrollStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//DropdownMenuItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.MenuSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `properties` of function androidx\.compose\.material//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//DropdownMenuItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ExposedDropdownMenuBox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.ExposedDropdownMenuBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ExposedDropdownMenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//ExposedDropdownMenuBox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.ExposedDropdownMenuBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.EditableExposedDropdownMenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//ExtendedFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material\.FloatingActionButtonElevation/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleExtendedFabWithIcon\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//ExtendedFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material\.FloatingActionButtonElevation/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FluidExtendedFab\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//FilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.SelectableChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FilterChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//FilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.SelectableChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FilterChipWithLeadingIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//FilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.SelectableChipColors\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.OutlinedFilterChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//FloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material\.FloatingActionButtonElevation\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleFab\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//IconButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.IconButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//LinearProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material//LinearProgressIndicator/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//MaterialTheme/\#androidx\.compose\.material\.Colors\#androidx\.compose\.material\.Typography\#androidx\.compose\.material\.Shapes\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//ModalBottomSheetLayout/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material\.ModalBottomSheetState\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ModalBottomSheetSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//OutlinedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Surface/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SelectableSurfaceSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Switch/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.SwitchColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SwitchSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Tab/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyTab\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyTab\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyIndicator\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyIndicatorTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.FancyAnimatedIndicator\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ToggleableSurfaceSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ClickableSurfaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ClickableSurfaceSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.Indication\?\#kotlin\.Boolean\#kotlin\.String\?\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//SwipeToDismiss/\#androidx\.compose\.material\.DismissState\#androidx\.compose\.ui\.Modifier\#kotlin\.collections\.Set\[androidx\.compose\.material\.DismissDirection\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material\.DismissDirection,androidx\.compose\.material\.ThresholdConfig\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SwipeToDismissListItems\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material//TextButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.ButtonElevation\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.material\.ButtonColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldWithPlaceholder\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldWithIcons\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldWithErrorState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldWithHelperMessage\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.PasswordTextField\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TextFieldWithHideKeyboardOnImeAction\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.SimpleTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//TriStateCheckbox/\#androidx\.compose\.ui\.state\.ToggleableState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.material\.CheckboxColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.TriStateCheckboxSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `leadingIconContentColor` of function androidx\.compose\.material/ChipDefaults/outlinedChipColors/\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material//LocalContentAlpha/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ContentAlphaSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//AlertDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.window\.DialogProperties/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.AlertDialogSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `shape` of function androidx\.compose\.material/TextFieldDefaults/BorderBox/\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.InteractionSource\#androidx\.compose\.material\.TextFieldColors\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material/MaterialTheme/colors/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.ThemeColorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material/TextFieldDefaults/OutlinedTextFieldDecorationBox/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.interaction\.InteractionSource\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material\.TextFieldColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CustomOutlinedTextFieldBasedOnDecorationBox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material//AlertDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.window\.DialogProperties/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.samples\.CustomAlertDialogSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `context` of function androidx\.security\.crypto//EncryptedSharedPreferences/\#android\.content\.Context\#kotlin\.String\#androidx\.security\.crypto\.MasterKey\#androidx\.security\.crypto\.EncryptedSharedPreferences\.PrefKeyEncryptionScheme\#androidx\.security\.crypto\.EncryptedSharedPreferences\.PrefValueEncryptionScheme/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.security\.crypto/EncryptedSharedPreferences/create/\#android\.content\.Context\#java\.lang\.String\#androidx\.security\.crypto\.MasterKey\#androidx\.security\.crypto\.EncryptedSharedPreferences\.PrefKeyEncryptionScheme\#androidx\.security\.crypto\.EncryptedSharedPreferences\.PrefValueEncryptionScheme/PointingToDeclaration/
 WARN: Missing @param tag for parameter `keyAlias` of function androidx\.security\.crypto/MasterKey\.Builder/Builder/\#android\.content\.Context\#java\.lang\.String/PointingToDeclaration/
@@ -1444,153 +690,32 @@
 WARN: Missing @param tag for parameter `action` of function androidx\.slice\.builders/ListBuilder\.RowBuilder/setTitleItem/\#androidx\.slice\.builders\.SliceAction\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `color` of function androidx\.slice\.widget/GridRowView/addImageItem/\#androidx\.slice\.SliceItem\#androidx\.slice\.SliceItem\#int\#android\.view\.ViewGroup\#boolean/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Card/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Card/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ClickableCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Card/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//CenterAlignedTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleCenterAlignedTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Checkbox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.CheckboxColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CheckboxSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Checkbox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.CheckboxColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CheckboxWithTextSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//CircularProgressIndicator/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.IndeterminateCircularProgressIndicatorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//CircularProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CircularProgressIndicatorSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `modifier` of function androidx\.compose\.material[0-9]+//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `properties` of function androidx\.compose\.material[0-9]+//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//DropdownMenu/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.DpOffset\#androidx\.compose\.ui\.window\.PopupProperties\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//ElevatedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedCard/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ElevatedCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//ElevatedCard/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedCard/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ClickableElevatedCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `body` of function androidx\.sqlite\.db//transaction/androidx\.sqlite\.db\.SupportSQLiteDatabase\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.sqlite\.db\.SupportSQLiteDatabase,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//ElevatedCard/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedFilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ElevatedFilterChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ElevatedSuggestionChip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ChipColors\#androidx\.compose\.material[0-9]+\.ChipElevation\?\#androidx\.compose\.material[0-9]+\.ChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ElevatedSuggestionChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ExposedDropdownMenuBox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.ExposedDropdownMenuBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ExposedDropdownMenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ExposedDropdownMenuBox/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.ExposedDropdownMenuBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.EditableExposedDropdownMenuSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ExtendedFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ExtendedFloatingActionButtonTextSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ExtendedFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ExtendedFloatingActionButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ExtendedFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.AnimatedExtendedFloatingActionButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilledIconButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilledIconButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilledIconToggleButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconToggleButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilledIconToggleButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilledTonalButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilledTonalButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilledTonalIconButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilledTonalIconButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `body` of function androidx\.sqlite\.db/SupportSQLiteDatabaseKt/transaction/androidx\.sqlite\.db\.SupportSQLiteDatabase\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.sqlite\.db\.SupportSQLiteDatabase,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `body` of function androidx\.sqlite\.db/SupportSQLiteDatabase/transaction/androidx\.sqlite\.db\.SupportSQLiteDatabase\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[androidx\.sqlite\.db\.SupportSQLiteDatabase,TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//FilledTonalButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilledTonalIconToggleButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconToggleButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilledTonalIconToggleButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilterChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FilterChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FilterChipWithLeadingIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//FloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FloatingActionButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//IconButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.IconButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.IconButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//IconToggleButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.IconToggleButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.IconToggleButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//InputChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.InputChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//InputChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.InputChipWithAvatarSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//InputChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ChipGroupSingleLineSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//InputChip/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SelectableChipColors\#androidx\.compose\.material[0-9]+\.SelectableChipElevation\?\#androidx\.compose\.material[0-9]+\.SelectableChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ChipGroupReflowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//LargeFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.LargeFloatingActionButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//LargeTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ExitUntilCollapsedLargeTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ModalBottomSheet/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.SheetState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ModalBottomSheetSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//LinearProgressIndicator/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.IndeterminateLinearProgressIndicatorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//LinearProgressIndicator/\#kotlin\.Float\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.StrokeCap/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.LinearProgressIndicatorSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ListItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.ListItemColors\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OneLineListItem\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ListItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.ListItemColors\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TwoLineListItem\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ListItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.ListItemColors\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ThreeLineListItem\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//MediumTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ExitUntilCollapsedMediumTopAppBar\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//MaterialTheme/\#androidx\.compose\.material[0-9]+\.ColorScheme\#androidx\.compose\.material[0-9]+\.Shapes\#androidx\.compose\.material[0-9]+\.Typography\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ModalBottomSheet/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.SheetState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.foundation\.layout\.WindowInsets\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ModalBottomSheetSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//ModalNavigationDrawer/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.DrawerState\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ModalNavigationDrawerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//NavigationBar/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.WindowInsets\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.NavigationBarSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//NavigationDrawerItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.NavigationDrawerItemColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ModalNavigationDrawerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//NavigationRail/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\?\#androidx\.compose\.foundation\.layout\.WindowInsets\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.NavigationRailSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `shape` of function androidx\.compose\.material[0-9]+//NavigationDrawerItem/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.NavigationDrawerItemColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OutlinedButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedCard/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OutlinedCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//OutlinedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedCard/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ClickableOutlinedCardSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//OutlinedCard/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedIconButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconButtonColors\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OutlinedIconButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//OutlinedCard/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.CardColors\#androidx\.compose\.material[0-9]+\.CardElevation\#androidx\.compose\.foundation\.BorderStroke\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedIconToggleButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.IconToggleButtonColors\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OutlinedIconToggleButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedTextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.OutlinedTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//OutlinedTextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleOutlinedTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//PermanentNavigationDrawer/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PermanentNavigationDrawerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//PlainTooltipBox/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.PlainTooltipState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.TooltipBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PlainTooltipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//PlainTooltipBox/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.PlainTooltipState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.TooltipBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PlainTooltipWithManualInvocationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RadioButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.RadioButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RadioButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RadioButton/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.RadioButtonColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RadioGroupSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.StepRangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderPositions,kotlin\.Unit\]\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RangeSliderWithCustomComponents\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RangeSlider/\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Function[0-9]+\[kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\],kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.StepRangeSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RichTooltipBox/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.RichTooltipState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.RichTooltipColors\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.TooltipBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RichTooltipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//RichTooltipBox/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.RichTooltipState\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.RichTooltipColors\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.TooltipBoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.RichTooltipWithManualInvocationSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Scaffold/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.material[0-9]+\.FabPosition\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.layout\.WindowInsets\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleScaffoldWithTopBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Scaffold/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.material[0-9]+\.FabPosition\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.layout\.WindowInsets\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SearchBar/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.SearchBarColors\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SearchBarSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#androidx\.compose\.material[0-9]+\.SliderState\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#androidx\.compose\.material[0-9]+\.SliderState\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.StepsSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#androidx\.compose\.material[0-9]+\.SliderState\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderWithCustomThumbSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#androidx\.compose\.material[0-9]+\.SliderState\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderWithCustomTrackAndThumb\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.StepsSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderWithCustomThumbSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Int\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SliderState,kotlin\.Unit\]\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderWithCustomTrackAndThumb\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Slider/\#kotlin\.Float\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.ranges\.ClosedFloatingPointRange\[kotlin\.Float\]\#kotlin\.Int\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.SliderColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.StepsSliderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SmallFloatingActionButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.material[0-9]+\.FloatingActionButtonElevation\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SmallFloatingActionButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.material[0-9]+\.SnackbarData\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.material[0-9]+\.SnackbarData\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.material[0-9]+\.SnackbarData\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithIndefiniteSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SmallTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Snackbar/\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithMultilineSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SmallTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PinnedTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SnackbarHost/\#androidx\.compose\.material[0-9]+\.SnackbarHostState\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SnackbarData,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithSimpleSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SnackbarHost/\#androidx\.compose\.material[0-9]+\.SnackbarHostState\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SnackbarData,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SuggestionChip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ChipColors\#androidx\.compose\.material[0-9]+\.ChipElevation\?\#androidx\.compose\.material[0-9]+\.ChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SuggestionChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SmallTopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.EnterAlwaysTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Surface/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SurfaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SelectableSurfaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ToggleableSurfaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ClickableSurfaceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//SwipeToDismiss/\#androidx\.compose\.material[0-9]+\.DismissState\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.collections\.Set\[androidx\.compose\.material[0-9]+\.DismissDirection\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SwipeToDismissListItems\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Switch/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SwitchColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SwitchSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Surface/\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Switch/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SwitchColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SwitchWithThumbIconSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyTab\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyIndicator\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyIndicatorTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyAnimatedIndicator\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TabRow/\#kotlin\.Int\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[androidx\.compose\.material[0-9]+\.TabPosition\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyIndicatorContainerTabs\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextButtonSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Tab/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.FancyTab\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//Surface/\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Boolean,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `maxSwipes` of function androidx\.test\.uiautomator/UiScrollable/scrollToBeginning/\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `maxSwipes` of function androidx\.test\.uiautomator/UiScrollable/scrollToEnd/\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `type` of function androidx\.textclassifier/TextClassification\.Builder/setEntityType/\#java\.lang\.String\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `type` of function androidx\.textclassifier/TextSelection\.Builder/setEntityType/\#java\.lang\.String\#float/PointingToDeclaration/
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.material[0-9]+//TextButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#androidx\.compose\.ui\.text\.input\.TextFieldValue\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.text\.input\.TextFieldValue,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleTextFieldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithPlaceholder\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithIcons\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithPrefixAndSuffix\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithErrorState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithSupportingText\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PasswordTextField\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TextField/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.String,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.TextStyle\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.text\.KeyboardOptions\#androidx\.compose\.foundation\.text\.KeyboardActions\#kotlin\.Boolean\#kotlin\.Int\#kotlin\.Int\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TextFieldWithHideKeyboardOnImeAction\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TimeInput/\#androidx\.compose\.material[0-9]+\.TimePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.TimePickerColors/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TimeInputSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TimePicker/\#androidx\.compose\.material[0-9]+\.TimePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.TimePickerColors\#androidx\.compose\.material[0-9]+\.TimePickerLayoutType/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TimePickerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TimePicker/\#androidx\.compose\.material[0-9]+\.TimePickerState\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.TimePickerColors\#androidx\.compose\.material[0-9]+\.TimePickerLayoutType/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TimePickerSwitchableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.PinnedTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TopAppBar/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.foundation\.layout\.WindowInsets\#androidx\.compose\.material[0-9]+\.TopAppBarColors\#androidx\.compose\.material[0-9]+\.TopAppBarScrollBehavior\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.EnterAlwaysTopAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//TriStateCheckbox/\#androidx\.compose\.ui\.state\.ToggleableState\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.CheckboxColors\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TriStateCheckboxSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `block` of function androidx\.tracing//traceAsync/\#kotlin\.String\#kotlin\.Int\#kotlin\.coroutines\.SuspendFunction[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.tracing//traceAsync/\#kotlin\.Function[0-9]+\[kotlin\.String\]\#kotlin\.Function[0-9]+\[kotlin\.Int\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `block` of function androidx\.tracing/TraceKt/traceAsync/\#kotlin\.String\#kotlin\.Int\#kotlin\.coroutines\.SuspendFunction[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
@@ -1606,104 +731,17 @@
 WARN: Missing @param tag for parameter `label` of function androidx\.tv\.material\.immersivelist/ImmersiveListBackgroundScope/AnimatedVisibility/\#kotlin\.Boolean\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.EnterTransition\#androidx\.compose\.animation\.ExitTransition\#kotlin\.String\#kotlin\.Function[0-9]+\[androidx\.compose\.animation\.AnimatedVisibilityScope,kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `disabledElevation` of function androidx\.compose\.material[0-9]+/CardDefaults/cardElevation/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `disabledElevation` of function androidx\.compose\.material[0-9]+/CardDefaults/elevatedCardElevation/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+/OutlinedTextFieldDefaults/DecorationBox/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.interaction\.InteractionSource\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.material[0-9]+\.TextFieldColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CustomOutlinedTextFieldBasedOnDecorationBox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+/SnackbarHostState/showSnackbar/\#androidx\.compose\.material[0-9]+\.SnackbarVisuals/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithCustomSnackbar\. b/[0-9]+
 WARN: Missing @param tag for parameter `disabledElevation` of function androidx\.compose\.material[0-9]+/CardDefaults/outlinedCardElevation/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `thumbSize` of function androidx\.compose\.material[0-9]+/SliderDefaults/Thumb/\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.SliderColors\#kotlin\.Boolean\#androidx\.compose\.ui\.unit\.DpSize/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//AlertDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.window\.DialogProperties\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.AlertDialogWithCustomContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+/TextFieldDefaults/DecorationBox/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.interaction\.InteractionSource\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.CustomTextFieldBasedOnDecorationBox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+/SnackbarHostState/showSnackbar/\#kotlin\.String\#kotlin\.String\?\#kotlin\.Boolean\#androidx\.compose\.material[0-9]+\.SnackbarDuration/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ScaffoldWithCoroutinesSnackbar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//AlertDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.window\.DialogProperties/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.AlertDialogSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//AlertDialog/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.window\.DialogProperties/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.AlertDialogWithIconSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//AssistChip/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ChipColors\#androidx\.compose\.material[0-9]+\.ChipElevation\?\#androidx\.compose\.material[0-9]+\.ChipBorder\?\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.AssistChipSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//BadgedBox/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.BoxScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.NavigationBarItemWithBadge\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//BottomAppBar/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleBottomAppBar\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//BottomAppBar/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.layout\.WindowInsets/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.BottomAppBarWithFAB\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//BottomSheetScaffold/\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.ColumnScope,kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#androidx\.compose\.material[0-9]+\.BottomSheetScaffoldState\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[androidx\.compose\.material[0-9]+\.SnackbarHostState,kotlin\.Unit\]\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.PaddingValues,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.SimpleBottomSheetScaffoldSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ButtonSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+//Button/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.material[0-9]+\.ButtonElevation\?\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.ButtonWithIconSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `shape` of function androidx\.compose\.material[0-9]+/TextFieldDefaults/OutlinedBorderContainerBox/\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.foundation\.interaction\.InteractionSource\#androidx\.compose\.material[0-9]+\.TextFieldColors\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `shape` of function androidx\.compose\.material[0-9]+/TextFieldDefaults/TextFieldDecorationBox/\#kotlin\.String\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#kotlin\.Boolean\#kotlin\.Boolean\#androidx\.compose\.ui\.text\.input\.VisualTransformation\#androidx\.compose\.foundation\.interaction\.InteractionSource\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\?\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.compose\.material[0-9]+\.TextFieldColors\#androidx\.compose\.foundation\.layout\.PaddingValues\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `context` of function androidx\.tvprovider\.media\.tv/PreviewChannelHelper/PreviewChannelHelper/\#android\.content\.Context\#int\#int/PointingToDeclaration/
 WARN: Missing @param tag for parameter `initial` of function androidx\.compose\.runtime//collectAsState/kotlinx\.coroutines\.flow\.Flow\[TypeParam\(bounds=\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\)\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#kotlin\.coroutines\.CoroutineContext/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.runtime//Composition/\#androidx\.compose\.runtime\.Applier\[\*\]\#androidx\.compose\.runtime\.CompositionContext/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//collectAsState/kotlinx\.coroutines\.flow\.StateFlow\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.coroutines\.CoroutineContext/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.StateFlowSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `key` of function androidx\.compose\.runtime//traceEventStart/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `info` of function androidx\.compose\.runtime//traceEventStart/\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.String/PointingToDeclaration/
 WARN: Missing @param tag for parameter `dataKey` of function androidx\.compose\.runtime/Composer/startMovableGroup/\#kotlin\.Int\#kotlin\.Any\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.runtime//CompositionLocalProvider/\#androidx\.compose\.runtime\.CompositionLocalContext\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.compositionLocalProvider\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//CompositionLocalProvider/\#kotlin\.Array\[androidx\.compose\.runtime\.ProvidedValue\[\*\]\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.compositionLocalProvider\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ControlledComposition/\#androidx\.compose\.runtime\.Applier\[\*\]\#androidx\.compose\.runtime\.CompositionContext/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//getValue/androidx\.compose\.runtime\.State\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Any\?\#kotlin\.reflect\.KProperty\[\*\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DelegatedReadOnlyStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//DisposableEffect/\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.DisposableEffectScope,androidx\.compose\.runtime\.DisposableEffectResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.disposableEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//setValue/androidx\.compose\.runtime\.MutableState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Any\?\#kotlin\.reflect\.KProperty\[\*\]\#TypeParam\(bounds=\[kotlin\.Any\?\]\)/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DelegatedStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//DisposableEffect/\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.DisposableEffectScope,androidx\.compose\.runtime\.DisposableEffectResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.disposableEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//DisposableEffect/\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.DisposableEffectScope,androidx\.compose\.runtime\.DisposableEffectResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.disposableEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//DisposableEffect/\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.DisposableEffectScope,androidx\.compose\.runtime\.DisposableEffectResult\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.disposableEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ReusableComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ReusableComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.SkippableUpdater\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],kotlin\.Unit\]\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//ReusableComposeNode/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.Updater\[TypeParam\(bounds=\[kotlin\.Any\]\)\],kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//derivedStateOf/\#androidx\.compose\.runtime\.SnapshotMutationPolicy\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DerivedStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//derivedStateOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DerivedStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//key/\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.LocallyUniqueKeys\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//key/\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.NotAlwaysUniqueKeys\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//key/\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MoreCorrectUniqueKeys\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//key/\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.TwoInputsKeySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentColumnRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//movableContentWithReceiverOf/\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.MovableContentMultiColumnSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateListOf/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.stateListSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateMapOf/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.stateMapSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateOf/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.runtime\.SnapshotMutationPolicy\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.SimpleStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateOf/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.runtime\.SnapshotMutationPolicy\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.DestructuredStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateOf/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.runtime\.SnapshotMutationPolicy\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.observeUserSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime//mutableStateOf/\#TypeParam\(bounds=\[kotlin\.Any\?\]\)\#androidx\.compose\.runtime\.SnapshotMutationPolicy\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.stateSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `content` of function androidx\.compose\.runtime\.saveable/SaveableStateHolder/SaveableStateProvider/\#kotlin\.Any\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//Saver/\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.saveable\.SaverScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),TypeParam\(bounds=\[kotlin\.Any\]\)\?\]\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\),TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.CustomSaverSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//listSaver/\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.saveable\.SaverScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.collections\.List\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\]\#kotlin\.Function[0-9]+\[kotlin\.collections\.List\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\],TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.ListSaverSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//mapSaver/\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.saveable\.SaverScope,TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.collections\.Map\[kotlin\.String,kotlin\.Any\?\]\]\#kotlin\.Function[0-9]+\[kotlin\.collections\.Map\[kotlin\.String,kotlin\.Any\?\],TypeParam\(bounds=\[kotlin\.Any\?\]\)\?\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.MapSaverSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//rememberSaveable/\#kotlin\.Array\[kotlin\.Any\?\]\#androidx\.compose\.runtime\.saveable\.Saver\[TypeParam\(bounds=\[kotlin\.Any\?\]\),kotlin\.Any\]\#kotlin\.String\?\#kotlin\.Function[0-9]+\[androidx\.compose\.runtime\.MutableState\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.RememberSaveableWithMutableStateAndCustomSaver\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//rememberSaveable/\#kotlin\.Array\[kotlin\.Any\?\]\#androidx\.compose\.runtime\.saveable\.Saver\[TypeParam\(bounds=\[kotlin\.Any\]\),kotlin\.Any\]\#kotlin\.String\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.RememberSaveable\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//rememberSaveable/\#kotlin\.Array\[kotlin\.Any\?\]\#androidx\.compose\.runtime\.saveable\.Saver\[TypeParam\(bounds=\[kotlin\.Any\]\),kotlin\.Any\]\#kotlin\.String\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.RememberSaveableCustomSaver\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//rememberSaveable/\#kotlin\.Array\[kotlin\.Any\?\]\#androidx\.compose\.runtime\.saveable\.Saver\[TypeParam\(bounds=\[kotlin\.Any\]\),kotlin\.Any\]\#kotlin\.String\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.RememberSaveableWithMutableState\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable//rememberSaveable/\#kotlin\.Array\[kotlin\.Any\?\]\#androidx\.compose\.runtime\.saveable\.Saver\[TypeParam\(bounds=\[kotlin\.Any\]\),kotlin\.Any\]\#kotlin\.String\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\]\)\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.RememberSaveableWithMutableStateAndCustomSaver\. b/[0-9]+
 WARN: Missing @param tag for parameter `block` of function androidx\.compose\.runtime\.snapshots/Snapshot\.Companion/observe/\#kotlin\.Function[0-9]+\[kotlin\.Any,kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[kotlin\.Any,kotlin\.Unit\]\?\#kotlin\.Function[0-9]+\[TypeParam\(bounds=\[kotlin\.Any\?\]\)\]/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier\.Node/coroutineScope/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierNodeCoroutineScopeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier\.Node/onReset/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierNodeResetSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/paddingFrom/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.AlignmentLine\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/paddingFrom/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.layout\.AlignmentLine\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.unit\.TextUnit/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Any\?\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/paddingFromBaseline/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromBaselineSampleDp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//composed/androidx\.compose\.ui\.Modifier\#kotlin\.String\#kotlin\.Array\[kotlin\.Any\?\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.platform\.InspectorInfo,kotlin\.Unit\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.Modifier,androidx\.compose\.ui\.Modifier\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.InspectorInfoInComposedModifierWithArgumentsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/paddingFromBaseline/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.TextUnit\#androidx\.compose\.ui\.unit\.TextUnit/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.PaddingFromBaselineSampleTextUnit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui//zIndex/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ZIndexModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/alpha/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AlphaSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/animateContentSize/androidx\.compose\.ui\.Modifier\#androidx\.compose\.animation\.core\.FiniteAnimationSpec\[androidx\.compose\.ui\.unit\.IntSize\]\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.unit\.IntSize,androidx\.compose\.ui\.unit\.IntSize,kotlin\.Unit\]\?/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimateContent\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/aspectRatio/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.SimpleAspectRatio\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier/background/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Shape/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.DrawBackgroundColor\. b/[0-9]+
 WARN: Missing @param tag for parameter `loadActionExecutor` of function androidx\.wear\.tiles\.renderer/TileRenderer/TileRenderer/\#android\.content\.Context\#androidx\.wear\.tiles\.LayoutElementBuilders\.Layout\#androidx\.wear\.tiles\.ResourceBuilders\.Resources\#java\.util\.concurrent\.Executor\#androidx\.wear\.tiles\.renderer\.TileRenderer\.LoadActionListener/PointingToDeclaration/
 WARN: Missing @param tag for parameter `loadActionExecutor` of function androidx\.wear\.tiles\.renderer/TileRenderer/TileRenderer/\#android\.content\.Context\#androidx\.wear\.tiles\.LayoutElementBuilders\.Layout\#int\#androidx\.wear\.tiles\.ResourceBuilders\.Resources\#java\.util\.concurrent\.Executor\#androidx\.wear\.tiles\.renderer\.TileRenderer\.LoadActionListener/PointingToDeclaration/
 WARN: Missing @param tag for parameter `listenerExecutor` of function androidx\.wear\.tiles\.timeline/TilesTimelineManager/TilesTimelineManager/\#android\.app\.AlarmManager\#androidx\.wear\.tiles\.timeline\.TilesTimelineManager\.Clock\#androidx\.wear\.tiles\.TimelineBuilders\.Timeline\#int\#java\.util\.concurrent\.Executor\#androidx\.wear\.tiles\.timeline\.TilesTimelineManager\.Listener/PointingToDeclaration/
@@ -1719,77 +757,14 @@
 WARN: Missing @param tag for parameter `tags` of function androidx\.work\.testing//TestWorkerBuilder/\#android\.content\.Context\#java\.util\.concurrent\.Executor\#androidx\.work\.Data\#kotlin\.collections\.List\[kotlin\.String\]\#kotlin\.Int\#kotlin\.collections\.List\[android\.net\.Uri\]\#kotlin\.collections\.List\[kotlin\.String\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `tags` of function androidx\.work\.testing/TestWorkerBuilderKt/TestWorkerBuilder/\#android\.content\.Context\#java\.util\.concurrent\.Executor\#androidx\.work\.Data\#kotlin\.collections\.List\[kotlin\.String\]\#kotlin\.Int\#kotlin\.collections\.List\[android\.net\.Uri\]\#kotlin\.collections\.List\[kotlin\.String\]/PointingToDeclaration/
 WARN: Missing @param tag for parameter `painter` of function androidx\.compose\.ui\.draw//paint/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.graphics\.painter\.Painter\#kotlin\.Boolean\#androidx\.compose\.ui\.Alignment\#androidx\.compose\.ui\.layout\.ContentScale\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ColorFilter\?/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//rotate/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RotateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//scale/androidx\.compose\.ui\.Modifier\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ScaleNonUniformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//scale/androidx\.compose\.ui\.Modifier\#kotlin\.Float/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ScaleUniformSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.draw//shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ShadowSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `ambientColor` of function androidx\.compose\.ui\.draw//shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
 WARN: Missing @param tag for parameter `spotColor` of function androidx\.compose\.ui\.draw//shadow/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.graphics\.Shape\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequesterModifier/focusRequester/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequesterModifierNode/captureFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//captureFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusState/isCaptured/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/down/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Down/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/down/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester\.Companion/Cancel/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CancelFocusMoveSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester\.Companion/createRefs/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CreateFocusRequesterRefsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester/captureFocus/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequesterModifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/end/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusManager/clearFocus/\#kotlin\.Boolean/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ClearFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/end/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Left/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/left/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Next/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/enter/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusEnterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequesterModifierNode/freeFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusState/isFocused/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/next/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester/freeFocus/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Previous/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//focusProperties/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusProperties,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusPropertiesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//focusOrder/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.focus\.FocusRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequesterModifierNode/requestFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester/requestFocus/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Right/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/previous/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//focusRequester/androidx\.compose\.ui\.Modifier\#androidx\.compose\.ui\.focus\.FocusRequester/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusManager/moveFocus/\#androidx\.compose\.ui\.focus\.FocusDirection/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection\.Companion/Up/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//focusTarget/androidx\.compose\.ui\.Modifier\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSampleUsingLowerLevelFocusTarget\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//focusOrder/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusOrder,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/right/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/exit/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusExitSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//freeFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CaptureFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/start/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//onFocusChanged/androidx\.compose\.ui\.Modifier\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.focus\.FocusState,kotlin\.Unit\]/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusOrder/up/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus//requestFocus/androidx\.compose\.ui\.focus\.FocusRequesterModifierNode\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/left/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/next/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/previous/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/right/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/start/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusProperties/up/\#/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CustomFocusOrderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/horizontalGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.HorizontalGradientColorStopSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/ImageBitmap/readPixels/\#kotlin\.IntArray\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.ImageBitmapReadPixelsSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `radians` of function androidx\.compose\.ui\.graphics//rotateRad/androidx\.compose\.ui\.graphics\.Canvas\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/verticalGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.VerticalGradientColorStopSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/verticalGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics//toPixelMap/androidx\.compose\.ui\.graphics\.ImageBitmap\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.Int\#kotlin\.IntArray\#kotlin\.Int\#kotlin\.Int/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.ImageBitmapToPixelMapSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/verticalGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.VerticalGradientSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/verticalGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
 WARN: Missing @param tag for parameter `renderEffect` of function androidx\.compose\.ui\.graphics/BlurEffect/BlurEffect/\#androidx\.compose\.ui\.graphics\.RenderEffect\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/
 WARN: Multiple sources exist for BlurEffect\. Artifact ID metadata will not be displayed
 WARN: Missing @param tag for parameter `clipOp` of function androidx\.compose\.ui\.graphics/Canvas/clipRect/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.ClipOp/PointingToDeclaration/
 WARN: Missing @param tag for parameter `paint` of function androidx\.compose\.ui\.graphics/Canvas/drawArc/\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Paint/PointingToDeclaration/
 WARN: Missing @param tag for parameter `operation` of function androidx\.compose\.ui\.graphics/AndroidPath/op/\#androidx\.compose\.ui\.graphics\.Path\#androidx\.compose\.ui\.graphics\.Path\#androidx\.compose\.ui\.graphics\.PathOperation/PointingToDeclaration/
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/horizontalGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.HorizontalGradientSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/horizontalGradient/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.Color\]\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/linearGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.LinearGradientColorStopSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/Brush\.Companion/linearGradient/\#kotlin\.Array\[kotlin\.Pair\[kotlin\.Float,androidx\.compose\.ui\.graphics\.Color\]\]\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.geometry\.Offset\#androidx\.compose\.ui\.graphics\.TileMode/PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.GradientBrushSample\. b/[0-9]+
 WARN\: Multiple sources exist for RestrictTo\. Artifact ID metadata will not be displayed
 WARN\: Multiple sources exist for Scope\. Artifact ID metadata will not be displayed
 WARN\: Multiple sources exist for SparseArrayCompat\. Artifact ID metadata will not be displayed
@@ -1805,6 +780,7 @@
 WARNING\: link to \@throws type ArrayIndexOutOfBoundsException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function\, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name\,  e\.g\.\`\@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root\=CustomDocTag\(children\=\[P\(children\=\[Text\(body\=if \, children\=\[\]\, params\=\{\}\)\, DocumentationLink\(dri\=androidx\.collection\/CircularArray\/removeFromEnd\/\#kotlin\.Int\/PointingToCallableParameters\([0-9]+\)\/\, children\=\[Text\(body\=count\, children\=\[\]\, params\=\{\}\)\]\, params\=\{href\=\[count\]\}\)\, Text\(body\= is larger than \, children\=\[\]\, params\=\{\}\)\, DocumentationLink\(dri\=androidx\.collection\/CircularArray\/size\/\#\/PointingToDeclaration\/\, children\=\[Text\(body\=size\, children\=\[\]\, params\=\{\}\)\]\, params\=\{href\=\[size\]\}\)\]\, params\=\{\}\)\]\, params\=\{\}\, name\=MARKDOWN_FILE\)\, name\=ArrayIndexOutOfBoundsException\, exceptionAddress\=null\)\.\`
 WARNING\: link to \@throws type ArrayIndexOutOfBoundsException does not resolve\. Is it from a package that the containing file does not import\? Is docs inherited to an un\-documented override function\, but the exception class is not in scope in the inheriting class\? The general fix for these is to fully qualify the exception name\,  e\.g\.\`\@throws java\.io\.IOException under some conditions\. This was observed in Throws\(root\=CustomDocTag\(children\=\[P\(children\=\[Text\(body\=if \, children\=\[\]\, params\=\{\}\)\, DocumentationLink\(dri\=androidx\.collection\/CircularArray\/removeFromStart\/\#kotlin\.Int\/PointingToCallableParameters\([0-9]+\)\/\, children\=\[Text\(body\=count\, children\=\[\]\, params\=\{\}\)\]\, params\=\{href\=\[count\]\}\)\, Text\(body\= is larger than \, children\=\[\]\, params\=\{\}\)\, DocumentationLink\(dri\=androidx\.collection\/CircularArray\/size\/\#\/PointingToDeclaration\/\, children\=\[Text\(body\=size\, children\=\[\]\, params\=\{\}\)\]\, params\=\{href\=\[size\]\}\)\]\, params\=\{\}\)\]\, params\=\{\}\, name\=MARKDOWN_FILE\)\, name\=ArrayIndexOutOfBoundsException\, exceptionAddress\=null\)\.\`
 WARN\: Multiple sources exist for ArraySet\. Artifact ID metadata will not be displayed
+WARN\: Multiple sources exist for CheckResult\. Artifact ID metadata will not be displayed
 # Wire proto generation, task :generateDebugProtos
 Writing .* to \$OUT_DIR/.*/build/generated/source/wire
 # > Task :compose:ui:ui-tooling:processDebugAndroidTestManifest
@@ -1834,6 +810,7 @@
 public abstract java\.util\.List<androidx\.room\.integration\.kotlintestapp\.test\.JvmNameInDaoTest\.JvmNameEntity> jvmQuery\(\);
 public abstract androidx\.room\.integration\.kotlintestapp\.test\.JvmNameInDaoTest\.JvmNameDao jvmDao\(\);
 \^
+Note: \$SUPPORT/wear/tiles/tiles\-material/src/main/java/androidx/wear/tiles/material/CircularProgressIndicator\.java has additional uses or overrides of a deprecated API\.
 Note: \$SUPPORT/wear/tiles/tiles\-material/src/main/java/androidx/wear/tiles/material/TitleChip\.java has additional uses or overrides of a deprecated API\.
 \$SUPPORT/wear/tiles/tiles\-material/src/main/java/androidx/wear/tiles/material/layouts/PrimaryLayout\.java:[0-9]+: warning: \[deprecation\] CompactChip in androidx\.wear\.tiles\.material has been deprecated
 Note: \$SUPPORT/wear/tiles/tiles\-material/src/main/java/androidx/wear/tiles/material/Button\.java has additional uses or overrides of a deprecated API\.
@@ -2369,124 +1346,4 @@
 Info: Unexpected error while reading deps\.ui\.inspection\.kotlin\.reflect\.jvm\.internal\.KClassImpl\$Data\$qualifiedName\$[0-9]+'s kotlin\.Metadata: null
 Info: Unexpected error while reading deps\.ui\.inspection\.kotlin\.reflect\.jvm\.internal\.KCallableImpl's kotlin\.Metadata: null
 # b/271306193 remove after aosp/2589888 :emoji:emoji:spdxSbomForRelease
-spdx sboms require a version but project: noto\-emoji\-compat\-flatbuffers has no specified version
-# > Task :docs-public:docs
-WARNING: no common source set for DPackage androidx\.compose\.ui\.test\.junit[0-9]+////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every usable sourceSet depends on jvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common source set for DPackage androidx\.compose\.ui\.tooling////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every usable sourceSet depends on jvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common source set for DPackage androidx\.compose\.ui\.test\.junit[0-9]+////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every sourceSet depends onjvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common source set for DPackage androidx\.compose\.ui\.tooling////PointingToDeclaration/! Falling back to jvmMain sourceSet! This is only defensible if every sourceSet depends onjvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/AbstractApplier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/AlignmentLine///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.AlignmentLineSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Animatable///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimatableAnimateToGenericsType\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/AnimatedVisibilityScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AVScopeAnimateEnterExit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/AnimationResult///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.AnimatableAnimationResultSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/AnnotatedString\.Builder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderAppendableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/Applier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.CustomTreeComposition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/BaselineShift///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.BaselineShiftSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/BaselineShift///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.BaselineShiftAnnotatedStringSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewRequester///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewRequester///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringPartOfComposableIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewResponder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.relocation/BringIntoViewResponder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.BringPartOfComposableIntoViewSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/CompositionLocal///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.createCompositionLocal\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/CompositionLocal///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.compositionLocalProvider\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/CompositionLocal///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.someScreenSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/CompositionLocal///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.consumeCompositionLocal\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/CompositionLocalConsumerModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CompositionLocalConsumingModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/ContentTransform///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DelegatingNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DelegatedNodeSampleExplicit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DelegatingNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DelegatedNodeSampleImplicit\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DelegatingNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LazyDelegationExample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DelegatingNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ConditionalDelegationExample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DelegatingNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DelegateInAttachSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.unit/Density///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.unit\.samples\.WithDensitySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.unit/Dp///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.unit\.samples\.DpSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.unit/Dp///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.unit\.samples\.ToPxSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/DrawModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.DrawModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics\.drawscope/DrawScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.DrawScopeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/EnterExitState///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedVisibilityWithBooleanVisibleParamNoReceiver\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/EnterTransition///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/ExitTransition///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.SlideTransition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusDirection///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.MoveFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.RequestFocusSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusRequester\.Companion\.FocusRequesterFactory///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.CreateFocusRequesterRefsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.focus/FocusState///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.FocusableSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontListFontFamily///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilySansSerifSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontListFontFamily///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.CustomFontFamilySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/FontSynthesis///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.FontFamilySynthesisSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/GlobalPositionAwareModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnGloballyPositioned\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/GlobalPositionAwareModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.GlobalPositionAwareModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.icons/Icons///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.icons\.samples\.AppIcons\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material\.icons/Icons///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material\.icons\.samples\.DrawIcon\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/Immutable///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.simpleImmutableClass\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/InfiniteRepeatableSpec///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteProgressIndicator\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/InfiniteTransition///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteTransitionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.text/InlineTextContent///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.InlineTextContentSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.interaction/InteractionSource///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SimpleInteractionSourceSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.interaction/InteractionSource///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.InteractionSourceFlowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/Key///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventIsAltPressedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEvent///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.input\.key/KeyEventType///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.KeyEventTypeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/KeyframesSpec///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.FloatKeyframesBuilder\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/KeyframesSpec///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.KeyframesBuilderWithEasing\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/KeyframesSpec\.KeyframesSpecConfig///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.KeyframesBuilderForPosition\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/LayoutAwareModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnSizeChangedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/LayoutAwareModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnPlaced\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/LayoutAwareModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutAwareModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LayoutModifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/LayoutModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LayoutModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/LineBreak///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.LineBreakSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/LineBreak///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AndroidLineBreakSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/LookaheadScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.LookaheadLayoutCoordinatesSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/MainTestClock///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.testSlideOut\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/MainTestClock///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.testControlClock\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierUsageSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierFactorySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierParameterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SubcomponentModifierSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier\.Companion///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierUsageSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui/Modifier\.Companion///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierParameterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.modifier/ModifierLocalModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.JustReadingOrProvidingModifierLocalNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/ModifierNodeElement///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.ModifierNodeElementSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/ModifierNodeElement///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SemanticsModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/MouseInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/MouseInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.mouseInputScrollWhileDown\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/MultiModalInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.multiModalInputClickDragDrop\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/MutableTransitionState///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InitialStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.layout/MutableWindowInsets///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.layout\.samples\.withConsumedInsetsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/MutatorMutex///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.mutatorMutexStateObject\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/OnGloballyPositionedModifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnGloballyPositioned\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/OnPlacedModifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnPlaced\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/OnRemeasuredModifier///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.OnSizeChangedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/OverscrollEffect///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.OverscrollSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.pager/PageSize///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.CustomPageSizeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/ParagraphStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.ParagraphStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/ParagraphStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.ParagraphStyleAnnotatedStringsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/PixelMap///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.ImageBitmapReadPixelsSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.node/PointerInputModifierNode///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.PointerInputModifierNodeSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.font/ResourceFont///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.CustomFontFamilySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/RotaryInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.rotaryInputScroll\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable/SaveableStateHolder///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.SimpleNavigationWithSaveableStateSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime\.saveable/Saver///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.saveable\.samples\.CustomSaverSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation/ScrollState///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.ControlledScrollableRowSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.clickAndVerifyCheckbox\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteraction///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.useUnmergedTree\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/SemanticsNodeInteractionCollection///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.verifyTwoClickableNodes\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation/SizeTransform///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.samples\.AnimatedContentTransitionSpecSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures\.snapping/SnapFlingBehavior///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SnapFlingBehaviorSimpleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.foundation\.gestures\.snapping/SnapFlingBehavior///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.foundation\.samples\.SnapFlingBehaviorCustomizedSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.runtime/SnapshotMutationPolicy///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.runtime\.samples\.counterSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.SpanStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/SpanStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.AnnotatedStringBuilderSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.graphics/StampedPathEffectStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.graphics\.samples\.StampedPathEffectSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/StartOffset///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.InfiniteProgressIndicator\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.layout/SubcomposeIntermediateMeasureScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.samples\.SubcomposeLayoutWithIntermediateMeasurePolicySample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text\.style/TextMotion///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextMotionSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.text/TextStyle///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.text\.samples\.TextStyleSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.material[0-9]+/TimePickerState///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.material[0-9]+\.samples\.TimePickerSample\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/TouchInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputClick\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/TouchInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputSwipeUp\. b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.ui\.test/TouchInjectionScope///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.ui\.test\.samples\.touchInputLShapedGesture\. b/[0-9]+
-WARNING: no common source set for DParameter androidx\.compose\.ui\.test\.junit[0-9]+//createComposeRule/\#kotlin\.coroutines\.CoroutineContext/PointingToCallableParameters\([0-9]+\)/! Falling back to jvmMain sourceSet! This is only defensible if every usable sourceSet depends on jvmMain! This is a bug in dackka: b/[0-9]+
-WARNING: no common sourceSet for androidx\.compose\.animation\.core/Transition///PointingToDeclaration/, falling back to \.single\(\) when resolving @sample androidx\.compose\.animation\.core\.samples\.GestureAnimationSample\. b/[0-9]+
\ No newline at end of file
+spdx sboms require a version but project: noto\-emoji\-compat\-flatbuffers has no specified version
\ No newline at end of file
diff --git a/development/importMaven/src/main/kotlin/androidx/build/importMaven/Main.kt b/development/importMaven/src/main/kotlin/androidx/build/importMaven/Main.kt
index bd5716f..8730816 100644
--- a/development/importMaven/src/main/kotlin/androidx/build/importMaven/Main.kt
+++ b/development/importMaven/src/main/kotlin/androidx/build/importMaven/Main.kt
@@ -27,11 +27,11 @@
 import com.github.ajalt.clikt.parameters.options.option
 import com.github.ajalt.clikt.parameters.options.required
 import com.github.ajalt.clikt.parameters.types.int
+import kotlin.system.exitProcess
 import okio.FileSystem
 import okio.Path
 import okio.Path.Companion.toPath
 import org.apache.logging.log4j.kotlin.logger
-import kotlin.system.exitProcess
 
 /**
  * Base class for all commands which only reads the support repo folder.
@@ -253,6 +253,7 @@
                 --------------------------------------------------------------------------------
             """.trimIndent()
         }
+        updatePlaygroundMetalavaBuildIfNecessary(downloadedFiles)
         if (downloadedFiles.isEmpty()) {
             logger.warn(
                 """
@@ -267,7 +268,7 @@
         } else {
             if (!result.dependenciesPassedVerification) {
                 logger.warn(
-                   """
+                    """
                    Our Gradle build won't trust any artifacts that are unsigned or are signed with new keys. To trust these artifacts, run `development/update-verification-metadata.sh
                    """.trimIndent()
                 )
@@ -275,6 +276,42 @@
         }
         flushLogs()
     }
+
+    /**
+     * GitHub Playground's metalava build id needs to match the build id used by androidx.
+     *
+     * This method takes care of updating playground.properties if the metalava build id
+     * is specified in the import maven script, and we've downloaded metalava.
+     */
+    private fun updatePlaygroundMetalavaBuildIfNecessary(downloadedFiles: Set<Path>) {
+        val metalavaBuild = metalavaBuildId ?: return
+        val downloadedMetalava = downloadedFiles.any {
+            it.name.contains("metalava")
+        }
+        if (!downloadedMetalava) {
+            return
+        }
+        val playgroundPropertiesFile = null.orFromSupportRepoFolder(
+            "playground-common/playground.properties"
+        ).toFile()
+        check(playgroundPropertiesFile.exists()) {
+            """
+                Cannot find playground properties file. This is needed to update metalava in
+                playground to match AndroidX.
+            """.trimIndent()
+        }
+        val updatedProperties = playgroundPropertiesFile.readLines(
+            Charsets.UTF_8
+        ).joinToString("\n") {
+            if (it.trim().startsWith("androidx.playground.metalavaBuildId=")) {
+                "androidx.playground.metalavaBuildId=$metalavaBuild"
+            } else {
+                it
+            }
+        }
+        playgroundPropertiesFile.writeText(updatedProperties)
+        logger.info { "updated playground properties" }
+    }
 }
 
 /**
diff --git a/development/project-creator/compose-template/groupId/artifactId/build.gradle b/development/project-creator/compose-template/groupId/artifactId/build.gradle
index d169a63..b3b12f8 100644
--- a/development/project-creator/compose-template/groupId/artifactId/build.gradle
+++ b/development/project-creator/compose-template/groupId/artifactId/build.gradle
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-import androidx.build.LibraryType
 import androidx.build.KmpPlatformsKt
+import androidx.build.LibraryType
+import androidx.build.PlatformIdentifier
 
 plugins {
     id("AndroidXPlugin")
@@ -29,6 +30,8 @@
     android()
     if (desktopEnabled) desktop()
 
+    defaultPlatform(PlatformIdentifier.ANDROID)
+
     sourceSets {
         commonMain {
             dependencies {
diff --git a/development/studio/idea.properties b/development/studio/idea.properties
index f352237..6f9146c 100644
--- a/development/studio/idea.properties
+++ b/development/studio/idea.properties
@@ -194,4 +194,4 @@
 #-----------------------------------------------------------------------
 # Enable compose @Preview rendering
 #-----------------------------------------------------------------------
-compose.project.uses.compose.override=true
\ No newline at end of file
+compose.project.uses.compose.override=true
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 8ca6f01..dbcecb3 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -8,10 +8,10 @@
 }
 
 dependencies {
-    docs("androidx.activity:activity:1.8.0-alpha04")
-    docs("androidx.activity:activity-compose:1.8.0-alpha04")
-    samples("androidx.activity:activity-compose-samples:1.8.0-alpha04")
-    docs("androidx.activity:activity-ktx:1.8.0-alpha04")
+    docs("androidx.activity:activity:1.8.0-alpha05")
+    docs("androidx.activity:activity-compose:1.8.0-alpha05")
+    samples("androidx.activity:activity-compose-samples:1.8.0-alpha05")
+    docs("androidx.activity:activity-ktx:1.8.0-alpha05")
     docs("androidx.ads:ads-identifier:1.0.0-alpha05")
     docs("androidx.ads:ads-identifier-common:1.0.0-alpha05")
     docs("androidx.ads:ads-identifier-provider:1.0.0-alpha05")
@@ -30,14 +30,14 @@
     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.0-alpha14")
-    docs("androidx.benchmark:benchmark-junit4:1.2.0-alpha14")
-    docs("androidx.benchmark:benchmark-macro:1.2.0-alpha14")
-    docs("androidx.benchmark:benchmark-macro-junit4:1.2.0-alpha14")
+    docs("androidx.benchmark:benchmark-common:1.2.0-alpha15")
+    docs("androidx.benchmark:benchmark-junit4:1.2.0-alpha15")
+    docs("androidx.benchmark:benchmark-macro:1.2.0-alpha15")
+    docs("androidx.benchmark:benchmark-macro-junit4:1.2.0-alpha15")
     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.browser:browser:1.6.0-alpha01")
+    docs("androidx.browser:browser:1.6.0-alpha02")
     docs("androidx.camera:camera-camera2:1.3.0-alpha07")
     docs("androidx.camera:camera-core:1.3.0-alpha07")
     docs("androidx.camera:camera-extensions:1.3.0-alpha07")
@@ -55,55 +55,55 @@
     docs("androidx.cardview:cardview:1.0.0")
     kmpDocs("androidx.collection:collection:1.3.0-alpha03")
     docs("androidx.collection:collection-ktx:1.3.0-alpha03")
-    kmpDocs("androidx.compose.animation:animation:1.5.0-beta01")
+    kmpDocs("androidx.compose.animation:animation:1.5.0-beta02")
     kmpDocs("androidx.compose.animation:animation-core:1.5.0-beta01")
-    kmpDocs("androidx.compose.animation:animation-graphics:1.5.0-beta01")
-    samples("androidx.compose.animation:animation-samples:1.5.0-beta01")
-    samples("androidx.compose.animation:animation-core-samples:1.5.0-beta01")
-    samples("androidx.compose.animation:animation-graphics-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.foundation:foundation:1.5.0-beta01")
-    kmpDocs("androidx.compose.foundation:foundation-layout:1.5.0-beta01")
-    samples("androidx.compose.foundation:foundation-layout-samples:1.5.0-beta01")
-    samples("androidx.compose.foundation:foundation-samples:1.5.0-beta01")
+    kmpDocs("androidx.compose.animation:animation-graphics:1.5.0-beta02")
+    samples("androidx.compose.animation:animation-samples:1.5.0-beta02")
+    samples("androidx.compose.animation:animation-core-samples:1.5.0-beta02")
+    samples("androidx.compose.animation:animation-graphics-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.foundation:foundation:1.5.0-beta02")
+    kmpDocs("androidx.compose.foundation:foundation-layout:1.5.0-beta02")
+    samples("androidx.compose.foundation:foundation-layout-samples:1.5.0-beta02")
+    samples("androidx.compose.foundation:foundation-samples:1.5.0-beta02")
     kmpDocs("androidx.compose.material3:material3:1.2.0-alpha02")
     samples("androidx.compose.material3:material3-samples:1.2.0-alpha02")
     kmpDocs("androidx.compose.material3:material3-window-size-class:1.2.0-alpha02")
     samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-alpha01")
-    kmpDocs("androidx.compose.material:material:1.5.0-beta01")
-    kmpDocs("androidx.compose.material:material-icons-core:1.5.0-beta01")
-    samples("androidx.compose.material:material-icons-core-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.material:material-ripple:1.5.0-beta01")
-    samples("androidx.compose.material:material-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.runtime:runtime:1.5.0-beta01")
-    docs("androidx.compose.runtime:runtime-livedata:1.5.0-beta01")
-    samples("androidx.compose.runtime:runtime-livedata-samples:1.5.0-beta01")
-    docs("androidx.compose.runtime:runtime-rxjava2:1.5.0-beta01")
-    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.5.0-beta01")
-    docs("androidx.compose.runtime:runtime-rxjava3:1.5.0-beta01")
-    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.runtime:runtime-saveable:1.5.0-beta01")
-    samples("androidx.compose.runtime:runtime-saveable-samples:1.5.0-beta01")
-    samples("androidx.compose.runtime:runtime-samples:1.5.0-beta01")
+    kmpDocs("androidx.compose.material:material:1.5.0-beta02")
+    kmpDocs("androidx.compose.material:material-icons-core:1.5.0-beta02")
+    samples("androidx.compose.material:material-icons-core-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.material:material-ripple:1.5.0-beta02")
+    samples("androidx.compose.material:material-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.runtime:runtime:1.5.0-beta02")
+    docs("androidx.compose.runtime:runtime-livedata:1.5.0-beta02")
+    samples("androidx.compose.runtime:runtime-livedata-samples:1.5.0-beta02")
+    docs("androidx.compose.runtime:runtime-rxjava2:1.5.0-beta02")
+    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.5.0-beta02")
+    docs("androidx.compose.runtime:runtime-rxjava3:1.5.0-beta02")
+    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.runtime:runtime-saveable:1.5.0-beta02")
+    samples("androidx.compose.runtime:runtime-saveable-samples:1.5.0-beta02")
+    samples("androidx.compose.runtime:runtime-samples:1.5.0-beta02")
     docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha03")
-    kmpDocs("androidx.compose.ui:ui:1.5.0-beta01")
+    kmpDocs("androidx.compose.ui:ui:1.5.0-beta02")
     kmpDocs("androidx.compose.ui:ui-geometry:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-graphics:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-graphics-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-test:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-test-junit4:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-test-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-text:1.5.0-beta01")
-    docs("androidx.compose.ui:ui-text-google-fonts:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-text-samples:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling-data:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.5.0-beta01")
-    kmpDocs("androidx.compose.ui:ui-unit:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-unit-samples:1.5.0-beta01")
+    kmpDocs("androidx.compose.ui:ui-graphics:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-graphics-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-test:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-test-junit4:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-test-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-text:1.5.0-beta02")
+    docs("androidx.compose.ui:ui-text-google-fonts:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-text-samples:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling-data:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-tooling-preview:1.5.0-beta02")
+    kmpDocs("androidx.compose.ui:ui-unit:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-unit-samples:1.5.0-beta02")
     kmpDocs("androidx.compose.ui:ui-util:1.5.0-beta01")
-    docs("androidx.compose.ui:ui-viewbinding:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-viewbinding-samples:1.5.0-beta01")
-    samples("androidx.compose.ui:ui-samples:1.5.0-beta01")
+    docs("androidx.compose.ui:ui-viewbinding:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-viewbinding-samples:1.5.0-beta02")
+    samples("androidx.compose.ui:ui-samples:1.5.0-beta02")
     docs("androidx.concurrent:concurrent-futures:1.2.0-alpha01")
     docs("androidx.concurrent:concurrent-futures-ktx:1.2.0-alpha01")
     docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha10")
@@ -111,21 +111,22 @@
     docs("androidx.constraintlayout:constraintlayout-core:1.1.0-alpha10")
     docs("androidx.contentpager:contentpager:1.0.0")
     docs("androidx.coordinatorlayout:coordinatorlayout:1.2.0")
-    docs("androidx.core.uwb:uwb:1.0.0-alpha05")
-    docs("androidx.core.uwb:uwb-rxjava3:1.0.0-alpha05")
+    docs("androidx.core:core:1.12.0-alpha05")
+    docs("androidx.core:core-animation:1.0.0-beta02")
+    docs("androidx.core:core-animation-testing:1.0.0-beta01")
     docs("androidx.core:core-google-shortcuts:1.1.0")
+    docs("androidx.core:core-ktx:1.12.0-alpha05")
     docs("androidx.core:core-performance:1.0.0-alpha03")
     samples("androidx.core:core-performance-samples:1.0.0-alpha03")
     docs("androidx.core:core-remoteviews:1.0.0-beta04")
     docs("androidx.core:core-role:1.2.0-alpha01")
-    docs("androidx.core:core-animation:1.0.0-beta02")
-    docs("androidx.core:core-animation-testing:1.0.0-beta01")
-    docs("androidx.core:core:1.12.0-alpha04")
-    docs("androidx.core:core-ktx:1.12.0-alpha03")
     docs("androidx.core:core-splashscreen:1.1.0-alpha01")
-    docs("androidx.core:core-testing:1.12.0-alpha03")
-    docs("androidx.credentials:credentials:1.2.0-alpha03")
-    docs("androidx.credentials:credentials-play-services-auth:1.2.0-alpha03")
+    docs("androidx.core:core-telecom:1.0.0-alpha01")
+    docs("androidx.core:core-testing:1.12.0-alpha05")
+    docs("androidx.core.uwb:uwb:1.0.0-alpha05")
+    docs("androidx.core.uwb:uwb-rxjava3:1.0.0-alpha05")
+    docs("androidx.credentials:credentials:1.2.0-alpha05")
+    docs("androidx.credentials:credentials-play-services-auth:1.2.0-alpha05")
     docs("androidx.credentials:credentials-provider:1.0.0-alpha03")
     docs("androidx.cursoradapter:cursoradapter:1.0.0")
     docs("androidx.customview:customview:1.2.0-alpha02")
@@ -144,32 +145,32 @@
     docs("androidx.drawerlayout:drawerlayout:1.2.0")
     docs("androidx.dynamicanimation:dynamicanimation:1.1.0-alpha02")
     docs("androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03")
+    docs("androidx.emoji:emoji:1.2.0-alpha03")
+    docs("androidx.emoji:emoji-appcompat:1.2.0-alpha03")
+    docs("androidx.emoji:emoji-bundled:1.2.0-alpha03")
     docs("androidx.emoji2:emoji2:1.4.0-beta04")
     docs("androidx.emoji2:emoji2-bundled:1.4.0-beta04")
     docs("androidx.emoji2:emoji2-emojipicker:1.4.0-beta04")
     docs("androidx.emoji2:emoji2-views:1.4.0-beta04")
     docs("androidx.emoji2:emoji2-views-helper:1.4.0-beta04")
-    docs("androidx.emoji:emoji:1.2.0-alpha03")
-    docs("androidx.emoji:emoji-appcompat:1.2.0-alpha03")
-    docs("androidx.emoji:emoji-bundled:1.2.0-alpha03")
     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.6.0-rc01")
-    docs("androidx.fragment:fragment-ktx:1.6.0-rc01")
-    docs("androidx.fragment:fragment-testing:1.6.0-rc01")
+    docs("androidx.fragment:fragment:1.7.0-alpha01")
+    docs("androidx.fragment:fragment-ktx:1.7.0-alpha01")
+    docs("androidx.fragment:fragment-testing:1.7.0-alpha01")
     docs("androidx.glance:glance:1.0.0-beta01")
-    samples("androidx.glance:glance-appwidget-samples:1.0.0-beta01")
     docs("androidx.glance:glance-appwidget:1.0.0-beta01")
+    samples("androidx.glance:glance-appwidget-samples:1.0.0-beta01")
     docs("androidx.glance:glance-appwidget-preview:1.0.0-alpha06")
     docs("androidx.glance:glance-appwidget-proto:1.0.0-alpha03")
     docs("androidx.glance:glance-preview:1.0.0-alpha06")
     docs("androidx.glance:glance-wear-tiles:1.0.0-alpha06")
     docs("androidx.glance:glance-wear-tiles-preview:1.0.0-alpha06")
-    docs("androidx.graphics:graphics-core:1.0.0-alpha03")
+    docs("androidx.graphics:graphics-core:1.0.0-alpha04")
     docs("androidx.gridlayout:gridlayout:1.1.0-beta01")
-    docs("androidx.health.connect:connect-client:1.0.0-alpha11")
-    samples("androidx.health.connect:connect-client-samples:1.0.0-alpha11")
+    docs("androidx.health.connect:connect-client:1.1.0-alpha01")
+    samples("androidx.health.connect:connect-client-samples:1.1.0-alpha01")
     docs("androidx.health:health-services-client:1.0.0-beta03")
     docs("androidx.heifwriter:heifwriter:1.1.0-alpha01")
     docs("androidx.hilt:hilt-common:1.0.0-beta01")
@@ -214,69 +215,69 @@
     docs("androidx.media2:media2-session:1.2.1")
     docs("androidx.media2:media2-widget:1.2.1")
     docs("androidx.media:media:1.6.0")
-    docs("androidx.media3:media3-cast:1.1.0-beta01")
-    docs("androidx.media3:media3-common:1.1.0-beta01")
-    docs("androidx.media3:media3-container:1.1.0-beta01")
-    docs("androidx.media3:media3-database:1.1.0-beta01")
-    docs("androidx.media3:media3-datasource:1.1.0-beta01")
-    docs("androidx.media3:media3-datasource-cronet:1.1.0-beta01")
-    docs("androidx.media3:media3-datasource-okhttp:1.1.0-beta01")
-    docs("androidx.media3:media3-datasource-rtmp:1.1.0-beta01")
-    docs("androidx.media3:media3-decoder:1.1.0-beta01")
-    docs("androidx.media3:media3-effect:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-dash:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-hls:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-ima:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-rtsp:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-smoothstreaming:1.1.0-beta01")
-    docs("androidx.media3:media3-exoplayer-workmanager:1.1.0-beta01")
-    docs("androidx.media3:media3-extractor:1.1.0-beta01")
-    docs("androidx.media3:media3-muxer:1.1.0-beta01")
-    docs("androidx.media3:media3-session:1.1.0-beta01")
-    docs("androidx.media3:media3-test-utils:1.1.0-beta01")
-    docs("androidx.media3:media3-test-utils-robolectric:1.1.0-beta01")
-    docs("androidx.media3:media3-transformer:1.1.0-beta01")
-    docs("androidx.media3:media3-ui:1.1.0-beta01")
-    docs("androidx.media3:media3-ui-leanback:1.1.0-beta01")
-    docs("androidx.mediarouter:mediarouter:1.6.0-alpha03")
-    docs("androidx.mediarouter:mediarouter-testing:1.6.0-alpha03")
+    docs("androidx.media3:media3-cast:1.1.0-rc01")
+    docs("androidx.media3:media3-common:1.1.0-rc01")
+    docs("androidx.media3:media3-container:1.1.0-rc01")
+    docs("androidx.media3:media3-database:1.1.0-rc01")
+    docs("androidx.media3:media3-datasource:1.1.0-rc01")
+    docs("androidx.media3:media3-datasource-cronet:1.1.0-rc01")
+    docs("androidx.media3:media3-datasource-okhttp:1.1.0-rc01")
+    docs("androidx.media3:media3-datasource-rtmp:1.1.0-rc01")
+    docs("androidx.media3:media3-decoder:1.1.0-rc01")
+    docs("androidx.media3:media3-effect:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-dash:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-hls:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-ima:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-rtsp:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-smoothstreaming:1.1.0-rc01")
+    docs("androidx.media3:media3-exoplayer-workmanager:1.1.0-rc01")
+    docs("androidx.media3:media3-extractor:1.1.0-rc01")
+    docs("androidx.media3:media3-muxer:1.1.0-rc01")
+    docs("androidx.media3:media3-session:1.1.0-rc01")
+    docs("androidx.media3:media3-test-utils:1.1.0-rc01")
+    docs("androidx.media3:media3-test-utils-robolectric:1.1.0-rc01")
+    docs("androidx.media3:media3-transformer:1.1.0-rc01")
+    docs("androidx.media3:media3-ui:1.1.0-rc01")
+    docs("androidx.media3:media3-ui-leanback:1.1.0-rc01")
+    docs("androidx.mediarouter:mediarouter:1.6.0-alpha04")
+    docs("androidx.mediarouter:mediarouter-testing:1.6.0-alpha04")
     docs("androidx.metrics:metrics-performance:1.0.0-alpha04")
-    docs("androidx.navigation:navigation-common:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-common-ktx:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-compose:2.7.0-alpha01")
-    samples("androidx.navigation:navigation-compose-samples:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-dynamic-features-fragment:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-dynamic-features-runtime:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-fragment:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-fragment-ktx:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-runtime:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-runtime-ktx:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-testing:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-ui:2.7.0-alpha01")
-    docs("androidx.navigation:navigation-ui-ktx:2.7.0-alpha01")
-    docs("androidx.paging:paging-common:3.2.0-alpha06")
-    docs("androidx.paging:paging-common-ktx:3.2.0-alpha06")
-    docs("androidx.paging:paging-compose:1.0.0-alpha20")
-    samples("androidx.paging:paging-compose-samples:1.0.0-alpha20")
-    docs("androidx.paging:paging-guava:3.2.0-alpha06")
-    docs("androidx.paging:paging-runtime:3.2.0-alpha06")
-    docs("androidx.paging:paging-runtime-ktx:3.2.0-alpha06")
-    docs("androidx.paging:paging-rxjava2:3.2.0-alpha06")
-    docs("androidx.paging:paging-rxjava2-ktx:3.2.0-alpha06")
-    docs("androidx.paging:paging-rxjava3:3.2.0-alpha06")
-    samples("androidx.paging:paging-samples:3.2.0-alpha06")
-    docs("androidx.paging:paging-testing:3.2.0-alpha06")
+    docs("androidx.navigation:navigation-common:2.7.0-beta01")
+    docs("androidx.navigation:navigation-common-ktx:2.7.0-beta01")
+    docs("androidx.navigation:navigation-compose:2.7.0-beta01")
+    samples("androidx.navigation:navigation-compose-samples:2.7.0-beta01")
+    docs("androidx.navigation:navigation-dynamic-features-fragment:2.7.0-beta01")
+    docs("androidx.navigation:navigation-dynamic-features-runtime:2.7.0-beta01")
+    docs("androidx.navigation:navigation-fragment:2.7.0-beta01")
+    docs("androidx.navigation:navigation-fragment-ktx:2.7.0-beta01")
+    docs("androidx.navigation:navigation-runtime:2.7.0-beta01")
+    docs("androidx.navigation:navigation-runtime-ktx:2.7.0-beta01")
+    docs("androidx.navigation:navigation-testing:2.7.0-beta01")
+    docs("androidx.navigation:navigation-ui:2.7.0-beta01")
+    docs("androidx.navigation:navigation-ui-ktx:2.7.0-beta01")
+    docs("androidx.paging:paging-common:3.2.0-beta01")
+    docs("androidx.paging:paging-common-ktx:3.2.0-beta01")
+    docs("androidx.paging:paging-compose:3.2.0-beta01")
+    samples("androidx.paging:paging-compose-samples:3.2.0-beta01")
+    docs("androidx.paging:paging-guava:3.2.0-beta01")
+    docs("androidx.paging:paging-runtime:3.2.0-beta01")
+    docs("androidx.paging:paging-runtime-ktx:3.2.0-beta01")
+    docs("androidx.paging:paging-rxjava2:3.2.0-beta01")
+    docs("androidx.paging:paging-rxjava2-ktx:3.2.0-beta01")
+    docs("androidx.paging:paging-rxjava3:3.2.0-beta01")
+    samples("androidx.paging:paging-samples:3.2.0-beta01")
+    docs("androidx.paging:paging-testing:3.2.0-beta01")
     docs("androidx.palette:palette:1.0.0")
     docs("androidx.palette:palette-ktx:1.0.0")
     docs("androidx.percentlayout:percentlayout:1.0.1")
     docs("androidx.preference:preference:1.2.0")
     docs("androidx.preference:preference-ktx:1.2.0")
     docs("androidx.print:print:1.1.0-beta01")
-    docs("androidx.privacysandbox.ads:ads-adservices:1.0.0-beta04")
-    docs("androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta04")
-    docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha04")
-    docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha04")
+    docs("androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05")
+    docs("androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05")
+    docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha05")
+    docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha05")
     docs("androidx.privacysandbox.tools:tools:1.0.0-alpha04")
     docs("androidx.privacysandbox.tools:tools-apigenerator:1.0.0-alpha04")
     docs("androidx.privacysandbox.tools:tools-apipackager:1.0.0-alpha04")
@@ -342,15 +343,15 @@
     docs("androidx.test.services:storage:1.5.0-alpha01")
     docs("androidx.test.uiautomator:uiautomator:2.3.0-alpha03")
     docs("androidx.textclassifier:textclassifier:1.0.0-alpha04")
-    docs("androidx.tracing:tracing:1.2.0-rc01")
-    docs("androidx.tracing:tracing-ktx:1.2.0-rc01")
-    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha15")
-    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha15")
+    docs("androidx.tracing:tracing:1.3.0-alpha01")
+    docs("androidx.tracing:tracing-ktx:1.3.0-alpha01")
+    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha16")
+    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha16") // TODO(243405142) clean-up
     docs("androidx.transition:transition:1.5.0-alpha01")
     docs("androidx.transition:transition-ktx:1.5.0-alpha01")
-    docs("androidx.tv:tv-foundation:1.0.0-alpha06")
-    docs("androidx.tv:tv-material:1.0.0-alpha06")
-    samples("androidx.tv:tv-samples:1.0.0-alpha06")
+    docs("androidx.tv:tv-foundation:1.0.0-alpha07")
+    docs("androidx.tv:tv-material:1.0.0-alpha07")
+    samples("androidx.tv:tv-samples:1.0.0-alpha07")
     docs("androidx.tvprovider:tvprovider:1.1.0-alpha01")
     docs("androidx.vectordrawable:vectordrawable:1.2.0-beta01")
     docs("androidx.vectordrawable:vectordrawable-animated:1.2.0-alpha01")
@@ -358,26 +359,26 @@
     docs("androidx.versionedparcelable:versionedparcelable:1.1.1")
     docs("androidx.viewpager2:viewpager2:1.1.0-beta02")
     docs("androidx.viewpager:viewpager:1.1.0-alpha01")
-    docs("androidx.wear.compose:compose-foundation:1.2.0-beta01")
-    samples("androidx.wear.compose:compose-foundation-samples:1.2.0-beta01")
-    docs("androidx.wear.compose:compose-material:1.2.0-beta01")
-    docs("androidx.wear.compose:compose-material-core:1.2.0-beta01")
-    samples("androidx.wear.compose:compose-material-samples:1.2.0-beta01")
-    docs("androidx.wear.compose:compose-material3:1.0.0-alpha05")
-    samples("androidx.wear.compose:compose-material3-samples:1.2.0-beta01")
-    docs("androidx.wear.compose:compose-navigation:1.2.0-beta01")
-    samples("androidx.wear.compose:compose-navigation-samples:1.2.0-beta01")
-    docs("androidx.wear.compose:compose-ui-tooling:1.2.0-beta01")
-    docs("androidx.wear.protolayout:protolayout:1.0.0-alpha10")
-    docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha10")
-    docs("androidx.wear.protolayout:protolayout-material:1.0.0-alpha10")
-    docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha10")
-    docs("androidx.wear.tiles:tiles:1.2.0-alpha06")
-    docs("androidx.wear.tiles:tiles-material:1.2.0-alpha06")
-    docs("androidx.wear.tiles:tiles-proto:1.2.0-alpha06")
-    docs("androidx.wear.tiles:tiles-renderer:1.2.0-alpha06")
-    docs("androidx.wear.tiles:tiles-testing:1.2.0-alpha06")
-    docs("androidx.wear.tiles:tiles-tooling:1.2.0-alpha06")
+    docs("androidx.wear.compose:compose-foundation:1.2.0-beta02")
+    samples("androidx.wear.compose:compose-foundation-samples:1.2.0-beta02")
+    docs("androidx.wear.compose:compose-material:1.2.0-beta02")
+    docs("androidx.wear.compose:compose-material-core:1.2.0-beta02")
+    samples("androidx.wear.compose:compose-material-samples:1.2.0-beta02")
+    docs("androidx.wear.compose:compose-material3:1.0.0-alpha06")
+    samples("androidx.wear.compose:compose-material3-samples:1.2.0-beta02")
+    docs("androidx.wear.compose:compose-navigation:1.2.0-beta02")
+    samples("androidx.wear.compose:compose-navigation-samples:1.2.0-beta02")
+    docs("androidx.wear.compose:compose-ui-tooling:1.2.0-beta02")
+    docs("androidx.wear.protolayout:protolayout:1.0.0-alpha11")
+    docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha11")
+    docs("androidx.wear.protolayout:protolayout-material:1.0.0-alpha11")
+    docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha11")
+    docs("androidx.wear.tiles:tiles:1.2.0-alpha07")
+    docs("androidx.wear.tiles:tiles-material:1.2.0-alpha07")
+    docs("androidx.wear.tiles:tiles-proto:1.2.0-alpha07")
+    docs("androidx.wear.tiles:tiles-renderer:1.2.0-alpha07")
+    docs("androidx.wear.tiles:tiles-testing:1.2.0-alpha07")
+    docs("androidx.wear.tiles:tiles-tooling:1.2.0-alpha07")
     docs("androidx.wear.watchface:watchface:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-client:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-client-guava:1.2.0-alpha08")
@@ -385,39 +386,38 @@
     docs("androidx.wear.watchface:watchface-complications-data:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0-alpha08")
-    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-data:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-editor:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-editor-guava:1.2.0-alpha08")
-    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-guava:1.2.0-alpha08")
     samples("androidx.wear.watchface:watchface-samples:1.2.0-alpha08")
     docs("androidx.wear.watchface:watchface-style:1.2.0-alpha08")
-    docs("androidx.wear:wear:1.3.0-alpha05")
+    docs("androidx.wear:wear:1.3.0-beta01")
     stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
-    docs("androidx.wear:wear-ongoing:1.1.0-alpha01")
-    docs("androidx.wear:wear-phone-interactions:1.1.0-alpha03")
-    docs("androidx.wear:wear-remote-interactions:1.0.0")
     docs("androidx.wear:wear-input:1.2.0-alpha02")
     samples("androidx.wear:wear-input-samples:1.2.0-alpha01")
     docs("androidx.wear:wear-input-testing:1.2.0-alpha02")
-    docs("androidx.webkit:webkit:1.7.0")
+    docs("androidx.wear:wear-ongoing:1.1.0-alpha01")
+    docs("androidx.wear:wear-phone-interactions:1.1.0-alpha03")
+    docs("androidx.wear:wear-remote-interactions:1.0.0")
+    docs("androidx.webkit:webkit:1.8.0-alpha01")
     docs("androidx.window.extensions.core:core:1.0.0")
-    docs("androidx.window:window:1.2.0-alpha01")
+    docs("androidx.window:window:1.2.0-alpha02")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
-    docs("androidx.window:window-core:1.2.0-alpha01")
+    docs("androidx.window:window-core:1.2.0-alpha02")
     stubs("androidx.window:window-extensions:1.0.0-alpha01")
-    docs("androidx.window:window-java:1.2.0-alpha01")
-    docs("androidx.window:window-rxjava2:1.2.0-alpha01")
-    docs("androidx.window:window-rxjava3:1.2.0-alpha01")
-    samples("androidx.window:window-samples:1.2.0-alpha01")
-    docs("androidx.window:window-testing:1.2.0-alpha01")
-    docs("androidx.work:work-gcm:2.8.1")
-    docs("androidx.work:work-multiprocess:2.8.1")
-    docs("androidx.work:work-runtime:2.8.1")
-    docs("androidx.work:work-runtime-ktx:2.8.1")
-    docs("androidx.work:work-rxjava2:2.8.1")
-    docs("androidx.work:work-rxjava3:2.8.1")
-    docs("androidx.work:work-testing:2.8.1")
+    docs("androidx.window:window-java:1.2.0-alpha02")
+    docs("androidx.window:window-rxjava2:1.2.0-alpha02")
+    docs("androidx.window:window-rxjava3:1.2.0-alpha02")
+    samples("androidx.window:window-samples:1.2.0-alpha02")
+    docs("androidx.window:window-testing:1.2.0-alpha02")
+    docs("androidx.work:work-gcm:2.9.0-alpha01")
+    docs("androidx.work:work-multiprocess:2.9.0-alpha01")
+    docs("androidx.work:work-runtime:2.9.0-alpha01")
+    docs("androidx.work:work-runtime-ktx:2.9.0-alpha01")
+    docs("androidx.work:work-rxjava2:2.9.0-alpha01")
+    docs("androidx.work:work-rxjava3:2.9.0-alpha01")
+    docs("androidx.work:work-testing:2.9.0-alpha01")
 }
+
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index d898c6f..a9bc28c 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -12,6 +12,7 @@
     docs(project(":activity:activity-compose"))
     samples(project(":activity:activity-compose:activity-compose-samples"))
     docs(project(":activity:activity-ktx"))
+    // ads-identifier is deprecated
     kmpDocs(project(":annotation:annotation"))
     docs(project(":annotation:annotation-experimental"))
     docs(project(":appactions:builtintypes:builtintypes"))
@@ -43,6 +44,7 @@
     docs(project(":arch:core:core-runtime"))
     docs(project(":arch:core:core-testing"))
     docs(project(":asynclayoutinflater:asynclayoutinflater"))
+    docs(project(":asynclayoutinflater:asynclayoutinflater-appcompat"))
     docs(project(":autofill:autofill"))
     docs(project(":benchmark:benchmark-benchmark"))
     docs(project(":benchmark:benchmark-common"))
@@ -61,8 +63,9 @@
     docs(project(":camera:camera-effects-still-portrait"))
     docs(project(":camera:camera-extensions"))
     stubs(fileTree(dir: "../camera/camera-extensions-stub", include: ["camera-extensions-stub.jar"]))
-    docs(project(":camera:camera-mlkit-vision"))
     docs(project(":camera:camera-lifecycle"))
+    docs(project(":camera:camera-mlkit-vision"))
+    // camera-previewview is not hosted in androidx
     docs(project(":camera:camera-video"))
     docs(project(":camera:camera-view"))
     docs(project(":camera:camera-viewfinder"))
@@ -75,58 +78,61 @@
     docs(project(":cardview:cardview"))
     kmpDocs(project(":collection:collection"))
     docs(project(":collection:collection-ktx"))
-    docs(project(":compose:animation:animation"))
-    docs(project(":compose:animation:animation-core"))
-    docs(project(":compose:animation:animation-graphics"))
+    kmpDocs(project(":compose:animation:animation"))
+    kmpDocs(project(":compose:animation:animation-core"))
+    kmpDocs(project(":compose:animation:animation-graphics"))
     samples(project(":compose:animation:animation-core:animation-core-samples"))
     samples(project(":compose:animation:animation:animation-samples"))
     samples(project(":compose:animation:animation-graphics:animation-graphics-samples"))
-    docs(project(":compose:foundation:foundation"))
-    docs(project(":compose:foundation:foundation-layout"))
+    kmpDocs(project(":compose:foundation:foundation"))
+    kmpDocs(project(":compose:foundation:foundation-layout"))
     samples(project(":compose:foundation:foundation-layout:foundation-layout-samples"))
     samples(project(":compose:foundation:foundation:foundation-samples"))
-    docs(project(":compose:material3:material3"))
-    docs(project(":compose:material3:material3-adaptive"))
+    kmpDocs(project(":compose:material3:material3"))
+    kmpDocs(project(":compose:material3:material3-adaptive"))
     samples(project(":compose:material3:material3:material3-samples"))
-    docs(project(":compose:material3:material3-window-size-class"))
+    kmpDocs(project(":compose:material3:material3-window-size-class"))
     samples(project(":compose:material3:material3-window-size-class:material3-window-size-class-samples"))
-    docs(project(":compose:material:material"))
-    docs(project(":compose:material:material-icons-core"))
+    kmpDocs(project(":compose:material:material"))
+    kmpDocs(project(":compose:material:material-icons-core"))
     samples(project(":compose:material:material-icons-core:material-icons-core-samples"))
-    docs(project(":compose:material:material-ripple"))
+    kmpDocs(project(":compose:material:material-ripple"))
     samples(project(":compose:material:material:material-samples"))
-    docs(project(":compose:runtime:runtime"))
+    kmpDocs(project(":compose:runtime:runtime"))
+    samples(project(":compose:runtime:runtime:runtime-samples"))
     docs(project(":compose:runtime:runtime-livedata"))
     samples(project(":compose:runtime:runtime-livedata:runtime-livedata-samples"))
     docs(project(":compose:runtime:runtime-rxjava2"))
     samples(project(":compose:runtime:runtime-rxjava2:runtime-rxjava2-samples"))
     docs(project(":compose:runtime:runtime-rxjava3"))
     samples(project(":compose:runtime:runtime-rxjava3:runtime-rxjava3-samples"))
-    docs(project(":compose:runtime:runtime-saveable"))
+    kmpDocs(project(":compose:runtime:runtime-saveable"))
     samples(project(":compose:runtime:runtime-saveable:runtime-saveable-samples"))
-    samples(project(":compose:runtime:runtime:runtime-samples"))
-    docs(project(":compose:ui:ui"))
+    docs(project(":compose:runtime:runtime-tracing"))
+    kmpDocs(project(":compose:ui:ui"))
     docs(project(":compose:ui:ui-android-stubs"))
-    docs(project(":compose:ui:ui-geometry"))
-    docs(project(":compose:ui:ui-graphics"))
+    kmpDocs(project(":compose:ui:ui-geometry"))
+    kmpDocs(project(":compose:ui:ui-graphics"))
     samples(project(":compose:ui:ui-graphics:ui-graphics-samples"))
-    docs(project(":compose:ui:ui-test"))
+    kmpDocs(project(":compose:ui:ui-test"))
     samples(project(":compose:ui:ui-test:ui-test-samples"))
-    docs(project(":compose:ui:ui-test-junit4"))
-    docs(project(":compose:ui:ui-text"))
+    kmpDocs(project(":compose:ui:ui-test-junit4"))
+    kmpDocs(project(":compose:ui:ui-text"))
     samples(project(":compose:ui:ui-text:ui-text-samples"))
-    docs(project(":compose:ui:ui-tooling"))
-    docs(project(":compose:ui:ui-tooling-data"))
-    docs(project(":compose:ui:ui-unit"))
+    docs(project(":compose:ui:ui-text-google-fonts"))
+    kmpDocs(project(":compose:ui:ui-tooling"))
+    kmpDocs(project(":compose:ui:ui-tooling-data"))
+    kmpDocs(project(":compose:ui:ui-tooling-preview"))
+    kmpDocs(project(":compose:ui:ui-unit"))
     samples(project(":compose:ui:ui-unit:ui-unit-samples"))
-    docs(project(":compose:ui:ui-util"))
+    kmpDocs(project(":compose:ui:ui-util"))
     docs(project(":compose:ui:ui-viewbinding"))
     samples(project(":compose:ui:ui-viewbinding:ui-viewbinding-samples"))
     samples(project(":compose:ui:ui:ui-samples"))
     docs(project(":concurrent:concurrent-futures"))
     docs(project(":concurrent:concurrent-futures-ktx"))
-    docs(project(":constraintlayout:constraintlayout-compose"))
     docs(project(":constraintlayout:constraintlayout"))
+    kmpDocs(project(":constraintlayout:constraintlayout-compose"))
     docs(project(":constraintlayout:constraintlayout-core"))
     docs(project(":contentpager:contentpager"))
     docs(project(":coordinatorlayout:coordinatorlayout"))
@@ -135,6 +141,8 @@
     docs(project(":core:core-animation-testing"))
     docs(project(":core:core-appdigest"))
     docs(project(":core:core-google-shortcuts"))
+    docs(project(":core:haptics:haptics"))
+    samples(project(":core:haptics:haptics-samples"))
     docs(project(":core:core-i18n"))
     docs(project(":core:core-ktx"))
     docs(project(":core:core-location-altitude"))
@@ -143,11 +151,10 @@
     docs(project(":core:core-performance-testing"))
     samples(project(":core:core-performance:core-performance-samples"))
     docs(project(":core:core-remoteviews"))
-    docs(project(":core:core-splashscreen"))
     docs(project(":core:core-role"))
+    docs(project(":core:core-splashscreen"))
+    docs(project(":core:core-telecom"))
     docs(project(":core:core-testing"))
-    docs(project(":core:haptics:haptics"))
-    samples(project(":core:haptics:haptics-samples"))
     docs(project(":core:uwb:uwb"))
     docs(project(":core:uwb:uwb-rxjava3"))
     docs(project(":credentials:credentials"))
@@ -156,10 +163,10 @@
     docs(project(":cursoradapter:cursoradapter"))
     docs(project(":customview:customview"))
     docs(project(":customview:customview-poolingcontainer"))
-    docs(project(":datastore:datastore"))
+    kmpDocs(project(":datastore:datastore"))
     kmpDocs(project(":datastore:datastore-core"))
     kmpDocs(project(":datastore:datastore-core-okio"))
-    docs(project(":datastore:datastore-preferences"))
+    kmpDocs(project(":datastore:datastore-preferences"))
     kmpDocs(project(":datastore:datastore-preferences-core"))
     docs(project(":datastore:datastore-preferences-proto"))
     docs(project(":datastore:datastore-preferences-rxjava2"))
@@ -172,12 +179,12 @@
     docs(project(":drawerlayout:drawerlayout"))
     docs(project(":dynamicanimation:dynamicanimation"))
     docs(project(":dynamicanimation:dynamicanimation-ktx"))
-    docs(project(":emoji2:emoji2-emojipicker"))
     docs(project(":emoji:emoji"))
     docs(project(":emoji:emoji-appcompat"))
     docs(project(":emoji:emoji-bundled"))
     docs(project(":emoji2:emoji2"))
     docs(project(":emoji2:emoji2-bundled"))
+    docs(project(":emoji2:emoji2-emojipicker"))
     docs(project(":emoji2:emoji2-views"))
     docs(project(":emoji2:emoji2-views-helper"))
     docs(project(":enterprise:enterprise-feedback"))
@@ -189,9 +196,14 @@
     docs(project(":glance:glance"))
     docs(project(":glance:glance-appwidget"))
     samples(project(":glance:glance-appwidget:glance-appwidget-samples"))
+    docs(project(":glance:glance-appwidget-preview"))
+    docs(project(":glance:glance-appwidget-proto"))
+    docs(project(":glance:glance-preview"))
     docs(project(":glance:glance-wear-tiles"))
+    docs(project(":glance:glance-wear-tiles-preview"))
     docs(project(":graphics:filters:filters"))
     docs(project(":graphics:graphics-core"))
+    docs(project(":graphics:graphics-path"))
     docs(project(":graphics:graphics-shapes"))
     docs(project(":gridlayout:gridlayout"))
     docs(project(":health:connect:connect-client"))
@@ -209,11 +221,13 @@
     docs(project(":javascriptengine:javascriptengine"))
     docs(project(":metrics:metrics-performance"))
     docs(project(":leanback:leanback"))
+    docs(project(":leanback:leanback-grid"))
     docs(project(":leanback:leanback-paging"))
     docs(project(":leanback:leanback-preference"))
     docs(project(":leanback:leanback-tab"))
     docs(project(":lifecycle:lifecycle-common"))
     docs(project(":lifecycle:lifecycle-common-java8"))
+    docs(project(":lifecycle:lifecycle-extensions"))
     docs(project(":lifecycle:lifecycle-livedata"))
     docs(project(":lifecycle:lifecycle-livedata-core"))
     docs(project(":lifecycle:lifecycle-livedata-core-ktx"))
@@ -234,14 +248,17 @@
     docs(project(":lifecycle:lifecycle-viewmodel-savedstate"))
     docs(project(":loader:loader"))
     docs(project(":loader:loader-ktx"))
+    // localbroadcastmanager is deprecated
     docs(project(":media2:media2-common"))
     docs(project(":media2:media2-exoplayer"))
     docs(project(":media2:media2-player"))
     docs(project(":media2:media2-session"))
     docs(project(":media2:media2-widget"))
     docs(project(":media:media"))
+    // androidx.media3 is not hosted in androidx
     docs(project(":mediarouter:mediarouter"))
     docs(project(":mediarouter:mediarouter-testing"))
+    docs(project(":metrics:metrics-performance"))
     docs(project(":navigation:navigation-common"))
     docs(project(":navigation:navigation-common-ktx"))
     docs(project(":navigation:navigation-compose"))
@@ -280,6 +297,7 @@
     docs(project(":privacysandbox:tools:tools"))
     docs(project(":privacysandbox:tools:tools-apicompiler"))
     docs(project(":privacysandbox:tools:tools-apigenerator"))
+    docs(project(":privacysandbox:tools:tools-apipackager"))
     docs(project(":privacysandbox:tools:tools-core"))
     docs(project(":privacysandbox:ui:ui-client"))
     docs(project(":privacysandbox:ui:ui-core"))
@@ -290,6 +308,7 @@
     docs(project(":recyclerview:recyclerview-selection"))
     docs(project(":remotecallback:remotecallback"))
     docs(project(":resourceinspection:resourceinspection-annotation"))
+    docs(project(":resourceinspection:resourceinspection-processor"))
     docs(project(":room:room-common"))
     docs(project(":room:room-guava"))
     docs(project(":room:room-ktx"))
@@ -324,9 +343,13 @@
     docs(project(":sqlite:sqlite-ktx"))
     docs(project(":startup:startup-runtime"))
     docs(project(":swiperefreshlayout:swiperefreshlayout"))
+    // androidx.test is not hosted in androidx
     docs(project(":test:uiautomator:uiautomator"))
+    // androidx.textclassifier is not hosted in androidx
     docs(project(":tracing:tracing"))
     docs(project(":tracing:tracing-ktx"))
+    docs(project(":tracing:tracing-perfetto"))
+    docs(project(":tracing:tracing-perfetto-handshake"))
     docs(project(":transition:transition"))
     docs(project(":transition:transition-ktx"))
     docs(project(":tv:tv-foundation"))
@@ -339,56 +362,60 @@
     docs(project(":versionedparcelable:versionedparcelable"))
     docs(project(":viewpager2:viewpager2"))
     docs(project(":viewpager:viewpager"))
+    docs(project(":wear:compose:compose-foundation"))
+    samples(project(":wear:compose:compose-foundation-samples"))
+    docs(project(":wear:compose:compose-material"))
+    docs(project(":wear:compose:compose-material-core"))
+    samples(project(":wear:compose:compose-material-samples"))
+    docs(project(":wear:compose:compose-material3"))
+    samples(project(":wear:compose:compose-material3-samples"))
+    docs(project(":wear:compose:compose-navigation"))
+    samples(project(":wear:compose:compose-navigation-samples"))
+    docs(project(":wear:compose:compose-ui-tooling"))
     docs(project(":wear:protolayout:protolayout"))
     docs(project(":wear:protolayout:protolayout-expression"))
     docs(project(":wear:protolayout:protolayout-expression-pipeline"))
     docs(project(":wear:protolayout:protolayout-material"))
     docs(project(":wear:protolayout:protolayout-renderer"))
-    docs(project(":wear:wear"))
-    stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
-    docs(project(":wear:compose:compose-foundation"))
-    samples(project(":wear:compose:compose-foundation-samples"))
-    docs(project(":wear:compose:compose-material"))
-    samples(project(":wear:compose:compose-material-samples"))
-    docs(project(":wear:compose:compose-navigation"))
-    samples(project(":wear:compose:compose-navigation-samples"))
-    docs(project(":wear:compose:compose-ui-tooling"))
-    docs(project(":wear:wear-input"))
-    docs(project(":wear:wear-input-testing"))
-    samples(project(":wear:wear-input-samples"))
-    docs(project(":wear:wear-ongoing"))
-    docs(project(":wear:wear-phone-interactions"))
-    docs(project(":wear:wear-remote-interactions"))
     docs(project(":wear:tiles:tiles"))
     docs(project(":wear:tiles:tiles-material"))
     docs(project(":wear:tiles:tiles-proto"))
     docs(project(":wear:tiles:tiles-renderer"))
     docs(project(":wear:tiles:tiles-testing"))
+    docs(project(":wear:tiles:tiles-tooling"))
     docs(project(":wear:watchface:watchface"))
+    docs(project(":wear:watchface:watchface-client"))
+    docs(project(":wear:watchface:watchface-client-guava"))
     docs(project(":wear:watchface:watchface-complications"))
     docs(project(":wear:watchface:watchface-complications-data"))
     docs(project(":wear:watchface:watchface-complications-data-source"))
-    samples(project(":wear:watchface:watchface-complications-data-source-samples"))
+    docs(project(":wear:watchface:watchface-complications-data-source-ktx"))
     docs(project(":wear:watchface:watchface-complications-rendering"))
-    docs(project(":wear:watchface:watchface-client"))
-    docs(project(":wear:watchface:watchface-client-guava"))
     docs(project(":wear:watchface:watchface-data"))
     docs(project(":wear:watchface:watchface-editor"))
     docs(project(":wear:watchface:watchface-editor-guava"))
-    docs(project(":wear:watchface:watchface-editor-samples"))
     docs(project(":wear:watchface:watchface-guava"))
     samples(project(":wear:watchface:watchface-samples"))
     docs(project(":wear:watchface:watchface-style"))
+    docs(project(":wear:wear"))
+    stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
+    docs(project(":wear:wear-input"))
+    samples(project(":wear:wear-input-samples"))
+    docs(project(":wear:wear-input-testing"))
+    docs(project(":wear:wear-ongoing"))
+    docs(project(":wear:wear-phone-interactions"))
+    docs(project(":wear:wear-remote-interactions"))
     docs(project(":webkit:webkit"))
     docs(project(":window:window"))
+    stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release.aar"]))
+    stubs(project(":window:extensions:core:core"))
+    stubs(project(":window:extensions:extensions"))
+    stubs(project(":window:sidecar:sidecar"))
     docs(project(":window:window-core"))
     docs(project(":window:window-java"))
     docs(project(":window:window-rxjava2"))
     docs(project(":window:window-rxjava3"))
-    stubs(project(":window:sidecar:sidecar"))
     samples(project(":window:window-samples"))
-    stubs(project(":window:extensions:extensions"))
-    stubs(project(":window:extensions:core:core"))
     docs(project(":window:window-testing"))
     docs(project(":work:work-gcm"))
     docs(project(":work:work-multiprocess"))
diff --git a/docs/api_guidelines/misc.md b/docs/api_guidelines/misc.md
index a2930e6..f1a6e7f 100644
--- a/docs/api_guidelines/misc.md
+++ b/docs/api_guidelines/misc.md
@@ -834,3 +834,48 @@
 ```
 <project>/src/main/resources/META-INF/proguard/androidx.core_core.pro
 ```
+
+### Conditional Proguard Rules
+
+Libraries are strongly encouraged to minimize the number of classes that are
+kept as part of keep rules. More specifically, library authors are expected to
+identify the entry points of their library that call into code paths that may
+require classes to be exempt from proguard rules. This may be due to internal
+reflection usages or JNI code. In the case of JNI code, java/kotlin classes and
+methods that are implemented in native must be exempt in order to avoid JNI
+linking errors in libraries that are consumed by applications built with
+proguard enabled.
+
+A common pattern is to create an annotation class that is used to annotate all
+classes and methods that are to be excluded from proguard obfuscation.
+
+For example:
+
+```
+/// in MyProguardExceptionAnnotation.kt
+internal annotation class MyProguardExemptionAnnotation
+```
+
+Then reference this annotation within your proguard config conditionally
+whenever the public API is consumed that leverages facilities that need to be
+excluded from proguard optimization.
+
+```
+# in proguard-rules.pro
+# The following keeps classes annotated with MyProguardExemptionAnnotation
+# defined above
+-if class androidx.mylibrary.MyPublicApi
+-keep @androidx.mylibrary.MyProguardExemptionAnnotation public class *
+
+# The following keeps methods annotated with MyProguardExcemptionAnnotation
+-if class androidx.mylibrary.MyPublicApi
+-keepclasseswithmembers class * {
+    @androidx.mylibrary.MyProguardExcemptionAnnotation *;
+}
+```
+
+Note that for each public API entry point an additional proguard rule would need
+to be introduced in the corresponding proguard-rules.pro. This is because as of
+writing there is no "or" operator within proguard that can be used to include
+the keep rules for multiple conditions. So each rule would need to be
+copy/pasted for each public API entrypoint.
diff --git a/docs/onboarding.md b/docs/onboarding.md
index feb4b7d..2069d45 100644
--- a/docs/onboarding.md
+++ b/docs/onboarding.md
@@ -524,7 +524,7 @@
 `{androidx-main-checkout}/prebuilts/androidx/internal/androidx/`. We
 colloquially refer to this two step process of (1) updating `docs-public` and
 (2) checking in a prebuilt artifact into the prebuilts directory as
-[The Prebuilts Dance](/company/teams/androidx/releasing_detailed.md#the-prebuilts-dance™).
+[The Prebuilts Dance](/company/teams/androidx/releasing_prebuilts_dance.md#the-prebuilts-dance™).
 So, to build javadocs that will be published to
 https://developer.android.com/reference/androidx/packages, both of these steps
 need to be completed.
diff --git a/drawerlayout/drawerlayout/api/api_lint.ignore b/drawerlayout/drawerlayout/api/api_lint.ignore
index be4e831..69b398e 100644
--- a/drawerlayout/drawerlayout/api/api_lint.ignore
+++ b/drawerlayout/drawerlayout/api/api_lint.ignore
@@ -3,12 +3,6 @@
     Parameter type is concrete collection (`java.util.ArrayList`); must be higher-level interface
 
 
-InvalidNullabilityOverride: androidx.drawerlayout.widget.DrawerLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
-    Invalid nullability on parameter `canvas` in method `drawChild`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.drawerlayout.widget.DrawerLayout#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-
-
 ListenerInterface: androidx.drawerlayout.widget.DrawerLayout.SimpleDrawerListener:
     Listeners should be an interface, or otherwise renamed Callback: SimpleDrawerListener
 
@@ -23,6 +17,8 @@
     Missing nullability on parameter `p` in method `checkLayoutParams`
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#dispatchGenericMotionEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `event` in method `dispatchGenericMotionEvent`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
     Missing nullability on parameter `child` in method `drawChild`
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateDefaultLayoutParams():
@@ -35,6 +31,8 @@
     Missing nullability on method `generateLayoutParams` return
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
     Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
 MissingNullability: androidx.drawerlayout.widget.DrawerLayout#onKeyDown(int, android.view.KeyEvent) parameter #1:
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/PopupViewHelper.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/PopupViewHelper.kt
index b1e7b2f..e000eb32 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/PopupViewHelper.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/PopupViewHelper.kt
@@ -159,9 +159,9 @@
     private val radius = resources.getDimension(R.dimen.emoji_picker_skin_tone_circle_radius)
     var paint: Paint? = null
 
-    override fun draw(canvas: Canvas?) {
+    override fun draw(canvas: Canvas) {
         super.draw(canvas)
-        canvas?.apply {
+        canvas.apply {
             paint?.let { drawCircle(width / 2f, height / 2f, radius, it) }
         }
     }
diff --git a/fragment/CHANGELOG.md b/fragment/CHANGELOG.md
index b14a2c3..16f1431 100644
--- a/fragment/CHANGELOG.md
+++ b/fragment/CHANGELOG.md
@@ -22,6 +22,16 @@
   This would cause that cached state to be reused if that fragment instance was on the back stack
   when using the multiple back stacks API to save and restore that fragment.
 
+### New Features
+
+* Fragments now provide support for Predictive back when using
+  Animators. This allows you to use the back gesture motion to seek to the
+  previous fragment with your custom Animator before deciding to either
+  commit or cancel the transaction via the completed gesture.
+
+
+# 1.6.0-rc01
+
 ### Dependency Updates
 
 - Changed dependency of Activity library from version 1.5.1 to version 1.7.1.
diff --git a/fragment/fragment-ktx/build.gradle b/fragment/fragment-ktx/build.gradle
index 7327886..ad0cc6e 100644
--- a/fragment/fragment-ktx/build.gradle
+++ b/fragment/fragment-ktx/build.gradle
@@ -25,7 +25,7 @@
 
 dependencies {
     api(project(":fragment:fragment"))
-    api("androidx.activity:activity-ktx:1.7.1") {
+    api(project(":activity:activity-ktx")) {
         because "Mirror fragment dependency graph for -ktx artifacts"
     }
     api("androidx.core:core-ktx:1.2.0") {
diff --git a/fragment/fragment/api/current.txt b/fragment/fragment/api/current.txt
index 553ab8a..deedda9 100644
--- a/fragment/fragment/api/current.txt
+++ b/fragment/fragment/api/current.txt
@@ -278,6 +278,7 @@
     method public final void clearFragmentResultListener(String);
     method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
     method @Deprecated public static void enableDebugLogging(boolean);
+    method @androidx.fragment.app.PredictiveBackControl public static void enablePredictiveBack(boolean);
     method @MainThread public boolean executePendingTransactions();
     method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
     method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
@@ -456,6 +457,9 @@
     method public void setSelection(int);
   }
 
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface PredictiveBackControl {
+  }
+
 }
 
 package androidx.fragment.app.strictmode {
diff --git a/fragment/fragment/api/restricted_current.txt b/fragment/fragment/api/restricted_current.txt
index aed956b..7baefa7 100644
--- a/fragment/fragment/api/restricted_current.txt
+++ b/fragment/fragment/api/restricted_current.txt
@@ -282,6 +282,7 @@
     method public final void clearFragmentResultListener(String);
     method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
     method @Deprecated public static void enableDebugLogging(boolean);
+    method @androidx.fragment.app.PredictiveBackControl public static void enablePredictiveBack(boolean);
     method @MainThread public boolean executePendingTransactions();
     method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
     method public androidx.fragment.app.Fragment? findFragmentById(@IdRes int);
@@ -485,6 +486,9 @@
     method public void setSelection(int);
   }
 
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface PredictiveBackControl {
+  }
+
 }
 
 package androidx.fragment.app.strictmode {
diff --git a/fragment/fragment/build.gradle b/fragment/fragment/build.gradle
index e2863b8..b16457b 100644
--- a/fragment/fragment/build.gradle
+++ b/fragment/fragment/build.gradle
@@ -29,7 +29,7 @@
     api("androidx.collection:collection:1.1.0")
     api("androidx.viewpager:viewpager:1.0.0")
     api("androidx.loader:loader:1.0.0")
-    api("androidx.activity:activity:1.7.1")
+    api(project(":activity:activity"))
     api("androidx.lifecycle:lifecycle-runtime:2.6.1")
     api("androidx.lifecycle:lifecycle-livedata-core:2.6.1")
     api("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/OnBackStackChangedListenerTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/OnBackStackChangedListenerTest.kt
index f331268..370fad4 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/OnBackStackChangedListenerTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/OnBackStackChangedListenerTest.kt
@@ -16,12 +16,16 @@
 
 package androidx.fragment.app
 
+import android.os.Build
+import androidx.activity.BackEventCompat
+import androidx.annotation.RequiresApi
 import androidx.fragment.app.FragmentManager.OnBackStackChangedListener
 import androidx.fragment.app.test.FragmentTestActivity
 import androidx.fragment.test.R
 import androidx.test.core.app.ActivityScenario
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
 import androidx.testutils.withActivity
 import com.google.common.truth.Truth.assertThat
 import leakcanary.DetectLeaksAfterTestSuccess
@@ -445,4 +449,128 @@
             assertThat(committedCount).isEqualTo(1)
         }
     }
+
+    @RequiresApi(34)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testBackStackHandledOnBackChange() {
+        with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
+            val fragmentManager = withActivity { supportFragmentManager }
+
+            val fragment = StrictFragment()
+            val fragment2 = StrictFragment()
+            var startedCount = 0
+            var committedCount = 0
+
+            withActivity {
+                fragmentManager.beginTransaction()
+                    .setReorderingAllowed(true)
+                    .add(R.id.content, fragment)
+                    .addToBackStack(null)
+                    .commit()
+                executePendingTransactions()
+            }
+
+            withActivity {
+                fragmentManager.beginTransaction()
+                    .setReorderingAllowed(true)
+                    .add(R.id.content, fragment2)
+                    .addToBackStack(null)
+                    .commit()
+                executePendingTransactions()
+            }
+
+            val listener = object : OnBackStackChangedListener {
+                override fun onBackStackChanged() { /* nothing */ }
+
+                override fun onBackStackChangeStarted(fragment: Fragment, pop: Boolean) {
+                    startedCount++
+                }
+
+                override fun onBackStackChangeCommitted(fragment: Fragment, pop: Boolean) {
+                    committedCount++
+                }
+            }
+            fragmentManager.addOnBackStackChangedListener(listener)
+
+            withActivity {
+                onBackPressedDispatcher.dispatchOnBackStarted(BackEventCompat(0f, 0f, 0f, 0))
+                executePendingTransactions()
+            }
+
+            assertThat(startedCount).isEqualTo(1)
+            assertThat(committedCount).isEqualTo(0)
+
+            withActivity {
+                onBackPressedDispatcher.onBackPressed()
+            }
+
+            assertThat(startedCount).isEqualTo(1)
+            assertThat(committedCount).isEqualTo(1)
+
+            assertThat(fragment).isSameInstanceAs(fragmentManager.findFragmentById(R.id.content))
+        }
+    }
+
+    @RequiresApi(34)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testBackStackCancelledOnBackChange() {
+        with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
+            val fragmentManager = withActivity { supportFragmentManager }
+
+            val fragment = StrictFragment()
+            val fragment2 = StrictFragment()
+            var startedCount = 0
+            var committedCount = 0
+
+            withActivity {
+                fragmentManager.beginTransaction()
+                    .setReorderingAllowed(true)
+                    .add(R.id.content, fragment)
+                    .addToBackStack(null)
+                    .commit()
+                executePendingTransactions()
+            }
+
+            withActivity {
+                fragmentManager.beginTransaction()
+                    .setReorderingAllowed(true)
+                    .add(R.id.content, fragment2)
+                    .addToBackStack(null)
+                    .commit()
+                executePendingTransactions()
+            }
+
+            val listener = object : OnBackStackChangedListener {
+                override fun onBackStackChanged() { /* nothing */ }
+
+                override fun onBackStackChangeStarted(fragment: Fragment, pop: Boolean) {
+                    startedCount++
+                }
+
+                override fun onBackStackChangeCommitted(fragment: Fragment, pop: Boolean) {
+                    committedCount++
+                }
+            }
+            fragmentManager.addOnBackStackChangedListener(listener)
+
+            withActivity {
+                onBackPressedDispatcher.dispatchOnBackStarted(BackEventCompat(0f, 0f, 0f, 0))
+                executePendingTransactions()
+            }
+
+            assertThat(startedCount).isEqualTo(1)
+            assertThat(committedCount).isEqualTo(0)
+
+            withActivity {
+                onBackPressedDispatcher.dispatchOnBackCancelled()
+            }
+
+            assertThat(startedCount).isEqualTo(1)
+            assertThat(committedCount).isEqualTo(0)
+
+            assertThat(fragment2).isSameInstanceAs(fragmentManager.findFragmentById(R.id.content))
+        }
+    }
 }
\ No newline at end of file
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/DefaultSpecialEffectsController.kt b/fragment/fragment/src/main/java/androidx/fragment/app/DefaultSpecialEffectsController.kt
index 0fcc195..15a7b33 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/DefaultSpecialEffectsController.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/DefaultSpecialEffectsController.kt
@@ -17,12 +17,17 @@
 
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
+import android.annotation.SuppressLint
 import android.content.Context
 import android.graphics.Rect
+import android.os.Build
 import android.util.Log
 import android.view.View
 import android.view.ViewGroup
 import android.view.animation.Animation
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
 import androidx.collection.ArrayMap
 import androidx.core.os.CancellationSignal
 import androidx.core.view.OneShotPreDrawListener
@@ -127,6 +132,7 @@
         }
     }
 
+    @SuppressLint("NewApi", "PrereleaseSdkCoreDependency")
     private fun startAnimations(
         animationInfos: List<AnimationInfo>,
         awaitingContainerChanges: MutableList<Operation>,
@@ -198,7 +204,26 @@
                 }
             })
             animator.setTarget(viewToAnimate)
-            animator.start()
+            if (Build.VERSION.SDK_INT >= 34 && operation.fragment.mTransitioning) {
+                val animatorSet = animationInfo.getAnimation(container.context)?.animator
+                operation.addBackProgressCallbacks({ backEvent ->
+                    if (animatorSet != null) {
+                        val totalDuration = Api24Impl.totalDuration(animatorSet)
+                        var time = (backEvent.progress * totalDuration).toLong()
+                        // We cannot let the time get to 0 or the totalDuration to avoid
+                        // completing the operation accidentally.
+                        if (time == 0L) {
+                            time = 1L
+                        }
+                        if (time == totalDuration) {
+                            time = totalDuration - 1
+                        }
+                        Api26Impl.setCurrentPlayTime(animatorSet, time)
+                    }
+                }) { animatorSet?.start() }
+            } else {
+                animator.start()
+            }
             if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
                 Log.v(FragmentManager.TAG,
                     "Animator from operation $operation has started.")
@@ -206,10 +231,19 @@
             // Listen for cancellation and use that to cancel the Animator
             val signal: CancellationSignal = animationInfo.signal
             signal.setOnCancelListener {
-                animator.end()
+                if (operation.isSeeking) {
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                        Api26Impl.reverse(animator)
+                    }
+                } else {
+                    animator.end()
+                }
                 if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
-                    Log.v(FragmentManager.TAG,
-                        "Animator from operation $operation has been canceled.")
+                    Log.v(
+                        FragmentManager.TAG,
+                        "Animator from operation $operation has been canceled" +
+                            "${if (operation.isSeeking) " with seeking." else "."} "
+                    )
                 }
             }
         }
@@ -874,4 +908,25 @@
             )
         }
     }
+
+    @RequiresApi(24)
+    internal object Api24Impl {
+        @DoNotInline
+        fun totalDuration(animatorSet: AnimatorSet): Long {
+            return animatorSet.totalDuration
+        }
+    }
+
+    @RequiresApi(26)
+    internal object Api26Impl {
+        @DoNotInline
+        fun reverse(animatorSet: AnimatorSet) {
+            animatorSet.reverse()
+        }
+
+        @DoNotInline
+        fun setCurrentPlayTime(animatorSet: AnimatorSet, time: Long) {
+            animatorSet.currentPlayTime = time
+        }
+    }
 }
\ No newline at end of file
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
index 53224f7..0718eba 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
@@ -175,6 +175,9 @@
     // If set this fragment is being removed from its activity.
     boolean mRemoving;
 
+    // If set this fragment is transitioning via a back gesture
+    boolean mTransitioning;
+
     boolean mBeingSaved;
 
     // Set to true if this fragment was instantiated from a layout file.
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
index 3e841c8..c81a09d 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -43,6 +43,7 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 
+import androidx.activity.BackEventCompat;
 import androidx.activity.OnBackPressedCallback;
 import androidx.activity.OnBackPressedDispatcher;
 import androidx.activity.OnBackPressedDispatcherOwner;
@@ -115,6 +116,23 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     public static final String TAG = "FragmentManager";
 
+    static boolean USE_PREDICTIVE_BACK = true;
+
+    /**
+     * Control whether FragmentManager uses the new state predictive back feature that allows
+     * seeing the previous Fragment when using gesture back.
+     * <p>
+     * This should only be changed <strong>before</strong> any fragment transactions are done
+     * (i.e., in your <code>Application</code> class or prior to <code>super.onCreate()</code>
+     * in every activity).
+     *
+     * @param enabled Whether predictive back should be enabled.
+     */
+    @PredictiveBackControl
+    public static void enablePredictiveBack(boolean enabled) {
+        FragmentManager.USE_PREDICTIVE_BACK = enabled;
+    }
+
     /**
      * Control whether the framework's internal fragment manager debugging
      * logs are turned on.  If enabled, you will see output in logcat as
@@ -440,12 +458,48 @@
     private final FragmentLayoutInflaterFactory mLayoutInflaterFactory =
             new FragmentLayoutInflaterFactory(this);
     private OnBackPressedDispatcher mOnBackPressedDispatcher;
+
+    BackStackRecord mTransitioningOp = null;
+
+    boolean mBackStarted = false;
     private final OnBackPressedCallback mOnBackPressedCallback =
             new OnBackPressedCallback(false) {
+
+                @Override
+                public void handleOnBackStarted(@NonNull BackEventCompat backEvent) {
+                    if (USE_PREDICTIVE_BACK) {
+                        prepareBackStackTransition();
+                    }
+                }
+
+                @Override
+                public void handleOnBackProgressed(@NonNull BackEventCompat backEvent) {
+                    if (mTransitioningOp != null) {
+                        // Collect the correct SpecialEffectsControllers and pass in the progress
+                        Set<SpecialEffectsController> changedControllers  =
+                                collectChangedControllers(
+                                        new ArrayList<>(
+                                                Collections.singletonList(mTransitioningOp)
+                                        ), 0, 1
+                                );
+                        for (SpecialEffectsController controller: changedControllers) {
+                            controller.processProgress(backEvent);
+                        }
+                    }
+                }
+
                 @Override
                 public void handleOnBackPressed() {
                     FragmentManager.this.handleOnBackPressed();
                 }
+
+                @Override
+                public void handleOnBackCancelled() {
+                    if (USE_PREDICTIVE_BACK) {
+                        cancelBackStackTransition();
+                        mTransitioningOp = null;
+                    }
+                }
             };
 
     private final AtomicInteger mBackStackIndex = new AtomicInteger();
@@ -458,7 +512,7 @@
     private final Map<String, LifecycleAwareResultListener> mResultListeners =
             Collections.synchronizedMap(new HashMap<String, LifecycleAwareResultListener>());
 
-    private ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
+    ArrayList<OnBackStackChangedListener> mBackStackChangeListeners;
     private final FragmentLifecycleCallbacksDispatcher mLifecycleCallbacksDispatcher =
             new FragmentLifecycleCallbacksDispatcher(this);
     private final CopyOnWriteArrayList<FragmentOnAttachListener> mOnAttachListeners =
@@ -707,22 +761,49 @@
 
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     void handleOnBackPressed() {
-        // First, execute any pending actions to make sure we're in an
-        // up to date view of the world just in case anyone is queuing
-        // up transactions that change the back stack then immediately
-        // calling onBackPressed()
-        execPendingActions(true);
-        if (mOnBackPressedCallback.isEnabled()) {
-            // We still have a back stack, so we can pop
-            popBackStackImmediate();
+        if (USE_PREDICTIVE_BACK && mTransitioningOp != null) {
+            if (mBackStackChangeListeners != null && !mBackStackChangeListeners.isEmpty()) {
+                // Build a list of fragments based on the records
+                Set<Fragment> fragments = new LinkedHashSet<>(
+                        fragmentsFromRecord(mTransitioningOp));
+                // Dispatch to all of the fragments in the list
+                for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
+                    // We give all fragment the back stack changed started signal first
+                    for (Fragment fragment : fragments) {
+                        listener.onBackStackChangeCommitted(fragment, true);
+                    }
+                }
+            }
+            for (FragmentTransaction.Op op : mTransitioningOp.mOps) {
+                if (op.mFragment != null) {
+                    op.mFragment.mTransitioning = false;
+                }
+            }
+            Set<SpecialEffectsController> changedControllers = collectChangedControllers(
+                    new ArrayList<>(Collections.singletonList(mTransitioningOp)), 0, 1
+            );
+            for (SpecialEffectsController controller : changedControllers) {
+                controller.completeBack();
+            }
+            mTransitioningOp = null;
         } else {
-            // Sigh. Due to FragmentManager's asynchronicity, we can
-            // get into cases where we *think* we can handle the back
-            // button but because of frame perfect dispatch, we fell
-            // on our face. Since our callback is disabled, we can
-            // re-trigger the onBackPressed() to dispatch to the next
-            // enabled callback
-            mOnBackPressedDispatcher.onBackPressed();
+            // First, execute any pending actions to make sure we're in an
+            // up to date view of the world just in case anyone is queuing
+            // up transactions that change the back stack then immediately
+            // calling onBackPressed()
+            execPendingActions(true);
+            if (mOnBackPressedCallback.isEnabled()) {
+                // We still have a back stack, so we can pop
+                popBackStackImmediate();
+            } else {
+                // Sigh. Due to FragmentManager's asynchronicity, we can
+                // get into cases where we *think* we can handle the back
+                // button but because of frame perfect dispatch, we fell
+                // on our face. Since our callback is disabled, we can
+                // re-trigger the onBackPressed() to dispatch to the next
+                // enabled callback
+                mOnBackPressedDispatcher.onBackPressed();
+            }
         }
     }
 
@@ -850,6 +931,18 @@
         enqueueAction(new PopBackStackState(null, id, flags), allowStateLoss);
     }
 
+    void prepareBackStackTransition() {
+        enqueueAction(new PrepareBackStackTransitionState(), false);
+    }
+
+    void cancelBackStackTransition() {
+        if (mTransitioningOp != null) {
+            mTransitioningOp.mCommitted = false;
+            mTransitioningOp.commit();
+            executePendingTransactions();
+        }
+    }
+
     /**
      * Like {@link #popBackStack(int, int)}, but performs the operation immediately
      * inside of the call.  This is like calling {@link #executePendingTransactions()}
@@ -1905,17 +1998,19 @@
             for (BackStackRecord record : records) {
                 fragments.addAll(fragmentsFromRecord(record));
             }
-            // Dispatch to all of the fragments in the list
-            for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
-                // We give all fragment the back stack changed started signal first
-                for (Fragment fragment: fragments) {
-                    listener.onBackStackChangeStarted(fragment, isPop);
+            if (mTransitioningOp == null) {
+                // Dispatch to all of the fragments in the list
+                for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
+                    // We give all fragment the back stack changed started signal first
+                    for (Fragment fragment : fragments) {
+                        listener.onBackStackChangeStarted(fragment, isPop);
+                    }
                 }
-            }
-            for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
-                // Then we give them all the committed signal
-                for (Fragment fragment: fragments) {
-                    listener.onBackStackChangeCommitted(fragment, isPop);
+                for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
+                    // Then we give them all the committed signal
+                    for (Fragment fragment : fragments) {
+                        listener.onBackStackChangeCommitted(fragment, isPop);
+                    }
                 }
             }
         }
@@ -1969,7 +2064,7 @@
         }
     }
 
-    private Set<SpecialEffectsController> collectChangedControllers(
+    Set<SpecialEffectsController> collectChangedControllers(
             @NonNull ArrayList<BackStackRecord> records, int startIndex, int endIndex) {
         Set<SpecialEffectsController> controllers = new HashSet<>();
         for (int index = startIndex; index < endIndex; index++) {
@@ -2135,7 +2230,7 @@
         }
     }
 
-    private Set<Fragment> fragmentsFromRecord(@NonNull BackStackRecord record) {
+    Set<Fragment> fragmentsFromRecord(@NonNull BackStackRecord record) {
         Set<Fragment> fragments = new HashSet<>();
         for (int i = 0; i < record.mOps.size(); i++) {
             Fragment f = record.mOps.get(i).mFragment;
@@ -2330,6 +2425,19 @@
         return true;
     }
 
+    boolean prepareBackStackState(@NonNull ArrayList<BackStackRecord> records,
+            @NonNull ArrayList<Boolean> isRecordPop) {
+        // The transitioning record is the last one on the back stack.
+        mTransitioningOp = mBackStack.get(mBackStack.size() - 1);
+        // Mark all fragments in the record as transitioning
+        for (FragmentTransaction.Op op: mTransitioningOp.mOps) {
+            if (op.mFragment != null) {
+                op.mFragment.mTransitioning = true;
+            }
+        }
+        return popBackStackState(records, isRecordPop, null, -1, 0);
+    }
+
     /**
      * Find the index in the back stack associated with the given name / id.
      * <p>
@@ -3567,6 +3675,35 @@
         }
     }
 
+    class PrepareBackStackTransitionState implements OpGenerator {
+
+        @Override
+        public boolean generateOps(@NonNull ArrayList<BackStackRecord> records,
+                @NonNull ArrayList<Boolean> isRecordPop) {
+            boolean result = prepareBackStackState(records, isRecordPop);
+            mBackStarted = true;
+            // Dispatch started signal to onBackStackChangedListeners.
+            if (mBackStackChangeListeners != null && !mBackStackChangeListeners.isEmpty()) {
+                if (records.size() > 0) {
+                    boolean isPop = isRecordPop.get(records.size() - 1);
+                    Set<Fragment> fragments = new LinkedHashSet<>();
+                    // Build a list of fragments based on the records
+                    for (BackStackRecord record : records) {
+                        fragments.addAll(fragmentsFromRecord(record));
+                    }
+                    // Dispatch to all of the fragments in the list
+                    for (OnBackStackChangedListener listener : mBackStackChangeListeners) {
+                        // We give all fragment the back stack changed started signal first
+                        for (Fragment fragment : fragments) {
+                            listener.onBackStackChangeStarted(fragment, isPop);
+                        }
+                    }
+                }
+            }
+            return result;
+        }
+    }
+
     @SuppressLint("BanParcelableUsage")
     static class LaunchedFragmentInfo implements Parcelable {
         String mWho;
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
index 68154fb..4d7fd71 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
@@ -236,6 +236,11 @@
         if (mFragment.mDeferStart && mFragment.mState < Fragment.STARTED) {
             maxState = Math.min(maxState, Fragment.ACTIVITY_CREATED);
         }
+        // Fragments that are transitioning are part of a seeking effect and must be at least
+        // AWAITING_EXIT_EFFECTS
+        if (mFragment.mTransitioning) {
+            maxState = Math.max(maxState, Fragment.AWAITING_EXIT_EFFECTS);
+        }
         if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
             Log.v(FragmentManager.TAG, "computeExpectedState() of " + maxState + " for "
                     + mFragment);
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/PredictiveBackControl.kt b/fragment/fragment/src/main/java/androidx/fragment/app/PredictiveBackControl.kt
new file mode 100644
index 0000000..81a1209
--- /dev/null
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/PredictiveBackControl.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.fragment.app
+
+/**
+ * @see FragmentManager.enablePredictiveBack
+ */
+@Retention(AnnotationRetention.BINARY)
+@Target(AnnotationTarget.FUNCTION)
+@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
+annotation class PredictiveBackControl
\ No newline at end of file
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/SpecialEffectsController.kt b/fragment/fragment/src/main/java/androidx/fragment/app/SpecialEffectsController.kt
index 75b52ea..cce0ff4 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/SpecialEffectsController.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/SpecialEffectsController.kt
@@ -18,6 +18,7 @@
 import android.util.Log
 import android.view.View
 import android.view.ViewGroup
+import androidx.activity.BackEventCompat
 import androidx.annotation.CallSuper
 import androidx.core.os.CancellationSignal
 import androidx.core.view.ViewCompat
@@ -131,6 +132,13 @@
         synchronized(pendingOperations) {
             val signal = CancellationSignal()
             val existingOperation = findPendingOperation(fragmentStateManager.fragment)
+                // Get the running operation if the fragment is current transitioning as that means
+                // we can reverse the effect via the merge if needed.
+                ?: if (fragmentStateManager.fragment.mTransitioning) {
+                    findRunningOperation(fragmentStateManager.fragment)
+                } else {
+                    null
+                }
             if (existingOperation != null) {
                 // Update the existing operation by merging in the new information
                 // rather than creating a new Operation entirely
@@ -211,7 +219,8 @@
                             "SpecialEffectsController: Cancelling operation $operation"
                         )
                     }
-                    operation.cancel()
+                    // Cancel with seeking if the fragment is transitioning
+                    operation.cancel(operation.fragment.mTransitioning)
                     if (!operation.isComplete) {
                         // Re-add any animations that didn't synchronously call complete()
                         // to continue to track them as running operations
@@ -220,6 +229,9 @@
                 }
                 updateFinalState()
                 val newPendingOperations = pendingOperations.toMutableList()
+                if (newPendingOperations.isEmpty()) {
+                    return
+                }
                 pendingOperations.clear()
                 runningOperations.addAll(newPendingOperations)
                 if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
@@ -333,6 +345,18 @@
         isPop: Boolean
     )
 
+    fun processProgress(backEvent: BackEventCompat) {
+        runningOperations.forEach { operation ->
+            operation.backInProgressListener?.invoke(backEvent)
+        }
+    }
+
+    fun completeBack() {
+        runningOperations.forEach { operation ->
+            operation.backOnCompleteListener?.invoke()
+        }
+    }
+
     /**
      * Class representing an ongoing special effects operation.
      *
@@ -480,10 +504,16 @@
 
         private val completionListeners = mutableListOf<Runnable>()
         private val specialEffectsSignals = mutableSetOf<CancellationSignal>()
+        var backInProgressListener: ((BackEventCompat) -> Unit)? = null
+            private set
+        var backOnCompleteListener: (() -> Unit)? = null
+            private set
         var isCanceled = false
             private set
         var isComplete = false
             private set
+        var isSeeking = false
+            private set
 
         var isStarted = false
             private set
@@ -517,6 +547,16 @@
             }
         }
 
+        fun cancel(withSeeking: Boolean) {
+            if (isCanceled) {
+                return
+            }
+            if (withSeeking) {
+                isSeeking = true
+            }
+            cancel()
+        }
+
         fun mergeWith(finalState: State, lifecycleImpact: LifecycleImpact) {
             when (lifecycleImpact) {
                 LifecycleImpact.ADDING -> if (this.finalState == State.REMOVED) {
@@ -564,6 +604,14 @@
             completionListeners.add(listener)
         }
 
+        fun addBackProgressCallbacks(
+            onProgress: (BackEventCompat) -> Unit,
+            onComplete: () -> Unit
+        ) {
+            backInProgressListener = onProgress
+            backOnCompleteListener = onComplete
+        }
+
         /**
          * Callback for when the operation is about to start.
          */
@@ -612,6 +660,8 @@
                 )
             }
             isComplete = true
+            backInProgressListener = null
+            backOnCompleteListener = null
             completionListeners.forEach { listener ->
                 listener.run()
             }
@@ -673,6 +723,9 @@
 
         override fun complete() {
             super.complete()
+            // Since we are completing, ensure that the transitioning flag is set to false before
+            // we move to state
+            fragment.mTransitioning = false
             fragmentStateManager.moveToExpectedState()
         }
     }
diff --git a/glance/glance-appwidget/lint-baseline.xml b/glance/glance-appwidget/lint-baseline.xml
index 805d083..7487854 100644
--- a/glance/glance-appwidget/lint-baseline.xml
+++ b/glance/glance-appwidget/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -37,4 +37,76 @@
             file="src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverTest.kt"/>
     </issue>
 
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemId&apos; with type Function1&lt;? super Integer, Long>."
+        errorLine1="        itemId: ((index: Int) -> Long) = { UnspecifiedItemId },"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemId&apos; with type Function1&lt;? super T, Long>."
+        errorLine1="    noinline itemId: ((item: T) -> Long) = { LazyListScope.UnspecifiedItemId },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;itemId&apos; with type Function2&lt;? super Integer, ? super T, Long>."
+        errorLine1="    noinline itemId: ((index: Int, item: T) -> Long) = { _, _ -> LazyListScope.UnspecifiedItemId },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemId&apos; with type Function1&lt;? super Integer, Long>."
+        errorLine1="        itemId: ((index: Int) -> Long) = { UnspecifiedItemId },"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super LazyItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable LazyItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemId&apos; with type Function1&lt;? super T, Long>."
+        errorLine1="    noinline itemId: ((item: T) -> Long) = { LazyVerticalGridScope.UnspecifiedItemId },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;itemId&apos; with type Function2&lt;? super Integer, ? super T, Long>."
+        errorLine1="    noinline itemId: ((index: Int, item: T) -> Long) = {"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt"/>
+    </issue>
+
 </issues>
diff --git a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
index d7693a77..551c543 100644
--- a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
@@ -76,6 +76,7 @@
         val value = "value"
         context.sendBroadcast(
             Intent(BROADCAST_ACTION)
+                .setPackage(context.packageName)
                 .putExtra(EXTRA_STRING, value)
                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
         )
diff --git a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
index 3fcfbdd..ffb947e 100644
--- a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
+++ b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiverScreenshotTest.kt
@@ -30,6 +30,7 @@
 import androidx.glance.ImageProvider
 import androidx.glance.LocalContext
 import androidx.glance.action.actionStartActivity
+import androidx.glance.appwidget.lazy.LazyColumn
 import androidx.glance.appwidget.test.R
 import androidx.glance.background
 import androidx.glance.color.ColorProvider
@@ -56,12 +57,15 @@
 import androidx.glance.unit.ColorProvider
 import androidx.test.filters.MediumTest
 import androidx.test.filters.SdkSuppress
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
 import org.junit.rules.TestRule
 
 @SdkSuppress(minSdkVersion = 29)
+@OptIn(ExperimentalCoroutinesApi::class)
 @MediumTest
 class GlanceAppWidgetReceiverScreenshotTest {
     private val mScreenshotRule = screenshotRule()
@@ -537,6 +541,76 @@
 
         mScreenshotRule.checkScreenshot(mHostRule.mHostView, "alignment")
     }
+
+    @Test
+    fun lazyColumn_alignment_end() = runTest {
+        val count = 5
+        TestGlanceAppWidget.uiDefinition = {
+            LazyColumnAlignmentTest(
+                count = count,
+                horizontalAlignment = Alignment.End
+            )
+        }
+
+        mHostRule.startHost()
+
+        mHostRule.waitForListViewChildCount(count)
+        mScreenshotRule.checkScreenshot(mHostRule.mHostView, "lazyColumn_alignment_end")
+    }
+
+    @Test
+    fun lazyColumn_alignment_center() = runTest {
+        val count = 5
+        TestGlanceAppWidget.uiDefinition = {
+            LazyColumnAlignmentTest(
+                count = count,
+                horizontalAlignment = Alignment.CenterHorizontally
+            )
+        }
+
+        mHostRule.startHost()
+
+        mHostRule.waitForListViewChildCount(count)
+        mScreenshotRule.checkScreenshot(mHostRule.mHostView, "lazyColumn_alignment_center")
+    }
+
+    @Test
+    fun lazyColumn_alignment_start() = runTest {
+        val count = 5
+        TestGlanceAppWidget.uiDefinition = {
+            LazyColumnAlignmentTest(
+                count = count,
+                horizontalAlignment = Alignment.Start
+            )
+        }
+
+        mHostRule.startHost()
+
+        mHostRule.waitForListViewChildCount(count)
+        mScreenshotRule.checkScreenshot(mHostRule.mHostView, "lazyColumn_alignment_start")
+    }
+}
+
+@Composable
+private fun LazyColumnAlignmentTest(count: Int, horizontalAlignment: Alignment.Horizontal) {
+    val columnColors = listOf(Color(0xffffdbcd), Color(0xff7d2d00))
+    val textBgColors = listOf(Color(0xffa33e00), Color(0xffffb596))
+
+    LazyColumn(
+        modifier = GlanceModifier
+            .fillMaxSize()
+            .background(columnColors[0], columnColors[1]),
+        horizontalAlignment = horizontalAlignment
+    ) {
+        items(count) { index ->
+            Text(
+                text = "item $index",
+                modifier = GlanceModifier
+                    .padding(horizontal = 16.dp, vertical = 8.dp)
+                    .background(textBgColors[0], textBgColors[1])
+            )
+        }
+    }
 }
 
 @Composable
diff --git a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
index 52d61ec..6040bea 100644
--- a/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
+++ b/glance/glance-appwidget/src/androidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
@@ -186,10 +186,14 @@
         mHostRule.startHost()
 
         mHostRule.waitForListViewChildren { list ->
-            val textView0 = list.getUnboxedListItem<TextView>(0)
-            val textView1 = list.getUnboxedListItem<TextView>(1)
-            val textView2 = list.getUnboxedListItem<TextView>(2)
-            val textView3 = list.getUnboxedListItem<TextView>(3)
+            val textView0 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 0, viewPosition = 0)
+            val textView1 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 1, viewPosition = 0)
+            val textView2 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 2, viewPosition = 0)
+            val textView3 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 3, viewPosition = 0)
             assertThat(textView0.text.toString()).isEqualTo("Row 0")
             assertThat(textView1.text.toString()).isEqualTo("Row 1")
             assertThat(textView2.text.toString()).isEqualTo("Row 2")
@@ -210,10 +214,14 @@
         mHostRule.startHost()
 
         mHostRule.waitForListViewChildren { list ->
-            val textView0 = list.getUnboxedListItem<TextView>(0)
-            val textView1 = list.getUnboxedListItem<TextView>(1)
-            val textView2 = list.getUnboxedListItem<TextView>(2)
-            val textView3 = list.getUnboxedListItem<TextView>(3)
+            val textView0 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 0, viewPosition = 0)
+            val textView1 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 1, viewPosition = 0)
+            val textView2 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 2, viewPosition = 0)
+            val textView3 =
+                list.getViewFromUnboxedListItem<TextView>(itemPosition = 3, viewPosition = 0)
             assertThat(textView0.text.toString()).isEqualTo("Row 0")
             assertThat(textView1.text.toString()).isEqualTo("Row 1")
             assertThat(textView2.text.toString()).isEqualTo("Row 2")
@@ -234,7 +242,7 @@
         mHostRule.startHost()
 
         mHostRule.waitForListViewChildren { list ->
-            list.getUnboxedListItem<TextView>(0)
+            list.getViewFromUnboxedListItem<TextView>(itemPosition = 0, viewPosition = 0)
         }
     }
 
@@ -251,7 +259,7 @@
         mHostRule.startHost()
 
         mHostRule.waitForListViewChildren { list ->
-            list.getUnboxedListItem<TextView>(0)
+            list.getViewFromUnboxedListItem<TextView>(itemPosition = 0, viewPosition = 0)
         }
     }
 
@@ -374,7 +382,7 @@
             rowItem0.performClick()
         }
 
-        mHostRule.waitForListViewChildWithText(text = "Row item 0, count 1") {}
+        mHostRule.waitForListViewChildWithText(text = "Row item 0, count 2") {}
     }
 
     @Test
@@ -462,7 +470,8 @@
         val buttons = arrayOfNulls<Button>(5)
         mHostRule.waitForListViewChildren { list ->
             for (it in 0..4) {
-                val button = list.getUnboxedListItem<Button>(it)
+                val button =
+                    list.getViewFromUnboxedListItem<Button>(itemPosition = it, viewPosition = 0)
                 buttons[it] = button
             }
         }
@@ -497,7 +506,10 @@
         val buttons = arrayOfNulls<FrameLayout>(5)
         mHostRule.waitForListViewChildren { list ->
             for (it in 0..4) {
-                val button = list.getUnboxedListItem<FrameLayout>(it)
+                val button = list.getViewFromUnboxedListItem<FrameLayout>(
+                    itemPosition = it,
+                    viewPosition = 0
+                )
                 buttons[it] = assertIs<FrameLayout>(button)
             }
         }
@@ -633,12 +645,24 @@
 }.buffer(0)
 
 internal inline fun <reified T : View> ListView.getUnboxedListItem(position: Int): T {
+    // RemoteViewsAdapter$RemoteViewsFrameLayout
     val remoteViewFrame = assertIs<FrameLayout>(getChildAt(position))
 
     // Android S- have a RemoteViewsAdapter$RemoteViewsFrameLayout first, Android T+ do not.
     if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) {
         return remoteViewFrame.getChildAt(0).getTargetView()
     }
-    val frame = assertIs<FrameLayout>(remoteViewFrame.getChildAt(0))
-    return frame.getChildAt(0).getTargetView()
+    // The RemoteViews created in translateComposition for holding an item
+    val rootView = assertIs<FrameLayout>(remoteViewFrame.getChildAt(0))
+    return rootView.getChildAt(0).getTargetView()
+}
+
+internal inline fun <reified T : View> ListView.getViewFromUnboxedListItem(
+    itemPosition: Int,
+    viewPosition: Int
+): T {
+    // Box added during normalization to allow aligning item contents per the alignment set on
+    // LazyColumn
+    val alignmentView = assertIs<FrameLayout>(getUnboxedListItem(itemPosition))
+    return alignmentView.getChildAt(viewPosition).getTargetView()
 }
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/NormalizeCompositionTree.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/NormalizeCompositionTree.kt
index da340c7c..2b86729 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/NormalizeCompositionTree.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/NormalizeCompositionTree.kt
@@ -167,7 +167,6 @@
     }
 
 private fun normalizeLazyListItem(view: EmittableLazyItemWithChildren) {
-    if (view.children.size == 1 && view.alignment == Alignment.CenterStart) return
     val box = EmittableBox()
     box.children += view.children
     box.contentAlignment = view.alignment
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyList.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyList.kt
index eaaf5e0..2430387 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyList.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyList.kt
@@ -196,9 +196,7 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         itemId: ((index: Int) -> Long) = { UnspecifiedItemId },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyItemScope.(index: Int) -> Unit
     )
 
@@ -256,7 +254,6 @@
  */
 inline fun <T> LazyListScope.items(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline itemId: ((item: T) -> Long) = { LazyListScope.UnspecifiedItemId },
     crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
 ) = items(items.size, { index: Int -> itemId(items[index]) }) {
@@ -275,7 +272,6 @@
  */
 inline fun <T> LazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline itemId: ((index: Int, item: T) -> Long) = { _, _ -> LazyListScope.UnspecifiedItemId },
     crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit
 ) = items(items.size, { index: Int -> itemId(index, items[index]) }) {
@@ -293,12 +289,9 @@
 }
 
 internal class EmittableLazyListItem : EmittableLazyItemWithChildren() {
-    override var modifier: GlanceModifier
-        get() = children.singleOrNull()?.modifier
-            ?: GlanceModifier.wrapContentHeight().fillMaxWidth()
-        set(_) {
-            throw IllegalAccessError("You cannot set the modifier of an EmittableLazyListItem")
-        }
+    // Fill max width of the lazy column so that item contents can be aligned per the horizontal
+    // alignment.
+    override var modifier: GlanceModifier = GlanceModifier.wrapContentHeight().fillMaxWidth()
     var itemId: Long = 0
 
     override fun copy(): Emittable = EmittableLazyListItem().also {
diff --git a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
index 9778863..53a41ce 100644
--- a/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
+++ b/glance/glance-appwidget/src/main/java/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
@@ -190,9 +190,7 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         itemId: ((index: Int) -> Long) = { UnspecifiedItemId },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable LazyItemScope.(index: Int) -> Unit
     )
 
@@ -250,7 +248,6 @@
  */
 inline fun <T> LazyVerticalGridScope.items(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline itemId: ((item: T) -> Long) = { LazyVerticalGridScope.UnspecifiedItemId },
     crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit
 ) = items(items.size, { index: Int -> itemId(items[index]) }) {
@@ -269,7 +266,6 @@
  */
 inline fun <T> LazyVerticalGridScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline itemId: ((index: Int, item: T) -> Long) = {
       _, _ -> LazyVerticalGridScope.UnspecifiedItemId
     },
@@ -294,14 +290,9 @@
 }
 
 internal class EmittableLazyVerticalGridListItem : EmittableLazyItemWithChildren() {
-    override var modifier: GlanceModifier
-        get() = children.singleOrNull()?.modifier
-            ?: GlanceModifier.wrapContentHeight().fillMaxWidth()
-        set(_) {
-            throw IllegalAccessError(
-              "You cannot set the modifier of an EmittableLazyVerticalGridListItem"
-            )
-        }
+    // Fill max width of the grid cell so that item contents can be aligned per the horizontal
+    // alignment.
+    override var modifier: GlanceModifier = GlanceModifier.wrapContentHeight().fillMaxWidth()
     var itemId: Long = 0
 
     override fun copy(): Emittable = EmittableLazyVerticalGridListItem().also {
diff --git a/glance/glance-wear-tiles/src/test/resources/robolectric.properties b/glance/glance-wear-tiles/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/glance/glance-wear-tiles/src/test/resources/robolectric.properties
+++ b/glance/glance-wear-tiles/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/glance/glance/lint-baseline.xml b/glance/glance/lint-baseline.xml
new file mode 100644
index 0000000..ed40f5a
--- /dev/null
+++ b/glance/glance/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor InteractiveFrameClock has parameter &apos;nanoTime&apos; with type Function0&lt;Long>."
+        errorLine1="    private val nanoTime: () -> Long = { System.nanoTime() }"
+        errorLine2="                          ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/glance/session/InteractiveFrameClock.kt"/>
+    </issue>
+
+</issues>
diff --git a/glance/glance/src/main/java/androidx/glance/session/InteractiveFrameClock.kt b/glance/glance/src/main/java/androidx/glance/session/InteractiveFrameClock.kt
index 5ef33e4..806d974 100644
--- a/glance/glance/src/main/java/androidx/glance/session/InteractiveFrameClock.kt
+++ b/glance/glance/src/main/java/androidx/glance/session/InteractiveFrameClock.kt
@@ -41,7 +41,6 @@
     private val baselineHz: Int = 5,
     private val interactiveHz: Int = 20,
     private val interactiveTimeoutMs: Long = 5_000,
-    @Suppress("PrimitiveInLambda")
     private val nanoTime: () -> Long = { System.nanoTime() }
 ) : MonotonicFrameClock {
     companion object {
diff --git a/glance/glance/src/test/resources/robolectric.properties b/glance/glance/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/glance/glance/src/test/resources/robolectric.properties
+++ b/glance/glance/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/gradle.properties b/gradle.properties
index 09b1a08..9bde541 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -26,17 +26,17 @@
 android.forceJacocoOutOfProcess=true
 android.experimental.lint.missingBaselineIsEmptyBaseline=true
 
-# Generate versioned API files
+# Do generate versioned API files
 androidx.writeVersionedApiFiles=true
 
-# Run the CheckAarMetadata task
+# Do run the CheckAarMetadata task
 android.experimental.disableCompileSdkChecks=false
 
-# Do restrict compileSdkPreview usage
+# Do restrict custom SDK usage (e.g. Mainline)
 androidx.allowCustomCompileSdk=false
 
 # Don't warn about needing to update AGP
-android.suppressUnsupportedCompileSdk=UpsideDownCake,VanillaIceCream,33
+android.suppressUnsupportedCompileSdk=UpsideDownCake,VanillaIceCream,33,34
 
 # Disable features we do not use
 android.defaults.buildfeatures.aidl=false
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 8ff6388..41584cd 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -36,9 +36,9 @@
 hilt = "2.44"
 incap = "0.2"
 jcodec = "0.2.5"
-kotlin = "1.8.21"
+kotlin = "1.8.22"
 kotlinBenchmark = "0.4.8"
-kotlinNative = "1.8.21"
+kotlinNative = "1.8.22"
 kotlinCompileTesting = "1.4.9"
 kotlinCoroutines = "1.6.4"
 kotlinCoroutines171 = "1.7.1"
@@ -57,7 +57,7 @@
 spdxGradlePlugin = "0.1.0"
 sqldelight = "1.3.0"
 retrofit = "2.7.2"
-wire = "4.5.1"
+wire = "4.7.0"
 
 [libraries]
 agpTestingPlatformCoreProto =  { module = "com.google.testing.platform:core-proto", version = "0.0.8-alpha08" }
@@ -224,6 +224,7 @@
 nullaway = { module = "com.uber.nullaway:nullaway", version = "0.3.7" }
 okhttpMockwebserver = { module = "com.squareup.okhttp3:mockwebserver", version = "3.14.7" }
 okio = { module = "com.squareup.okio:okio", version = "3.1.0" }
+opentest4j = { module = "org.opentest4j:opentest4j", version = "1.2.0" }
 playFeatureDelivery = { module = "com.google.android.play:feature-delivery", version = "2.0.1" }
 playCore = { module = "com.google.android.play:core", version = "1.10.3" }
 playServicesAuth = {module = "com.google.android.gms:play-services-auth", version = "20.5.0"}
@@ -245,7 +246,7 @@
 reactiveStreams = { module = "org.reactivestreams:reactive-streams", version = "1.0.0" }
 retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
 retrofitConverterWire = { module = "com.squareup.retrofit2:converter-wire", version.ref = "retrofit" }
-robolectric = { module = "org.robolectric:robolectric", version = "4.10.3" }
+robolectric = { module = "org.robolectric:robolectric", version = "4.9.2" }
 rxjava2 = { module = "io.reactivex.rxjava2:rxjava", version = "2.2.9" }
 rxjava3 = { module = "io.reactivex.rxjava3:rxjava", version = "3.0.0" }
 shadow = { module = "gradle.plugin.com.github.johnrengelman:shadow", version = "7.1.1" }
diff --git a/gradle/verification-keyring.keys b/gradle/verification-keyring.keys
index 7ddd517..bfa94d7 100644
--- a/gradle/verification-keyring.keys
+++ b/gradle/verification-keyring.keys
@@ -6375,6 +6375,42 @@
 =2g4Z
 -----END PGP PUBLIC KEY BLOCK-----
 
+pub    DA70BCBA6D76AD03
+uid    kaml GitHub Actions <githubactions@charleskorn.com>
+
+sub    66A2CBDE49E8A25D
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: BCPG v1.68
+
+mQENBGAwdRsBCADCXfWdHhywp8Rcgt834W/Z3MFEAxYdxjAJOTQhc/In1SJfIqi/
+xD7OKHA2fbwzRnS/UmXkmElTK7JI3/1gWRm8kEaaHTnlI63Z9MZV0DHMpJMgvpFM
+JXKMw9GWbOZt211YMFTkY3oi+kCIibzs4S+2zAiKX0/B5xU1gE0hnPYbXQtZ2sUb
+8t4axAkPdlDVrnBbgPD/+31c8G2Nsd3w6Rughi3SXdqp/6lKZpJNZV7ZPllA8wa3
+6hdOqWkh2Xh7uyKCXPtPyw57vwK1CeTmrAvI7Xhfh1Cxj2bnS8POnF0YsthtbG0Z
+6TupcFBrscugbl4F0aWsxCT0WjKQ75J2zgMnABEBAAG0M2thbWwgR2l0SHViIEFj
+dGlvbnMgPGdpdGh1YmFjdGlvbnNAY2hhcmxlc2tvcm4uY29tPokBTgQTAQgAOBYh
+BOAe0pOYGuSEQDtl19pwvLptdq0DBQJgMHUbAhsDBQsJCAcCBhUKCQgLAgQWAgMB
+Ah4BAheAAAoJENpwvLptdq0Dv1YIAKtEikvgdsiHjOAl30uN71sjfa2IQpczLqnX
+I+UWyFLbjkvXoYyhOwkbK+J9NqOVEn3r6mG+lQemP7CIyFixRTLw7B9kl5RAGe2g
+tfqPOufiWTAwkvgCfnR8OxOcz2tjspZpw/9I9razrJbvCzHxCc4QbMtlGQwrrDm0
+EVCH2Ks7sbiWWujl6EIKsVobuZHaRsqrpxPtC1I7xm+ed8rEKkrBThLB9Tf2itun
++w1ct7y1rgOGKh5XH9IYuSwEbWZH0dhMIsdItYZW1Uk+t6DXXTRq5OXHmr2s6JWt
+9HECR8b+xUUZIue3d8PWewiCElgz6c+Jq6ywEwGiSyZXvFBpLaC5AQ0EYDB1GwEI
+AMQiv6gHlSd5U1Jzc8vFMS/Pt7RMg2OF8Wedibqc0/EvzIHSqAkZnVs8iVmf6VYp
+bx1ihFG4ySaCmVkovJ7Yv6yHNyyqp1SsRPJJ1zGUVx5USOO8sT6FsS1Wis2NmWXf
+wcJkhO6RfBUF21vPjXkGlbkhyQxqsnCWtCDhZT9/OGacOTd+xUf9Fq2u5KACdn7h
+qlVMhaRgrPEmdh+95RjSHu+lkzoThG4S0rRd7u6XrUs4w5rqwBqWQB8jzS5I8L6H
+MpLnmLQckxnICGwRUyKywd23/zF3HN63Dbj8MCohrYRn39cXutlRbLH4dG8hPpoI
+JeP7OYZIUJGJYdsi5q+EJAsAEQEAAYkBNgQYAQgAIBYhBOAe0pOYGuSEQDtl19pw
+vLptdq0DBQJgMHUbAhsMAAoJENpwvLptdq0DtRMIAJiWNubgOvXDav3l7Wff+qPN
+zMKFh+9lNMyLaI5O8eEGjXAt90esN1MeVbKwFiNO5NSM2qLf7QJ6aXF6SIUGsWut
+1BUOt21Q5unl3n4YZ+Ff6zA/VEgniGJBJBBnBq2dJO/lJKj9tLkcbvzV0Aa+MLQ+
+lEB3lufGDU4xsApp6w18YQK2Za64drxYL9yChofSH0x+Gvx7aYaXi+K1L/HUSh7k
+qBcwgxmqlnWArnQ8sYd4WF1LOplzm4yp0XocHtcZ0hQG0ZW3kAEITPYfmVk26kO0
+Rsia71ZAHmuEYsLHz6uOIqf6XHbFUITFtdjPOSiJmQhIgiFCzvFSgrx6jKZSR04=
+=Jrn2
+-----END PGP PUBLIC KEY BLOCK-----
+
 pub    15C71C0A4E0B8EDD
 sub    891E4C2D471515FE
 -----BEGIN PGP PUBLIC KEY BLOCK-----
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index 1778366..18e5610 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -411,6 +411,7 @@
             <trusting group="com.beust"/>
             <trusting group="org.testng"/>
          </trusted-key>
+         <trusted-key id="e01ed293981ae484403b65d7da70bcba6d76ad03" group="com.charleskorn.kaml"/>
          <trusted-key id="e0d98c5fd55a8af232290e58dee12b9896f97e34" group="org.pcollections"/>
          <trusted-key id="e3a9f95079e84ce201f7cf60bede11eaf1164480" group="org.hamcrest"/>
          <trusted-key id="e62231331bca7e1f292c9b88c1b12a5d99c0729d" group="org.jetbrains"/>
@@ -458,19 +459,19 @@
       </trusted-keys>
    </configuration>
    <components>
-      <component group="" name="kotlin-native-prebuilt-linux-x86_64" version="1.8.21">
-         <artifact name="kotlin-native-prebuilt-linux-x86_64-1.8.21.tar.gz">
-            <sha256 value="a4ad0664076b44a80d182f3a3f40ca35a7b4ca4c13c84ad90c2e32fb3a829fd3" origin="Hand-built using sha256sum kotlin-native-prebuilt-linux-x86_64-1.8.21.tar.gz" reason="Artifact is not signed"/>
+      <component group="" name="kotlin-native-prebuilt-linux-x86_64" version="1.8.22">
+         <artifact name="kotlin-native-prebuilt-linux-x86_64-1.8.22.tar.gz">
+            <sha256 value="43106db0ad8fb292facae924c97591529de15b69a0426d0474ac3811820a05b5" origin="Hand-built using sha256sum kotlin-native-prebuilt-linux-x86_64-1.8.22.tar.gz" reason="Artifact is not signed"/>
          </artifact>
       </component>
-      <component group="" name="kotlin-native-prebuilt-macos-aarch64" version="1.8.21">
-         <artifact name="kotlin-native-prebuilt-macos-aarch64-1.8.21.tar.gz">
-            <sha256 value="f6ae002832b6727fb6da8701429d9d9ad7f4b9ac410aca446d9a1880293882aa" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-aarch64-1.8.21.tar.gz"/>
+      <component group="" name="kotlin-native-prebuilt-macos-aarch64" version="1.8.22">
+         <artifact name="kotlin-native-prebuilt-macos-aarch64-1.8.22.tar.gz">
+            <sha256 value="d693f7c70e491ee9fa1e9d7392192934fb1d504fab2a9c7e8dbe877af3228c7c" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-aarch64-1.8.22.tar.gz"/>
          </artifact>
       </component>
-      <component group="" name="kotlin-native-prebuilt-macos-x86_64" version="1.8.21">
-         <artifact name="kotlin-native-prebuilt-macos-x86_64-1.8.21.tar.gz">
-            <sha256 value="a4fefa2fd40d16fcdf1b0095cfaf3c1b2857a79290972b436c797fbb20df9b63" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-x86_64-1.8.21.tar.gz"/>
+      <component group="" name="kotlin-native-prebuilt-macos-x86_64" version="1.8.22">
+         <artifact name="kotlin-native-prebuilt-macos-x86_64-1.8.22.tar.gz">
+            <sha256 value="5d924f4278028352cb2bdbaa4b3fab967ab81c3fbea845bdb91cd583af5c9bcc" origin="Hand-built using sha256sum kotlin-native-prebuilt-macos-x86_64-1.8.22.tar.gz"/>
          </artifact>
       </component>
       <component group="aopalliance" name="aopalliance" version="1.0">
diff --git a/graphics/filters/filters/lint-baseline.xml b/graphics/filters/filters/lint-baseline.xml
index efe83da..9a42e316 100644
--- a/graphics/filters/filters/lint-baseline.xml
+++ b/graphics/filters/filters/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
 
     <issue
         id="UnsafeOptInUsageError"
diff --git a/graphics/graphics-core/api/current.txt b/graphics/graphics-core/api/current.txt
index d9f2b2f..f22bab1 100644
--- a/graphics/graphics-core/api/current.txt
+++ b/graphics/graphics-core/api/current.txt
@@ -83,6 +83,34 @@
     method public void onDrawComplete(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFenceCompat);
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrameBufferRenderer {
+    method public void execute(Runnable runnable);
+    method public androidx.graphics.opengl.GLRenderer getGLRenderer();
+    method public int getMaxBuffers();
+    method public int getPixelFormat();
+    method public androidx.graphics.opengl.SyncStrategy getSyncStrategy();
+    method public long getUsageFlags();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseCallback);
+    method public void render();
+  }
+
+  public static final class GLFrameBufferRenderer.Builder {
+    ctor public GLFrameBufferRenderer.Builder(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLFrameBufferRenderer.Callback callback);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer build();
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setGLRenderer(androidx.graphics.opengl.GLRenderer? glRenderer);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setMaxBuffers(int numBuffers);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setPixelFormat(int format);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setSyncStrategy(androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public static interface GLFrameBufferRenderer.Callback {
+    method @WorkerThread public default void onDrawComplete(androidx.graphics.surface.SurfaceControlCompat targetSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction, androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFence);
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform);
+  }
+
   public final class GLRenderer {
     ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EGLSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLManager,? extends android.opengl.EGLConfig> eglConfigFactory);
     method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
@@ -297,6 +325,8 @@
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBufferTransform(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int transformation);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setCrop(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Rect? crop);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDamageRegion(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Region? region);
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public androidx.graphics.surface.SurfaceControlCompat.Transaction setDataSpace(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int dataSpace);
+    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public androidx.graphics.surface.SurfaceControlCompat.Transaction setExtendedRangeBrightness(androidx.graphics.surface.SurfaceControlCompat surfaceControl, @FloatRange(from=1.0, fromInclusive=true) float currentBufferRatio, @FloatRange(from=1.0, fromInclusive=true) float desiredRatio);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setLayer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int z);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setOpaque(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean isOpaque);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setPosition(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float x, float y);
diff --git a/graphics/graphics-core/api/restricted_current.txt b/graphics/graphics-core/api/restricted_current.txt
index cf8f638..f5bd02c 100644
--- a/graphics/graphics-core/api/restricted_current.txt
+++ b/graphics/graphics-core/api/restricted_current.txt
@@ -83,6 +83,34 @@
     method public void onDrawComplete(androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFenceCompat);
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.Q) public final class GLFrameBufferRenderer {
+    method public void execute(Runnable runnable);
+    method public androidx.graphics.opengl.GLRenderer getGLRenderer();
+    method public int getMaxBuffers();
+    method public int getPixelFormat();
+    method public androidx.graphics.opengl.SyncStrategy getSyncStrategy();
+    method public long getUsageFlags();
+    method public boolean isValid();
+    method public void release(boolean cancelPending);
+    method public void release(boolean cancelPending, optional kotlin.jvm.functions.Function0<kotlin.Unit>? onReleaseCallback);
+    method public void render();
+  }
+
+  public static final class GLFrameBufferRenderer.Builder {
+    ctor public GLFrameBufferRenderer.Builder(android.view.SurfaceView surfaceView, androidx.graphics.opengl.GLFrameBufferRenderer.Callback callback);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer build();
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setGLRenderer(androidx.graphics.opengl.GLRenderer? glRenderer);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setMaxBuffers(int numBuffers);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setPixelFormat(int format);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setSyncStrategy(androidx.graphics.opengl.SyncStrategy syncStrategy);
+    method public androidx.graphics.opengl.GLFrameBufferRenderer.Builder setUsageFlags(long usageFlags);
+  }
+
+  public static interface GLFrameBufferRenderer.Callback {
+    method @WorkerThread public default void onDrawComplete(androidx.graphics.surface.SurfaceControlCompat targetSurfaceControl, androidx.graphics.surface.SurfaceControlCompat.Transaction transaction, androidx.graphics.opengl.FrameBuffer frameBuffer, androidx.hardware.SyncFenceCompat? syncFence);
+    method @WorkerThread public void onDrawFrame(androidx.graphics.opengl.egl.EGLManager eglManager, androidx.graphics.lowlatency.BufferInfo bufferInfo, float[] transform);
+  }
+
   public final class GLRenderer {
     ctor public GLRenderer(optional kotlin.jvm.functions.Function0<? extends androidx.graphics.opengl.egl.EGLSpec> eglSpecFactory, optional kotlin.jvm.functions.Function1<? super androidx.graphics.opengl.egl.EGLManager,? extends android.opengl.EGLConfig> eglConfigFactory);
     method public androidx.graphics.opengl.GLRenderer.RenderTarget attach(android.view.Surface surface, int width, int height, androidx.graphics.opengl.GLRenderer.RenderCallback renderer);
@@ -298,6 +326,8 @@
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setBufferTransform(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int transformation);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setCrop(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Rect? crop);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setDamageRegion(androidx.graphics.surface.SurfaceControlCompat surfaceControl, android.graphics.Region? region);
+    method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public androidx.graphics.surface.SurfaceControlCompat.Transaction setDataSpace(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int dataSpace);
+    method @RequiresApi(android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public androidx.graphics.surface.SurfaceControlCompat.Transaction setExtendedRangeBrightness(androidx.graphics.surface.SurfaceControlCompat surfaceControl, @FloatRange(from=1.0, fromInclusive=true) float currentBufferRatio, @FloatRange(from=1.0, fromInclusive=true) float desiredRatio);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setLayer(androidx.graphics.surface.SurfaceControlCompat surfaceControl, int z);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setOpaque(androidx.graphics.surface.SurfaceControlCompat surfaceControl, boolean isOpaque);
     method public androidx.graphics.surface.SurfaceControlCompat.Transaction setPosition(androidx.graphics.surface.SurfaceControlCompat surfaceControl, float x, float y);
diff --git a/graphics/graphics-core/build.gradle b/graphics/graphics-core/build.gradle
index 07c8a7d..7b122a2 100644
--- a/graphics/graphics-core/build.gradle
+++ b/graphics/graphics-core/build.gradle
@@ -26,6 +26,7 @@
 dependencies {
     api(libs.kotlinStdlib)
     implementation 'androidx.annotation:annotation:1.2.0'
+    implementation("androidx.core:core:1.8.0")
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.testRunner)
diff --git a/graphics/graphics-core/lint-baseline.xml b/graphics/graphics-core/lint-baseline.xml
new file mode 100644
index 0000000..a01fd91
--- /dev/null
+++ b/graphics/graphics-core/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            return if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt"/>
+    </issue>
+
+</issues>
diff --git a/graphics/graphics-core/src/androidTest/AndroidManifest.xml b/graphics/graphics-core/src/androidTest/AndroidManifest.xml
index 046bf8c..f7ad0b7 100644
--- a/graphics/graphics-core/src/androidTest/AndroidManifest.xml
+++ b/graphics/graphics-core/src/androidTest/AndroidManifest.xml
@@ -35,7 +35,7 @@
             android:exported="true">
         </activity>
 
-        <activity android:name="androidx.graphics.lowlatency.FrontBufferedRendererTestActivity"
+        <activity android:name="androidx.graphics.opengl.SurfaceViewTestActivity"
             android:label="WetDryRendererTest"
             android:exported="true"/>
 
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
index 4e7145d..cd8f0ec 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/CanvasFrontBufferedRendererTest.kt
@@ -24,6 +24,7 @@
 import androidx.annotation.RequiresApi
 import androidx.core.os.BuildCompat
 import androidx.graphics.drawSquares
+import androidx.graphics.opengl.SurfaceViewTestActivity
 import androidx.graphics.surface.SurfaceControlCompat
 import androidx.graphics.surface.SurfaceControlUtils
 import androidx.lifecycle.Lifecycle
@@ -94,7 +95,7 @@
         var renderer: CanvasFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -170,7 +171,7 @@
         var renderer: CanvasFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -277,7 +278,7 @@
         var renderer: CanvasFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -372,7 +373,7 @@
         var renderer: CanvasFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -411,7 +412,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
     @Test
     fun testMultiBufferedContentsNotPersisted() {
-        val screenWidth = FrontBufferedRendererTestActivity.WIDTH
+        val screenWidth = SurfaceViewTestActivity.WIDTH
         val renderLatch = CountDownLatch(1)
         val firstDrawLatch = CountDownLatch(1)
         val callbacks = object : CanvasFrontBufferedRenderer.Callback<Any> {
@@ -456,7 +457,7 @@
         var renderer: CanvasFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -573,7 +574,7 @@
             Assert.assertTrue(automation.setRotation(rotation))
             automation.waitForIdle(1000, 3000)
 
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -648,9 +649,9 @@
             }
         }
         var renderer: CanvasFrontBufferedRenderer<Any>? = null
-        var surfaceView: FrontBufferedRendererTestActivity.TestSurfaceView? = null
+        var surfaceView: SurfaceViewTestActivity.TestSurfaceView? = null
         val createLatch = CountDownLatch(1)
-        ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+        ActivityScenario.launch(SurfaceViewTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
             .onActivity {
                 surfaceView = it.getSurfaceView()
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/FrontBufferedRendererTestActivity.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/FrontBufferedRendererTestActivity.kt
deleted file mode 100644
index 9fae68f..0000000
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/FrontBufferedRendererTestActivity.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.graphics.lowlatency
-
-import android.app.Activity
-import android.content.Context
-import android.os.Bundle
-import android.view.SurfaceHolder
-import android.view.SurfaceView
-import android.view.ViewGroup
-
-class FrontBufferedRendererTestActivity : Activity() {
-
-    private lateinit var mSurfaceView: TestSurfaceView
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        val surfaceView = TestSurfaceView(this).also { mSurfaceView = it }
-        setContentView(surfaceView, ViewGroup.LayoutParams(WIDTH, HEIGHT))
-    }
-
-    fun getSurfaceView(): TestSurfaceView = mSurfaceView
-
-    companion object {
-        const val WIDTH = 100
-        const val HEIGHT = 100
-    }
-
-    class TestSurfaceView(context: Context) : SurfaceView(context) {
-
-        private var mHolderWrapper: HolderWrapper? = null
-
-        override fun getHolder(): SurfaceHolder {
-            var wrapper = mHolderWrapper
-            if (wrapper == null) {
-                wrapper = HolderWrapper(super.getHolder()).also { mHolderWrapper = it }
-            }
-            return wrapper
-        }
-
-        fun getCallbackCount(): Int = mHolderWrapper?.mCallbacks?.size ?: 0
-
-        class HolderWrapper(val wrapped: SurfaceHolder) : SurfaceHolder by wrapped {
-
-            val mCallbacks = ArrayList<SurfaceHolder.Callback>()
-
-            override fun addCallback(callback: SurfaceHolder.Callback) {
-                if (!mCallbacks.contains(callback)) {
-                    mCallbacks.add(callback)
-                    wrapped.addCallback(callback)
-                }
-            }
-
-            override fun removeCallback(callback: SurfaceHolder.Callback) {
-                if (mCallbacks.contains(callback)) {
-                    mCallbacks.remove(callback)
-                    wrapped.removeCallback(callback)
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
index ffdf583..8899880 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
@@ -26,6 +26,7 @@
 import android.view.SurfaceView
 import androidx.annotation.RequiresApi
 import androidx.graphics.opengl.GLRenderer
+import androidx.graphics.opengl.SurfaceViewTestActivity
 import androidx.graphics.opengl.egl.EGLManager
 import androidx.graphics.surface.SurfaceControlCompat
 import androidx.graphics.surface.SurfaceControlUtils
@@ -130,7 +131,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -231,7 +232,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -364,7 +365,7 @@
         var renderer: GLFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -475,7 +476,7 @@
         var renderer: GLFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -574,7 +575,7 @@
         var renderer: GLFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -680,7 +681,7 @@
         var renderer: GLFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -742,7 +743,7 @@
         var renderer: GLFrontBufferedRenderer<Int>? = null
         var surfaceView: SurfaceView?
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -863,7 +864,7 @@
         }
         var renderer: GLFrontBufferedRenderer<Any>? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     renderer = GLFrontBufferedRenderer(it.getSurfaceView(), callbacks)
@@ -886,7 +887,7 @@
     fun testDoubleBufferedContentsNotPersisted() {
         val mOrthoMatrix = FloatArray(16)
         val mProjectionMatrix = FloatArray(16)
-        val screenWidth = FrontBufferedRendererTestActivity.WIDTH
+        val screenWidth = SurfaceViewTestActivity.WIDTH
         val rectWidth = 10f
 
         val renderLatch = CountDownLatch(1)
@@ -968,7 +969,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -1080,7 +1081,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -1203,7 +1204,7 @@
         }
         var renderer: GLFrontBufferedRenderer<Any>? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -1257,9 +1258,9 @@
             }
         }
         var renderer: GLFrontBufferedRenderer<Any>? = null
-        var surfaceView: FrontBufferedRendererTestActivity.TestSurfaceView? = null
+        var surfaceView: SurfaceViewTestActivity.TestSurfaceView? = null
         val createLatch = CountDownLatch(1)
-        ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+        ActivityScenario.launch(SurfaceViewTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
             .onActivity {
                 surfaceView = it.getSurfaceView()
@@ -1312,9 +1313,9 @@
             }
         }
         var renderer: GLFrontBufferedRenderer<Any>? = null
-        var surfaceView: FrontBufferedRendererTestActivity.TestSurfaceView? = null
+        var surfaceView: SurfaceViewTestActivity.TestSurfaceView? = null
         val createLatch = CountDownLatch(1)
-        val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+        val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
             .onActivity {
                 surfaceView = it.getSurfaceView()
@@ -1386,7 +1387,7 @@
                 // NO-OP
             }
         }
-        ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+        ActivityScenario.launch(SurfaceViewTestActivity::class.java)
             .moveToState(Lifecycle.State.CREATED)
             .onActivity {
                 assertThrows(IllegalStateException::class.java) {
@@ -1422,7 +1423,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView?
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
@@ -1532,7 +1533,7 @@
         var renderer: GLFrontBufferedRenderer<Any>? = null
         var surfaceView: SurfaceView? = null
         try {
-            val scenario = ActivityScenario.launch(FrontBufferedRendererTestActivity::class.java)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
                 .moveToState(Lifecycle.State.CREATED)
                 .onActivity {
                     surfaceView = it.getSurfaceView()
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34Test.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34Test.kt
new file mode 100644
index 0000000..b1ade98
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34Test.kt
@@ -0,0 +1,413 @@
+/*
+ * 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.graphics.lowlatency
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.ColorSpace
+import android.hardware.HardwareBuffer
+import android.os.Build
+import androidx.core.os.BuildCompat
+import androidx.graphics.drawSquares
+import androidx.graphics.isAllColor
+import androidx.graphics.opengl.egl.supportsNativeAndroidFence
+import androidx.graphics.surface.SurfaceControlCompat
+import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_IDENTITY
+import androidx.graphics.verifyQuadrants
+import androidx.graphics.withEgl
+import androidx.hardware.SyncFenceCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class SingleBufferedCanvasRendererV34Test {
+
+    companion object {
+        const val TEST_WIDTH = 20
+        const val TEST_HEIGHT = 20
+    }
+
+    data class RectColors(
+        val topLeft: Int,
+        val topRight: Int,
+        val bottomLeft: Int,
+        val bottomRight: Int
+    )
+
+    @Test
+    fun testRenderFrameRotate0() {
+        testRenderWithTransform(
+            BUFFER_TRANSFORM_IDENTITY,
+            RectColors(
+                topLeft = Color.RED,
+                topRight = Color.YELLOW,
+                bottomRight = Color.BLUE,
+                bottomLeft = Color.GREEN
+            ),
+            RectColors(
+                topLeft = Color.RED,
+                topRight = Color.YELLOW,
+                bottomRight = Color.BLUE,
+                bottomLeft = Color.GREEN
+            )
+        )
+    }
+
+    @Test
+    fun testRenderFrameRotate90() {
+        testRenderWithTransform(
+            SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_90,
+            RectColors(
+                topLeft = Color.RED,
+                topRight = Color.YELLOW,
+                bottomRight = Color.BLUE,
+                bottomLeft = Color.GREEN
+            ),
+            RectColors(
+                topLeft = Color.YELLOW,
+                topRight = Color.BLUE,
+                bottomRight = Color.GREEN,
+                bottomLeft = Color.RED
+            )
+        )
+    }
+
+    @Test
+    fun testRenderFrameRotate180() {
+        testRenderWithTransform(
+            SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_180,
+            RectColors(
+                topLeft = Color.RED,
+                topRight = Color.YELLOW,
+                bottomRight = Color.BLUE,
+                bottomLeft = Color.GREEN
+            ),
+            RectColors(
+                topLeft = Color.BLUE,
+                topRight = Color.GREEN,
+                bottomRight = Color.RED,
+                bottomLeft = Color.YELLOW
+            )
+        )
+    }
+
+    @Test
+    fun testRenderFrameRotate270() {
+        testRenderWithTransform(
+            SurfaceControlCompat.BUFFER_TRANSFORM_ROTATE_270,
+            RectColors(
+                topLeft = Color.RED,
+                topRight = Color.YELLOW,
+                bottomRight = Color.BLUE,
+                bottomLeft = Color.GREEN
+            ),
+            RectColors(
+                topLeft = Color.GREEN,
+                topRight = Color.RED,
+                bottomRight = Color.YELLOW,
+                bottomLeft = Color.BLUE
+            )
+        )
+    }
+
+    @Test
+    fun testClearRenderer() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val transformer = BufferTransformer().apply {
+            computeTransform(TEST_WIDTH, TEST_HEIGHT, BUFFER_TRANSFORM_IDENTITY)
+        }
+        val executor = Executors.newSingleThreadExecutor()
+        val firstRenderLatch = CountDownLatch(1)
+        val clearLatch = CountDownLatch(2)
+        var buffer: HardwareBuffer? = null
+        val renderer = SingleBufferedCanvasRendererV34(
+            TEST_WIDTH,
+            TEST_HEIGHT,
+            transformer,
+            executor,
+            object : SingleBufferedCanvasRenderer.RenderCallbacks<Unit> {
+                override fun render(canvas: Canvas, width: Int, height: Int, param: Unit) {
+                    canvas.drawColor(Color.RED)
+                }
+
+                override fun onBufferReady(
+                    hardwareBuffer: HardwareBuffer,
+                    syncFenceCompat: SyncFenceCompat?
+                ) {
+                    syncFenceCompat?.awaitForever()
+                    buffer = hardwareBuffer
+                    firstRenderLatch.countDown()
+                    clearLatch.countDown()
+                }
+            })
+        try {
+            renderer.render(Unit)
+            firstRenderLatch.await(3000, TimeUnit.MILLISECONDS)
+            renderer.clear()
+            assertTrue(clearLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(buffer)
+            val colorSpace = ColorSpace.get(ColorSpace.Named.LINEAR_SRGB)
+            val bitmap = Bitmap.wrapHardwareBuffer(buffer!!, colorSpace)
+                ?.copy(Bitmap.Config.ARGB_8888, false)
+            assertNotNull(bitmap)
+            assertTrue(bitmap!!.isAllColor(Color.TRANSPARENT))
+        } finally {
+            val latch = CountDownLatch(1)
+            renderer.release(true) {
+                executor.shutdownNow()
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        }
+    }
+
+    @Test
+    fun testCancelPending() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val transformer = BufferTransformer().apply {
+            computeTransform(TEST_WIDTH, TEST_HEIGHT, BUFFER_TRANSFORM_IDENTITY)
+        }
+        val executor = Executors.newSingleThreadExecutor()
+        var buffer: HardwareBuffer? = null
+        val initialDrawLatch = CountDownLatch(1)
+
+        var drawCancelledRequestLatch: CountDownLatch? = null
+        val renderer = SingleBufferedCanvasRendererV34(
+            TEST_WIDTH,
+            TEST_HEIGHT,
+            transformer,
+            executor,
+            object : SingleBufferedCanvasRenderer.RenderCallbacks<Int> {
+                override fun render(canvas: Canvas, width: Int, height: Int, param: Int) {
+                    canvas.drawColor(param)
+                }
+
+                override fun onBufferReady(
+                    hardwareBuffer: HardwareBuffer,
+                    syncFenceCompat: SyncFenceCompat?
+                ) {
+                    syncFenceCompat?.awaitForever()
+                    buffer = hardwareBuffer
+                    initialDrawLatch.countDown()
+                    drawCancelledRequestLatch?.countDown()
+                }
+            })
+        try {
+            renderer.render(Color.RED)
+            assertTrue(initialDrawLatch.await(3000, TimeUnit.MILLISECONDS))
+
+            drawCancelledRequestLatch = CountDownLatch(2)
+            renderer.render(Color.BLUE)
+            renderer.render(Color.BLACK)
+            renderer.cancelPending()
+
+            // Because the requests were cancelled this latch should not be signalled
+            assertFalse(drawCancelledRequestLatch.await(1000, TimeUnit.MILLISECONDS))
+            assertNotNull(buffer)
+            val colorSpace = ColorSpace.get(ColorSpace.Named.LINEAR_SRGB)
+            val bitmap = Bitmap.wrapHardwareBuffer(buffer!!, colorSpace)
+                ?.copy(Bitmap.Config.ARGB_8888, false)
+            assertNotNull(bitmap)
+            assertTrue(bitmap!!.isAllColor(Color.RED))
+        } finally {
+            val latch = CountDownLatch(1)
+            renderer.release(true) {
+                executor.shutdownNow()
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        }
+    }
+
+    @Test
+    fun testMultiReleasesDoesNotCrash() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val transformer = BufferTransformer().apply {
+            computeTransform(TEST_WIDTH, TEST_HEIGHT, BUFFER_TRANSFORM_IDENTITY)
+        }
+        val executor = Executors.newSingleThreadExecutor()
+        val renderer = SingleBufferedCanvasRendererV34(
+            TEST_WIDTH,
+            TEST_HEIGHT,
+            transformer,
+            executor,
+            object : SingleBufferedCanvasRenderer.RenderCallbacks<Void> {
+                override fun render(canvas: Canvas, width: Int, height: Int, param: Void) {
+                    // NO-OP
+                }
+
+                override fun onBufferReady(
+                    hardwareBuffer: HardwareBuffer,
+                    syncFenceCompat: SyncFenceCompat?
+                ) {
+                    // NO-OP
+                }
+            })
+        try {
+            val latch = CountDownLatch(1)
+            renderer.release(true) {
+                executor.shutdownNow()
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+            renderer.release(true)
+        } finally {
+            if (!executor.isShutdown) {
+                executor.shutdownNow()
+            }
+        }
+    }
+
+    @Test
+    fun testRendererVisibleFlag() {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        var supportsNativeAndroidFence = false
+        withEgl { eglManager ->
+            supportsNativeAndroidFence = eglManager.supportsNativeAndroidFence()
+        }
+        if (!supportsNativeAndroidFence) {
+            return
+        }
+        val transformer = BufferTransformer().apply {
+            computeTransform(TEST_WIDTH, TEST_HEIGHT, BUFFER_TRANSFORM_IDENTITY)
+        }
+        val executor = Executors.newSingleThreadExecutor()
+        var syncFenceNull = false
+        var drawLatch: CountDownLatch? = null
+        val renderer = SingleBufferedCanvasRendererV34(
+            TEST_WIDTH,
+            TEST_HEIGHT,
+            transformer,
+            executor,
+            object : SingleBufferedCanvasRenderer.RenderCallbacks<Int> {
+                override fun render(canvas: Canvas, width: Int, height: Int, param: Int) {
+                    canvas.drawColor(param)
+                }
+
+                override fun onBufferReady(
+                    hardwareBuffer: HardwareBuffer,
+                    syncFenceCompat: SyncFenceCompat?
+                ) {
+                    syncFenceNull = syncFenceCompat == null
+                    syncFenceCompat?.awaitForever()
+                    drawLatch?.countDown()
+                }
+            })
+        try {
+            renderer.isVisible = false
+            drawLatch = CountDownLatch(1)
+            renderer.render(Color.RED)
+            assertTrue(drawLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertFalse(syncFenceNull)
+
+            renderer.isVisible = true
+            drawLatch = CountDownLatch(1)
+            renderer.render(Color.BLUE)
+            assertTrue(drawLatch.await(3000, TimeUnit.MILLISECONDS))
+        } finally {
+            val latch = CountDownLatch(1)
+            renderer.release(true) {
+                executor.shutdownNow()
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        }
+    }
+
+    private fun testRenderWithTransform(
+        transform: Int,
+        actualColors: RectColors,
+        expectedColors: RectColors
+    ) {
+        if (!BuildCompat.isAtLeastU()) {
+            return
+        }
+        val transformer = BufferTransformer()
+        transformer.computeTransform(TEST_WIDTH, TEST_HEIGHT, transform)
+        val executor = Executors.newSingleThreadExecutor()
+        var buffer: HardwareBuffer? = null
+        val renderLatch = CountDownLatch(1)
+        val renderer = SingleBufferedCanvasRendererV34(
+            TEST_WIDTH,
+            TEST_HEIGHT,
+            transformer,
+            executor,
+            object : SingleBufferedCanvasRenderer.RenderCallbacks<Int> {
+                override fun render(canvas: Canvas, width: Int, height: Int, param: Int) {
+                    drawSquares(
+                        canvas,
+                        width,
+                        height,
+                        actualColors.topLeft,
+                        actualColors.topRight,
+                        actualColors.bottomLeft,
+                        actualColors.bottomRight
+                    )
+                }
+
+                override fun onBufferReady(
+                    hardwareBuffer: HardwareBuffer,
+                    syncFenceCompat: SyncFenceCompat?
+                ) {
+                    syncFenceCompat?.awaitForever()
+                    buffer = hardwareBuffer
+                    renderLatch.countDown()
+                }
+            })
+        try {
+            renderer.render(0)
+            assertTrue(renderLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(buffer)
+            val colorSpace = ColorSpace.get(ColorSpace.Named.LINEAR_SRGB)
+            val bitmap = Bitmap.wrapHardwareBuffer(buffer!!, colorSpace)
+                ?.copy(Bitmap.Config.ARGB_8888, false)
+            assertNotNull(bitmap)
+            bitmap!!.verifyQuadrants(
+                expectedColors.topLeft,
+                expectedColors.topRight,
+                expectedColors.bottomLeft,
+                expectedColors.bottomRight
+            )
+        } finally {
+            val latch = CountDownLatch(1)
+            renderer.release(true) {
+                executor.shutdownNow()
+                latch.countDown()
+            }
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/FrameBufferView.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/FrameBufferView.kt
new file mode 100644
index 0000000..98744f6
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/FrameBufferView.kt
@@ -0,0 +1,139 @@
+/*
+ * 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.graphics.opengl
+
+import android.content.Context
+import android.graphics.Color
+import android.opengl.GLES20
+import android.opengl.Matrix
+import android.os.Build
+import android.view.MotionEvent
+import android.view.SurfaceView
+import androidx.annotation.RequiresApi
+import androidx.annotation.WorkerThread
+import androidx.graphics.lowlatency.BufferInfo
+import androidx.graphics.lowlatency.LineRenderer
+import androidx.graphics.opengl.egl.EGLManager
+import java.util.concurrent.ConcurrentLinkedQueue
+
+@RequiresApi(Build.VERSION_CODES.Q)
+class FrameBufferView(context: Context) : SurfaceView(context) {
+
+    private var mFrameBufferRenderer: GLFrameBufferRenderer? = null
+
+    private var mLineRenderer: LineRenderer? = null
+
+    private var mWidth: Int = 0
+    private var mHeight: Int = 0
+    private var mPreviousX: Float = 0f
+    private var mPreviousY: Float = 0f
+    private var mCurrentX: Float = 0f
+    private var mCurrentY: Float = 0f
+
+    @WorkerThread // GLThread
+    private fun obtainRenderer(): LineRenderer =
+        mLineRenderer ?: (LineRenderer()
+            .apply {
+                initialize()
+                mLineRenderer = this
+            })
+
+    private val mSceneParams = ConcurrentLinkedQueue<FloatArray>()
+
+    private val mCallbacks = object : GLFrameBufferRenderer.Callback {
+
+        private val mMVPMatrix = FloatArray(16)
+        private val mProjection = FloatArray(16)
+
+        override fun onDrawFrame(
+            eglManager: EGLManager,
+            bufferInfo: BufferInfo,
+            transform: FloatArray
+        ) {
+            GLES20.glViewport(0, 0, bufferInfo.width, bufferInfo.height)
+            GLES20.glClearColor(0f, 0f, 0f, 0f)
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
+            GLES20.glFlush()
+            Matrix.orthoM(
+                mMVPMatrix,
+                0,
+                0f,
+                bufferInfo.width.toFloat(),
+                0f,
+                bufferInfo.height.toFloat(),
+                -1f,
+                1f
+            )
+            Matrix.multiplyMM(mProjection, 0, mMVPMatrix, 0, transform, 0)
+            for (line in mSceneParams) {
+                obtainRenderer().drawLines(mProjection, line, Color.BLUE, LINE_WIDTH)
+            }
+        }
+    }
+
+    init {
+        setOnTouchListener { _, event ->
+            when (event.action) {
+                MotionEvent.ACTION_DOWN -> {
+                    requestUnbufferedDispatch(event)
+                    mCurrentX = event.x
+                    mCurrentY = event.y
+                }
+                MotionEvent.ACTION_MOVE -> {
+                    mPreviousX = mCurrentX
+                    mPreviousY = mCurrentY
+                    mCurrentX = event.x
+                    mCurrentY = event.y
+
+                    val line = FloatArray(4).apply {
+                        this[0] = mPreviousX
+                        this[1] = mPreviousY
+                        this[2] = mCurrentX
+                        this[3] = mCurrentY
+                    }
+                    mSceneParams.add(line)
+                    mFrameBufferRenderer?.render()
+                }
+            }
+            true
+        }
+    }
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        mFrameBufferRenderer = GLFrameBufferRenderer.Builder(this, mCallbacks)
+            .setMaxBuffers(1)
+            .build()
+    }
+
+    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+        super.onLayout(changed, left, top, right, bottom)
+        mWidth = right - left
+        mHeight = bottom - top
+    }
+
+    override fun onDetachedFromWindow() {
+        mFrameBufferRenderer?.release(true) {
+            obtainRenderer().release()
+        }
+        super.onDetachedFromWindow()
+    }
+
+    private companion object {
+        private const val LINE_WIDTH = 5f
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLFrameBufferRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLFrameBufferRendererTest.kt
new file mode 100644
index 0000000..b9f94fa
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLFrameBufferRendererTest.kt
@@ -0,0 +1,506 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.graphics.opengl
+
+import android.graphics.Color
+import android.hardware.HardwareBuffer
+import android.opengl.GLES20
+import android.opengl.Matrix
+import android.os.Build
+import android.view.SurfaceView
+import androidx.annotation.RequiresApi
+import androidx.graphics.lowlatency.BufferInfo
+import androidx.graphics.lowlatency.Rectangle
+import androidx.graphics.opengl.egl.EGLManager
+import androidx.graphics.opengl.egl.EGLSpec
+import androidx.graphics.opengl.egl.supportsNativeAndroidFence
+import androidx.graphics.surface.SurfaceControlCompat
+import androidx.graphics.surface.SurfaceControlUtils
+import androidx.hardware.SyncFenceCompat
+import androidx.lifecycle.Lifecycle
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class GLFrameBufferRendererTest {
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testSetSyncStrategy() {
+        val latch = CountDownLatch(1)
+
+        val syncStrategy = object : SyncStrategy {
+            override fun createSyncFence(eglSpec: EGLSpec): SyncFenceCompat? {
+                return SyncStrategy.ALWAYS.createSyncFence(eglSpec)
+            }
+        }
+        var fence: SyncFenceCompat? = null
+        var supportsNativeFence = false
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                supportsNativeFence = eglManager.supportsNativeAndroidFence()
+            }
+
+            override fun onDrawComplete(
+                targetSurfaceControl: SurfaceControlCompat,
+                transaction: SurfaceControlCompat.Transaction,
+                frameBuffer: FrameBuffer,
+                syncFence: SyncFenceCompat?
+            ) {
+                fence = syncFence
+                latch.countDown()
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks)
+                        .setSyncStrategy(syncStrategy)
+                        .build().also { fbr ->
+                            fbr.render()
+                        }
+                }
+            scenario.moveToState(Lifecycle.State.RESUMED)
+
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(renderer)
+            assertTrue(renderer!!.isValid())
+            assertTrue(syncStrategy === renderer?.getSyncStrategy())
+            if (supportsNativeFence) {
+                assertNotNull(fence)
+            } else {
+                assertNull(fence)
+            }
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testSetGLRenderer() {
+        val glRenderer = GLRenderer().apply { start() }
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                // NO-OP
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val createLatch = CountDownLatch(1)
+            ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks)
+                        .setGLRenderer(glRenderer)
+                        .build()
+                    createLatch.countDown()
+                }
+
+            assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(renderer)
+            assertTrue(renderer!!.isValid())
+            assertTrue(glRenderer == renderer?.getGLRenderer())
+        } finally {
+            renderer.blockingRelease()
+            glRenderer.stop(true)
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testSetMaxBuffers() {
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                // NO-OP
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val createLatch = CountDownLatch(1)
+            ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks)
+                        .setMaxBuffers(5)
+                        .build()
+                    createLatch.countDown()
+                }
+
+            assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(renderer)
+            assertTrue(renderer!!.isValid())
+            assertEquals(5, renderer?.getMaxBuffers())
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testSetPixelFormat() {
+        val flags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or
+            HardwareBuffer.USAGE_GPU_COLOR_OUTPUT
+        // First verify if another format other than RGBA_8888 is supported
+        if (!HardwareBuffer.isSupported(
+                1, // width
+                1, // height
+                HardwareBuffer.RGBA_FP16, // format
+                1, // layers
+                flags // flags
+            )) {
+            return
+        }
+        var pixelFormat = -1
+        val latch = CountDownLatch(1)
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                // NO-OP
+            }
+
+            override fun onDrawComplete(
+                targetSurfaceControl: SurfaceControlCompat,
+                transaction: SurfaceControlCompat.Transaction,
+                frameBuffer: FrameBuffer,
+                syncFence: SyncFenceCompat?
+            ) {
+                pixelFormat = frameBuffer.hardwareBuffer.format
+                latch.countDown()
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks)
+                        .setPixelFormat(HardwareBuffer.RGBA_FP16)
+                        .build()
+                }
+            scenario.moveToState(Lifecycle.State.RESUMED)
+
+            assertTrue(latch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(renderer)
+            assertTrue(renderer!!.isValid())
+            assertEquals(HardwareBuffer.RGBA_FP16, renderer?.getPixelFormat())
+            assertEquals(HardwareBuffer.RGBA_FP16, pixelFormat)
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testSetUsageFlags() {
+        val latch = CountDownLatch(1)
+        var actualUsageFlags = -1L
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                // NO-OP
+            }
+
+            override fun onDrawComplete(
+                targetSurfaceControl: SurfaceControlCompat,
+                transaction: SurfaceControlCompat.Transaction,
+                frameBuffer: FrameBuffer,
+                syncFence: SyncFenceCompat?
+            ) {
+                actualUsageFlags = frameBuffer.hardwareBuffer.usage
+                latch.countDown()
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val createLatch = CountDownLatch(1)
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks)
+                        .setUsageFlags(
+                            HardwareBuffer.USAGE_GPU_DATA_BUFFER or
+                                HardwareBuffer.USAGE_CPU_READ_RARELY)
+                        .build()
+                    createLatch.countDown()
+                }
+
+            scenario.moveToState(Lifecycle.State.RESUMED)
+
+            assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
+            assertNotNull(renderer)
+            val usageFlags = renderer?.getUsageFlags() ?: 0
+            assertTrue(usageFlags and HardwareBuffer.USAGE_GPU_DATA_BUFFER != 0L)
+            assertTrue(usageFlags and HardwareBuffer.USAGE_CPU_READ_RARELY != 0L)
+            assertTrue(actualUsageFlags and HardwareBuffer.USAGE_GPU_DATA_BUFFER != 0L)
+            assertTrue(actualUsageFlags and HardwareBuffer.USAGE_CPU_READ_RARELY != 0L)
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testExecute() {
+        val executeLatch = CountDownLatch(1)
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray,
+            ) {
+                // NO-OP
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks).build()
+                }
+
+            scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
+                renderer?.execute {
+                    executeLatch.countDown()
+                }
+            }
+
+            assertTrue(executeLatch.await(3000, TimeUnit.MILLISECONDS))
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testRenderFrameBuffer() {
+        val renderLatch = CountDownLatch(1)
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+
+            val mProjectionMatrix = FloatArray(16)
+            val mOrthoMatrix = FloatArray(16)
+
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                GLES20.glViewport(0, 0, bufferInfo.width, bufferInfo.height)
+                Matrix.orthoM(
+                    mOrthoMatrix,
+                    0,
+                    0f,
+                    bufferInfo.width.toFloat(),
+                    0f,
+                    bufferInfo.height.toFloat(),
+                    -1f,
+                    1f
+                )
+                Matrix.multiplyMM(mProjectionMatrix, 0, mOrthoMatrix, 0, transform, 0)
+                Rectangle().draw(mProjectionMatrix, Color.RED, 0f, 0f, 100f, 100f)
+            }
+
+            override fun onDrawComplete(
+                targetSurfaceControl: SurfaceControlCompat,
+                transaction: SurfaceControlCompat.Transaction,
+                frameBuffer: FrameBuffer,
+                syncFence: SyncFenceCompat?
+            ) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+                    transaction.addTransactionCommittedListener(
+                        Executors.newSingleThreadExecutor(),
+                        object : SurfaceControlCompat.TransactionCommittedListener {
+                            override fun onTransactionCommitted() {
+                                renderLatch.countDown()
+                            }
+                        }
+                    )
+                } else {
+                    renderLatch.countDown()
+                }
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView? = null
+        try {
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks).build()
+                }
+
+            scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
+                renderer?.render()
+            }
+            assertTrue(renderLatch.await(3000, TimeUnit.MILLISECONDS))
+
+            val coords = IntArray(2)
+            val width: Int
+            val height: Int
+            with(surfaceView!!) {
+                getLocationOnScreen(coords)
+                width = this.width
+                height = this.height
+            }
+
+            SurfaceControlUtils.validateOutput { bitmap ->
+                Color.RED ==
+                    bitmap.getPixel(coords[0] + width / 2, coords[1] + height / 2)
+            }
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testRenderedOnSurfaceRedraw() {
+        val renderLatch = CountDownLatch(1)
+        val callbacks = object : GLFrameBufferRenderer.Callback {
+
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                renderLatch.countDown()
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceView?
+        try {
+            val scenario = ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+                .moveToState(Lifecycle.State.CREATED)
+                .onActivity {
+                    surfaceView = it.getSurfaceView()
+                    renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callbacks).build()
+                }
+
+            scenario.moveToState(Lifecycle.State.RESUMED)
+            assertTrue(renderLatch.await(3000, TimeUnit.MILLISECONDS))
+        } finally {
+            renderer.blockingRelease()
+        }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.Q)
+    @Test
+    fun testReleaseRemovedSurfaceCallbacks() {
+        val callback = object : GLFrameBufferRenderer.Callback {
+            override fun onDrawFrame(
+                eglManager: EGLManager,
+                bufferInfo: BufferInfo,
+                transform: FloatArray
+            ) {
+                // NO-OP
+            }
+        }
+        var renderer: GLFrameBufferRenderer? = null
+        var surfaceView: SurfaceViewTestActivity.TestSurfaceView? = null
+        val createLatch = CountDownLatch(1)
+        ActivityScenario.launch(SurfaceViewTestActivity::class.java)
+            .moveToState(Lifecycle.State.CREATED)
+            .onActivity {
+                surfaceView = it.getSurfaceView()
+                renderer = GLFrameBufferRenderer.Builder(surfaceView!!, callback).build()
+                createLatch.countDown()
+            }
+
+        assertTrue(createLatch.await(3000, TimeUnit.MILLISECONDS))
+
+        val resolvedSurfaceView = surfaceView
+        try {
+            if (resolvedSurfaceView != null) {
+                assertEquals(1, resolvedSurfaceView.getCallbackCount())
+                val releaseLatch = CountDownLatch(1)
+                renderer!!.release(true) {
+                    releaseLatch.countDown()
+                }
+                assertTrue(releaseLatch.await(3000, TimeUnit.MILLISECONDS))
+                assertEquals(0, resolvedSurfaceView.getCallbackCount())
+                renderer = null
+            } else {
+                fail("Unable to resolve SurfaceView, was the test Activity created?")
+            }
+        } finally {
+            renderer?.blockingRelease()
+        }
+    }
+
+    @RequiresApi(Build.VERSION_CODES.Q)
+    private fun GLFrameBufferRenderer?.blockingRelease(timeoutMillis: Long = 3000) {
+        if (this != null) {
+            val destroyLatch = CountDownLatch(1)
+            release(false) {
+                destroyLatch.countDown()
+            }
+            assertTrue(destroyLatch.await(timeoutMillis, TimeUnit.MILLISECONDS))
+            assertFalse(isValid())
+        } else {
+            fail("GLFrameBufferRenderer is not initialized")
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SurfaceViewTestActivity.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SurfaceViewTestActivity.kt
new file mode 100644
index 0000000..da9d40f
--- /dev/null
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/SurfaceViewTestActivity.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.graphics.opengl
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+import android.view.ViewGroup
+
+class SurfaceViewTestActivity : Activity() {
+
+    private lateinit var mSurfaceView: TestSurfaceView
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val surfaceView = TestSurfaceView(this).also { mSurfaceView = it }
+        setContentView(surfaceView, ViewGroup.LayoutParams(WIDTH, HEIGHT))
+    }
+
+    fun getSurfaceView(): TestSurfaceView = mSurfaceView
+
+    companion object {
+        const val WIDTH = 100
+        const val HEIGHT = 100
+    }
+
+    class TestSurfaceView(context: Context) : SurfaceView(context) {
+
+        private var mHolderWrapper: HolderWrapper? = null
+
+        override fun getHolder(): SurfaceHolder {
+            var wrapper = mHolderWrapper
+            if (wrapper == null) {
+                wrapper = HolderWrapper(super.getHolder()).also { mHolderWrapper = it }
+            }
+            return wrapper
+        }
+
+        fun getCallbackCount(): Int = mHolderWrapper?.mCallbacks?.size ?: 0
+
+        class HolderWrapper(val wrapped: SurfaceHolder) : SurfaceHolder by wrapped {
+
+            val mCallbacks = ArrayList<SurfaceHolder.Callback>()
+
+            override fun addCallback(callback: SurfaceHolder.Callback) {
+                if (!mCallbacks.contains(callback)) {
+                    mCallbacks.add(callback)
+                    wrapped.addCallback(callback)
+                }
+            }
+
+            override fun removeCallback(callback: SurfaceHolder.Callback) {
+                if (mCallbacks.contains(callback)) {
+                    mCallbacks.remove(callback)
+                    wrapped.removeCallback(callback)
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
index 4d9d4b8..e4715d6 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlCompatTest.kt
@@ -16,19 +16,23 @@
 
 package androidx.graphics.surface
 
+import android.annotation.SuppressLint
 import android.graphics.Color
 import android.graphics.ColorSpace
 import android.graphics.Rect
 import android.graphics.Region
+import android.hardware.DataSpace
 import android.opengl.EGL14
 import android.os.Build
 import android.os.SystemClock
+import android.view.Display
 import android.view.SurfaceHolder
 import androidx.graphics.opengl.egl.EGLConfigAttributes
 import androidx.graphics.opengl.egl.EGLManager
 import androidx.graphics.opengl.egl.EGLSpec
 import androidx.graphics.opengl.egl.EGLVersion
 import androidx.graphics.opengl.egl.supportsNativeAndroidFence
+import androidx.graphics.surface.SurfaceControlUtils.Companion.getSolidBuffer
 import androidx.hardware.SyncFenceCompat
 import androidx.lifecycle.Lifecycle
 import androidx.test.core.app.ActivityScenario
@@ -40,9 +44,11 @@
 import java.util.concurrent.Executor
 import java.util.concurrent.Executors
 import java.util.concurrent.TimeUnit
+import java.util.function.Consumer
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertThrows
 import org.junit.Assert.assertTrue
 import org.junit.Assert.fail
 import org.junit.Before
@@ -1891,6 +1897,165 @@
         }
     }
 
+    @SuppressLint("NewApi")
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun testSetExtendedRangeBrightnessThrowsOnUnsupportedPlatforms() {
+        ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
+            .moveToState(
+                Lifecycle.State.CREATED
+            ).onActivity {
+                val callback = object : SurfaceHolderCallback() {
+                    override fun surfaceCreated(sh: SurfaceHolder) {
+
+                        assertThrows(UnsupportedOperationException::class.java) {
+                            val surfaceControl = SurfaceControlCompat.Builder()
+                                .setName("testSurfaceControl")
+                                .setParent(it.mSurfaceView)
+                                .build()
+                            SurfaceControlCompat.Transaction()
+                                .setExtendedRangeBrightness(surfaceControl, 1.0f, 2.0f)
+                                .commit()
+                        }
+                    }
+                }
+
+                it.addSurface(it.mSurfaceView, callback)
+            }
+    }
+
+    @SuppressLint("NewApi")
+    @SdkSuppress(maxSdkVersion = Build.VERSION_CODES.S_V2)
+    @Test
+    fun testSetDataSpaceThrowsOnUnsupportedPlatforms() {
+        ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
+            .moveToState(
+                Lifecycle.State.CREATED
+            ).onActivity {
+                val callback = object : SurfaceHolderCallback() {
+                    override fun surfaceCreated(sh: SurfaceHolder) {
+
+                        assertThrows(UnsupportedOperationException::class.java) {
+                            val surfaceControl = SurfaceControlCompat.Builder()
+                                .setName("testSurfaceControl")
+                                .setParent(it.mSurfaceView)
+                                .build()
+
+                            val extendedDataspace = DataSpace.pack(
+                                DataSpace.STANDARD_BT709,
+                                DataSpace.TRANSFER_SRGB, DataSpace.RANGE_EXTENDED
+                            )
+                            SurfaceControlCompat.Transaction()
+                                .setDataSpace(surfaceControl, extendedDataspace)
+                                .commit()
+                        }
+                    }
+                }
+
+                it.addSurface(it.mSurfaceView, callback)
+            }
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    fun testSetExtendedRangeBrightness() {
+        val scenario = ActivityScenario.launch(SurfaceControlWrapperTestActivity::class.java)
+            .moveToState(
+                Lifecycle.State.CREATED
+            ).onActivity {
+                val display = it.display
+                assertNotNull(display)
+                if (display!!.isHdrSdrRatioAvailable) {
+                    assertEquals(1.0f, display.hdrSdrRatio, .0001f)
+                }
+
+                it.window.attributes.screenBrightness = 0.01f
+                val hdrReady = CountDownLatch(1)
+                val listenerErrors = arrayOfNulls<Exception>(1)
+                if (display.isHdrSdrRatioAvailable) {
+                    display.registerHdrSdrRatioChangedListener(
+                        executor!!,
+                        object : Consumer<Display?> {
+                            var mIsRegistered = true
+                            override fun accept(updatedDisplay: Display?) {
+                                try {
+                                    assertEquals(display.displayId, updatedDisplay!!.displayId)
+                                    assertTrue(mIsRegistered)
+                                    if (display.hdrSdrRatio > 2f) {
+                                        hdrReady.countDown()
+                                        display.unregisterHdrSdrRatioChangedListener(this)
+                                        mIsRegistered = false
+                                    }
+                                } catch (e: Exception) {
+                                    synchronized(it) {
+                                        listenerErrors[0] = e
+                                        hdrReady.countDown()
+                                    }
+                                }
+                            }
+                        })
+                } else {
+                    assertThrows(IllegalStateException::class.java) {
+                        display.registerHdrSdrRatioChangedListener(
+                            executor!!,
+                            Consumer { _: Display? -> })
+                    }
+                }
+                val extendedDataspace = DataSpace.pack(DataSpace.STANDARD_BT709,
+                    DataSpace.TRANSFER_SRGB, DataSpace.RANGE_EXTENDED)
+                val buffer = getSolidBuffer(
+                    SurfaceControlWrapperTestActivity.DEFAULT_WIDTH,
+                    SurfaceControlWrapperTestActivity.DEFAULT_HEIGHT,
+                    Color.RED)
+                val callback = object : SurfaceHolderCallback() {
+                    override fun surfaceCreated(sh: SurfaceHolder) {
+                        val scCompat = SurfaceControlCompat
+                            .Builder()
+                            .setParent(it.getSurfaceView())
+                            .setName("SurfaceControlCompatTest")
+                            .build()
+
+                        SurfaceControlCompat.Transaction()
+                            .setBuffer(scCompat, buffer)
+                            .setDataSpace(scCompat, extendedDataspace)
+                            .setExtendedRangeBrightness(scCompat, 1.0f, 3.0f)
+                            .setVisibility(scCompat, true)
+                            .commit()
+                    }
+                }
+
+                it.addSurface(it.mSurfaceView, callback)
+            }
+
+        scenario.moveToState(Lifecycle.State.RESUMED).onActivity {
+            SurfaceControlUtils.validateOutput(it.window) { bitmap ->
+                val coord = intArrayOf(0, 0)
+                it.mSurfaceView.getLocationInWindow(coord)
+                val topLeft = bitmap.getPixel(
+                    coord[0] + 2,
+                    coord[1] + 2
+                )
+                val topRight = bitmap.getPixel(
+                    coord[0] + it.mSurfaceView.width - 2,
+                    coord[1] + 2
+                )
+                val bottomLeft = bitmap.getPixel(
+                    coord[0] + 2,
+                    coord[1] + it.mSurfaceView.height - 2
+                )
+                val bottomRight = bitmap.getPixel(
+                    coord[0] + it.mSurfaceView.width - 2,
+                    coord[1] + it.mSurfaceView.height - 2
+                )
+
+                Color.RED == topLeft &&
+                    topLeft == topRight &&
+                    bottomLeft == topRight &&
+                    bottomLeft == bottomRight
+            }
+        }
+    }
+
     fun Color.compositeOver(background: Color): Color {
         val fg = this.convert(background.colorSpace)
 
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
index 91a79e35..ead3b1d 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/surface/SurfaceControlUtils.kt
@@ -20,7 +20,10 @@
 import android.graphics.Bitmap
 import android.graphics.Color
 import android.hardware.HardwareBuffer
+import android.os.Build
 import android.os.SystemClock
+import android.view.Window
+import androidx.annotation.RequiresApi
 import androidx.test.filters.SdkSuppress
 import androidx.test.platform.app.InstrumentationRegistry
 import org.junit.Assert
@@ -28,6 +31,18 @@
 @SdkSuppress(minSdkVersion = 29)
 internal class SurfaceControlUtils {
     companion object {
+
+        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        fun validateOutput(window: Window, block: (bitmap: Bitmap) -> Boolean) {
+            val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
+            val bitmap = uiAutomation.takeScreenshot(window)
+            if (bitmap != null) {
+                block(bitmap)
+            } else {
+                throw IllegalArgumentException("Unable to obtain bitmap from screenshot")
+            }
+        }
+
         fun validateOutput(block: (bitmap: Bitmap) -> Boolean) {
             var sleepDurationMillis = 1000L
             var success = false
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
index 8a66107..ffc799b 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRenderer.kt
@@ -19,8 +19,10 @@
 import android.graphics.Canvas
 import android.hardware.HardwareBuffer
 import android.os.Build
+import androidx.annotation.OptIn
 import androidx.annotation.RequiresApi
 import androidx.annotation.WorkerThread
+import androidx.core.os.BuildCompat
 import androidx.hardware.SyncFenceCompat
 import java.util.concurrent.Executor
 
@@ -28,6 +30,7 @@
  * Interface to provide an abstraction around implementations for a low latency hardware
  * accelerated [Canvas] that provides a [HardwareBuffer] with the [Canvas] rendered scene
  */
+@RequiresApi(Build.VERSION_CODES.Q)
 internal interface SingleBufferedCanvasRenderer<T> {
 
     interface RenderCallbacks<T> {
@@ -67,7 +70,7 @@
 
     companion object {
 
-        @RequiresApi(Build.VERSION_CODES.Q)
+        @OptIn(markerClass = [BuildCompat.PrereleaseSdkCheck::class])
         fun <T> create(
             width: Int,
             height: Int,
@@ -75,14 +78,23 @@
             executor: Executor,
             bufferReadyListener: RenderCallbacks<T>
         ): SingleBufferedCanvasRenderer<T> {
-            // TODO return different instance for corresponding platform version
-            return SingleBufferedCanvasRendererV29(
-                width,
-                height,
-                bufferTransformer,
-                executor,
-                bufferReadyListener
-            )
+            return if (BuildCompat.isAtLeastU()) {
+                SingleBufferedCanvasRendererV34(
+                    width,
+                    height,
+                    bufferTransformer,
+                    executor,
+                    bufferReadyListener
+                )
+            } else {
+                SingleBufferedCanvasRendererV29(
+                    width,
+                    height,
+                    bufferTransformer,
+                    executor,
+                    bufferReadyListener
+                )
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34.kt
new file mode 100644
index 0000000..114a8c2
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/SingleBufferedCanvasRendererV34.kt
@@ -0,0 +1,160 @@
+/*
+ * 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.graphics.lowlatency
+
+import android.graphics.BlendMode
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.HardwareBufferRenderer
+import android.graphics.RenderNode
+import android.hardware.HardwareBuffer
+import android.os.Handler
+import android.os.HandlerThread
+import android.os.SystemClock
+import androidx.annotation.RequiresApi
+import androidx.hardware.SyncFenceCompat
+import java.util.concurrent.Executor
+
+@RequiresApi(34)
+internal class SingleBufferedCanvasRendererV34<T>(
+    private val width: Int,
+    private val height: Int,
+    private val bufferTransformer: BufferTransformer,
+    private val executor: Executor,
+    private val callbacks: SingleBufferedCanvasRenderer.RenderCallbacks<T>
+) : SingleBufferedCanvasRenderer<T> {
+
+    private val mRenderNode = RenderNode("node").apply {
+        setPosition(
+            0,
+            0,
+            width,
+            height
+        )
+        clipToBounds = false
+    }
+
+    private val mInverseTransform =
+        bufferTransformer.invertBufferTransform(bufferTransformer.computedTransform)
+    private val mHandlerThread = HandlerThread("renderRequestThread").apply { start() }
+    private val mHandler = Handler(mHandlerThread.looper)
+
+    private inline fun dispatchOnExecutor(crossinline block: () -> Unit) {
+        executor.execute {
+            block()
+        }
+    }
+
+    private inline fun doRender(block: (Canvas) -> Unit) {
+        val canvas = mRenderNode.beginRecording()
+        block(canvas)
+        mRenderNode.endRecording()
+
+        mHardwareBufferRenderer.obtainRenderRequest().apply {
+            if (mInverseTransform != BufferTransformHintResolver.UNKNOWN_TRANSFORM) {
+                setBufferTransform(mInverseTransform)
+            }
+            draw(executor) { result ->
+                callbacks.onBufferReady(mHardwareBuffer, SyncFenceCompat(result.fence))
+            }
+        }
+    }
+
+    private fun tearDown() {
+        mHardwareBufferRenderer.close()
+        mHandlerThread.quit()
+    }
+
+    private val mHardwareBuffer = HardwareBuffer.create(
+        bufferTransformer.glWidth,
+        bufferTransformer.glHeight,
+        HardwareBuffer.RGBA_8888,
+        1,
+        FrontBufferUtils.obtainHardwareBufferUsageFlags()
+    )
+
+    private val mHardwareBufferRenderer = HardwareBufferRenderer(mHardwareBuffer).apply {
+        setContentRoot(mRenderNode)
+    }
+
+    private var mIsReleasing = false
+
+    override fun render(param: T) {
+        if (!mIsReleasing) {
+            mHandler.post(RENDER) {
+                dispatchOnExecutor {
+                    doRender { canvas ->
+                        callbacks.render(canvas, width, height, param)
+                    }
+                }
+            }
+        }
+    }
+
+    override var isVisible: Boolean = false
+
+    override fun release(cancelPending: Boolean, onReleaseComplete: (() -> Unit)?) {
+        if (!mIsReleasing) {
+            if (cancelPending) {
+                cancelPending()
+            }
+            mHandler.post(RELEASE) {
+                tearDown()
+                if (onReleaseComplete != null) {
+                    dispatchOnExecutor {
+                        onReleaseComplete.invoke()
+                    }
+                }
+            }
+            mIsReleasing = true
+        }
+    }
+
+    override fun clear() {
+        if (!mIsReleasing) {
+            mHandler.post(CLEAR) {
+                dispatchOnExecutor {
+                    doRender { canvas ->
+                        canvas.drawColor(Color.BLACK, BlendMode.CLEAR)
+                    }
+                }
+            }
+        }
+    }
+
+    override fun cancelPending() {
+        if (!mIsReleasing) {
+            mHandler.removeCallbacksAndMessages(CLEAR)
+            mHandler.removeCallbacksAndMessages(RENDER)
+        }
+    }
+
+    private companion object {
+        const val RENDER = 0
+        const val CLEAR = 1
+        const val RELEASE = 2
+    }
+
+    /**
+     * Handler does not expose a post method that takes a token and a runnable.
+     * We need the token to be able to cancel pending requests so just call
+     * postAtTime with the default of SystemClock.uptimeMillis
+     */
+    private fun Handler.post(token: Any?, runnable: Runnable) {
+        postAtTime(runnable, token, SystemClock.uptimeMillis())
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLFrameBufferRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLFrameBufferRenderer.kt
new file mode 100644
index 0000000..28c9f05
--- /dev/null
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/GLFrameBufferRenderer.kt
@@ -0,0 +1,771 @@
+/*
+ * 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.graphics.opengl
+
+import android.hardware.HardwareBuffer
+import android.opengl.GLES20
+import android.opengl.Matrix
+import android.os.Build
+import android.util.Log
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+import androidx.annotation.RequiresApi
+import androidx.annotation.WorkerThread
+import androidx.graphics.lowlatency.BufferInfo
+import androidx.graphics.lowlatency.BufferTransformHintResolver
+import androidx.graphics.lowlatency.BufferTransformer
+import androidx.graphics.opengl.egl.EGLManager
+import androidx.graphics.opengl.egl.EGLSpec
+import androidx.graphics.surface.SurfaceControlCompat
+import androidx.hardware.SyncFenceCompat
+import java.lang.IllegalArgumentException
+import java.lang.IllegalStateException
+import java.util.concurrent.CountDownLatch
+
+/**
+ * Class responsible for supporting rendering to frame buffer objects that are backed by
+ * [HardwareBuffer] instances. This provides for more flexibility in OpenGL rendering as it supports
+ * configuration of the number of buffers within the underlying swap chain, pixel format of the
+ * buffers as well as fine grained control over synchronization of buffer content.
+ */
+@RequiresApi(Build.VERSION_CODES.Q)
+@Suppress("AcronymName")
+class GLFrameBufferRenderer internal constructor(
+    private val surfaceControlProvider: SurfaceControlProvider,
+    callback: Callback,
+    private val format: Int,
+    private val usage: Long,
+    private val maxBuffers: Int,
+    private val syncStrategy: SyncStrategy,
+    glRenderer: GLRenderer?
+) {
+
+    private val surfaceControlProviderCallbacks = object : SurfaceControlProvider.Callback {
+        override fun destroySurfaceControl() {
+            detachTargets(true)
+        }
+
+        override fun onSurfaceControlCreated(
+            surfaceControl: SurfaceControlCompat,
+            width: Int,
+            height: Int,
+            bufferTransformer: BufferTransformer,
+            inverseTransform: Int
+        ) {
+            val frameBufferPool = FrameBufferPool(
+                bufferTransformer.glWidth,
+                bufferTransformer.glHeight,
+                this@GLFrameBufferRenderer.format,
+                usage,
+                maxBuffers
+            )
+            val renderCallback = createFrameBufferRenderer(
+                surfaceControl,
+                inverseTransform,
+                bufferTransformer,
+                frameBufferPool,
+                callback
+            )
+            mBufferPool = frameBufferPool
+            mSurfaceControl = surfaceControl
+            mRenderTarget = mGLRenderer.createRenderTarget(width, height, renderCallback)
+        }
+
+        override fun requestRender(renderComplete: Runnable?) {
+            drawAsync(renderComplete)
+        }
+    }
+
+    /**
+     * Builder used to create a [GLFrameBufferRenderer] with various configurations
+     */
+    class Builder {
+        private var mPixelFormat = HardwareBuffer.RGBA_8888
+        private var mUsageFlags = DefaultFlags
+        private var mMaxBuffers = DefaultNumBuffers
+        private var mGLRenderer: GLRenderer? = null
+        private var mSyncStrategy: SyncStrategy = SyncStrategy.ALWAYS
+        private val mSurfaceControlProvider: SurfaceControlProvider
+        private val mCallback: Callback
+
+        /**
+         * Create a new [GLFrameBufferRenderer.Builder] with the provided [SurfaceView] to
+         * be the parent of the [SurfaceControlCompat] that is presented on screen.
+         * @param surfaceView SurfaceView to be the parent of the [SurfaceControlCompat] instance
+         * used for presenting rendered content on screen
+         * @param callback Callback used to render content within the corresponding buffers as well
+         * as optionally configuring [SurfaceControlCompat.Transaction] to present contents to the
+         * display
+         */
+        constructor(surfaceView: SurfaceView, callback: Callback) {
+            mSurfaceControlProvider = SurfaceViewProvider(surfaceView)
+            mCallback = callback
+        }
+
+        /**
+         * Creates a new [GLFrameBufferRenderer.Builder] with the provided [SurfaceControlCompat]
+         * as the parent [SurfaceControlCompat] for presenting contents to the display.
+         *
+         * @param parentSurfaceControl Parent [SurfaceControlCompat] instance.
+         * @param width Logical width of the buffers to be rendered into. This would correspond to
+         * the width of a [android.view.View].
+         * @param height Logical height of the buffers to be rendered into. This would correspond to
+         * the height of a [android.view.View].
+         * @param transformHint Hint used to specify how to pre-rotate content to optimize
+         * consumption of content by the display without having to introduce an additional GPU pass
+         * to handle rotation.
+         */
+        internal constructor(
+            parentSurfaceControl: SurfaceControlCompat,
+            width: Int,
+            height: Int,
+            transformHint: Int,
+            callback: Callback
+        ) {
+            mSurfaceControlProvider = DefaultSurfaceControlProvider(
+                parentSurfaceControl,
+                width,
+                height,
+                transformHint
+            )
+            mCallback = callback
+        }
+
+        /**
+         * Specify the [SyncStrategy] used for determining when to create [SyncFenceCompat]
+         * objects in order to handle synchronization. The [SyncFenceCompat] instance created
+         * according to the algorithm specified in the provided [SyncStrategy] will be passed
+         * to the corresponding [SurfaceControlCompat.Transaction.setBuffer] call in order to
+         * ensure the underlying buffer is not presented by the display until the fence signals.
+         *
+         * @param syncStrategy [SyncStrategy] used to determine when to create synchronization
+         * boundaries for buffer consumption. The default is [SyncStrategy.ALWAYS], indicating a
+         * fence should always be created after a request to render has been made.
+         *
+         * @return The builder instance
+         */
+        fun setSyncStrategy(syncStrategy: SyncStrategy): Builder {
+            mSyncStrategy = syncStrategy
+            return this
+        }
+
+        /**
+         * Specify the pixel format of the underlying buffers being rendered into by the created
+         * [GLFrameBufferRenderer].
+         *
+         * @param format Pixel format of the buffers to be rendered into. The default is RGBA_8888.
+         *
+         * @return The builder instance
+         */
+        fun setPixelFormat(format: Int): Builder {
+            mPixelFormat = format
+            return this
+        }
+
+        /**
+         * Specify the maximum number of buffers used within the swap chain of the
+         * [GLFrameBufferRenderer].
+         * If 1 is specified, then the created [GLFrameBufferRenderer] is running in "single buffer
+         * mode". In this case consumption of the buffer content would need to be coordinated with
+         * the [SyncFenceCompat] instance specified by the corresponding [SyncStrategy] algorithm
+         * @see [setSyncStrategy].
+         *
+         * @param numBuffers The number of buffers within the swap chain to be consumed by the
+         * created [GLFrameBufferRenderer]. This must be greater than zero.
+         *
+         * @return The builder instance
+         */
+        fun setMaxBuffers(numBuffers: Int): Builder {
+            require(numBuffers > 0) { "Must have at least 1 buffer" }
+            mMaxBuffers = numBuffers
+            return this
+        }
+
+        /**
+         * Specify the usage flags to be configured on the underlying [HardwareBuffer] instances
+         * created by the [GLFrameBufferRenderer].
+         *
+         * @param usageFlags Usage flags to be configured on the created [HardwareBuffer] instances
+         * that the [GLFrameBufferRenderer] will render into.
+         *
+         * @return The builder instance
+         */
+        fun setUsageFlags(usageFlags: Long): Builder {
+            mUsageFlags = usageFlags or DefaultFlags
+            return this
+        }
+
+        /**
+         * Configure the [GLRenderer] instance to be used by the [GLFrameBufferRenderer].
+         * By default this parameter is null indicating that the [GLFrameBufferRenderer] will
+         * create and manage its own [GLRenderer]. This is useful to share the same OpenGL
+         * resources and thread across multiple [GLFrameBufferRenderer] instances.
+         *
+         * @param glRenderer The [GLRenderer] used for leveraging OpenGL resources including the
+         * GL thread
+         *
+         * @return The builder instance
+         */
+        @Suppress("AcronymName")
+        fun setGLRenderer(glRenderer: GLRenderer?): Builder {
+            mGLRenderer = glRenderer
+            return this
+        }
+
+        /**
+         * Create the [GLFrameBufferRenderer] with the specified parameters on this [Builder]
+         * instance
+         *
+         * @return The newly created [GLFrameBufferRenderer]
+         */
+        fun build(): GLFrameBufferRenderer {
+            return GLFrameBufferRenderer(
+                mSurfaceControlProvider,
+                mCallback,
+                mPixelFormat,
+                mUsageFlags,
+                mMaxBuffers,
+                mSyncStrategy,
+                mGLRenderer
+            )
+        }
+    }
+
+    private var mSurfaceControl: SurfaceControlCompat? = null
+    private var mBufferPool: FrameBufferPool? = null
+    private var mRenderTarget: GLRenderer.RenderTarget? = null
+
+    private val mIsManagingGLRenderer: Boolean
+    private var mIsReleased = false
+    private val mContextCallbacks = object : GLRenderer.EGLContextCallback {
+        override fun onEGLContextCreated(eglManager: EGLManager) {
+            // NO-OP
+        }
+
+        override fun onEGLContextDestroyed(eglManager: EGLManager) {
+            tearDown(mBufferPool, mSurfaceControl)
+        }
+    }
+
+    private val mGLRenderer: GLRenderer
+
+    init {
+        if (maxBuffers < 1) {
+            throw IllegalArgumentException("FrameBufferRenderer must have at least 1 buffer")
+        }
+        val renderer = if (glRenderer == null) {
+            mIsManagingGLRenderer = true
+            GLRenderer().apply { start() }
+        } else {
+            mIsManagingGLRenderer = false
+            if (!glRenderer.isRunning()) {
+                throw IllegalStateException("The provided GLRenderer must be running prior to " +
+                    "creation of GLFrameBufferRenderer, " +
+                    "did you forget to call GLRenderer#start()?")
+            }
+            glRenderer
+        }
+        renderer.registerEGLContextCallback(mContextCallbacks)
+        surfaceControlProvider.createSurfaceControl(surfaceControlProviderCallbacks)
+        mGLRenderer = renderer
+    }
+
+    /**
+     * Queue a [Runnable] to be executed on the GL rendering thread. Note it is important
+     * this [Runnable] does not block otherwise it can stall the GL thread.
+     *
+     * @param runnable to be executed
+     */
+    fun execute(runnable: Runnable) {
+        if (isValid()) {
+            mGLRenderer.execute(runnable)
+        } else {
+            Log.w(TAG, "Attempt to execute runnable after " +
+                    "GLFrameBufferRenderer has been released")
+        }
+    }
+
+    /**
+     * Returns the pixel format of the buffers that are being rendered into by this
+     * [GLFrameBufferRenderer]
+     */
+    fun getPixelFormat(): Int = format
+
+    /**
+     * Returns the current usage flag hints of the buffers that are being rendered into by this
+     * [GLFrameBufferRenderer]
+     */
+    fun getUsageFlags(): Long = usage
+
+    /**
+     * Returns the [GLRenderer] used for issuing requests to render into the underlying buffers
+     * with OpenGL.
+     */
+    @Suppress("AcronymName")
+    fun getGLRenderer(): GLRenderer = mGLRenderer
+
+    /**
+     * Returns the [SyncStrategy] used for determining when to create [SyncFenceCompat]
+     * objects in order to handle synchronization. The [SyncFenceCompat] instance created
+     * according to the algorithm specified in the provided [SyncStrategy] will be passed
+     * to the corresponding [SurfaceControlCompat.Transaction.setBuffer] call in order to
+     * ensure the underlying buffer is not presented by the display until the fence signals.
+     */
+    fun getSyncStrategy(): SyncStrategy = syncStrategy
+
+    /**
+     * Returns the number of buffers within the swap chain used for rendering with this
+     * [GLFrameBufferRenderer]
+     */
+    fun getMaxBuffers(): Int = maxBuffers
+
+    internal fun createFrameBufferRenderer(
+        surfaceControl: SurfaceControlCompat,
+        inverseTransform: Int,
+        bufferTransformer: BufferTransformer,
+        frameBufferPool: FrameBufferPool,
+        callback: Callback
+    ): FrameBufferRenderer = FrameBufferRenderer(
+        object : FrameBufferRenderer.RenderCallback {
+
+            private val bufferInfo = BufferInfo().apply {
+                this.width = bufferTransformer.glWidth
+                this.height = bufferTransformer.glHeight
+            }
+
+            private var mCurrentFrameBuffer: FrameBuffer? = null
+
+            override fun obtainFrameBuffer(egl: EGLSpec): FrameBuffer {
+                val currentFrameBuffer = mCurrentFrameBuffer
+                // Single buffer mode if we already allocated 1 buffer just return the previous one
+                return if (maxBuffers == 1 && currentFrameBuffer != null) {
+                    currentFrameBuffer
+                } else {
+                    frameBufferPool.obtain(egl).also {
+                        bufferInfo.frameBufferId = it.frameBuffer
+                        mCurrentFrameBuffer = it
+                    }
+                }
+            }
+
+            override fun onDraw(eglManager: EGLManager) {
+                callback.onDrawFrame(eglManager, bufferInfo, bufferTransformer.transform)
+            }
+
+            override fun onDrawComplete(
+                frameBuffer: FrameBuffer,
+                syncFenceCompat: SyncFenceCompat?
+            ) {
+                val transaction = SurfaceControlCompat.Transaction()
+                    .setVisibility(surfaceControl, true)
+                    .setBuffer(surfaceControl, frameBuffer.hardwareBuffer, syncFenceCompat) {
+                        if (maxBuffers > 1) {
+                            // Release the previous buffer only if we are not in single buffered
+                            // mode
+                            frameBufferPool.release(frameBuffer)
+                        }
+                    }
+                if (inverseTransform != BufferTransformHintResolver.UNKNOWN_TRANSFORM) {
+                    transaction.setBufferTransform(surfaceControl, inverseTransform)
+                }
+                callback.onDrawComplete(surfaceControl, transaction, frameBuffer, syncFenceCompat)
+                transaction.commit()
+            }
+        },
+        syncStrategy
+    )
+
+    internal fun drawAsync(onComplete: Runnable? = null) {
+        val renderTarget = mRenderTarget
+        val renderer = mGLRenderer
+        if (renderTarget != null && renderer.isRunning()) {
+            // Register a callback in case the GLRenderer is torn down while we are waiting
+            // for rendering to complete. In this case invoke the drawFinished callback
+            // either if the render is complete or if the GLRenderer is torn down, whatever
+            // comes first
+            val eglContextCallback = object : GLRenderer.EGLContextCallback {
+                override fun onEGLContextCreated(eglManager: EGLManager) {
+                    // NO-OP
+                }
+
+                override fun onEGLContextDestroyed(eglManager: EGLManager) {
+                    onComplete?.run()
+                    renderer.unregisterEGLContextCallback(this)
+                }
+            }
+            renderer.registerEGLContextCallback(eglContextCallback)
+            mRenderTarget?.requestRender {
+                onComplete?.run()
+                renderer.unregisterEGLContextCallback(eglContextCallback)
+            }
+        } else {
+            onComplete?.run()
+        }
+    }
+
+    /**
+     * Release resources associated with the [GLFrameBufferRenderer]. After this method is invoked,
+     * the [GLFrameBufferRenderer] is in an invalid state and can no longer handle rendering
+     * content.
+     *
+     * @param cancelPending Flag to indicate that in process requests should be completed before
+     * the [GLFrameBufferRenderer] is released.
+     * @param onReleaseCallback Optional callback to be invoked on the underlying OpenGL thread when
+     * releasing resources has been completed
+     */
+    @JvmOverloads
+    fun release(cancelPending: Boolean, onReleaseCallback: (() -> Unit)? = null) {
+        if (!mIsReleased) {
+            surfaceControlProvider.release()
+
+            detachTargets(cancelPending, onReleaseCallback)
+
+            mGLRenderer.unregisterEGLContextCallback(mContextCallbacks)
+            if (mIsManagingGLRenderer) {
+                mGLRenderer.stop(false)
+            }
+
+            mIsReleased = true
+        } else {
+            Log.w(TAG, "Attempt to release already released GLFrameBufferRenderer")
+        }
+    }
+
+    @WorkerThread
+    internal fun tearDown(
+        frameBufferPool: FrameBufferPool?,
+        surfaceControl: SurfaceControlCompat?
+    ) {
+        frameBufferPool?.close()
+        if (surfaceControl != null) {
+            // Reparent the surface control to remove its contents from the display
+            SurfaceControlCompat.Transaction()
+                .reparent(surfaceControl, null)
+                .commit()
+            surfaceControl.release()
+        }
+    }
+
+    internal fun detachTargets(cancelPending: Boolean, onReleaseComplete: (() -> Unit)? = null) {
+        val frameBufferPool = mBufferPool
+        val surfaceControl = mSurfaceControl
+        val renderTarget = mRenderTarget
+        renderTarget?.detach(cancelPending)
+
+        mGLRenderer.execute {
+            tearDown(frameBufferPool, surfaceControl)
+            onReleaseComplete?.invoke()
+        }
+        mBufferPool = null
+        mSurfaceControl = null
+        mRenderTarget = null
+    }
+
+    /**
+     * Determines whether or not the [GLFrameBufferRenderer] is in a valid state. That is the
+     * [release] method has not been called.
+     * If this returns false, then subsequent calls to [render], and
+     * [release] are ignored
+     *
+     * @return `true` if this [GLFrameBufferRenderer] has been released, `false` otherwise
+     */
+    fun isValid(): Boolean = !mIsReleased
+
+    /**
+     * Render content to a buffer and present the result to the display.
+     *
+     * If this [GLFrameBufferRenderer] has been released, that is [isValid] returns `false`, this
+     * call is ignored.
+     */
+    fun render() {
+        if (!mIsReleased) {
+            mRenderTarget?.requestRender()
+        } else {
+            Log.w(TAG, "renderer is released, ignoring request")
+        }
+    }
+
+    /**
+     * [GLFrameBufferRenderer] callbacks that are invoked to render OpenGL content within the
+     * underlying buffers. This includes an optional callback to be used to configure the
+     * underlying [SurfaceControlCompat.Transaction] used to present content to the display
+     */
+    interface Callback {
+
+        /**
+         * Callback invoked to render content into a buffer with the specified
+         * parameters.
+         * @param eglManager [EGLManager] useful in configuring EGL objects to be used when issuing
+         * OpenGL commands to render into the front buffered layer
+         * @param bufferInfo [BufferInfo] about the buffer that is being rendered into. This
+         * includes the width and height of the buffer which can be different than the corresponding
+         * dimensions of the [SurfaceView] provided to the [GLFrameBufferRenderer] as pre-rotation
+         * can occasionally swap width and height parameters in order to avoid GPU composition to
+         * rotate content. This should be used as input to [GLES20.glViewport].
+         * Additionally this also contains a frame buffer identifier that can be used to retarget
+         * rendering operations to the original destination after rendering into intermediate
+         * scratch buffers.
+         * @param transform Matrix that should be applied to the rendering in this callback.
+         * This should be consumed as input to any vertex shader implementations. Buffers are
+         * pre-rotated in advance in order to avoid unnecessary overhead of GPU composition to
+         * rotate content in the same install orientation of the display.
+         * This is a 4 x 4 matrix is represented as a flattened array of 16 floating point values.
+         * Consumers are expected to leverage [Matrix.multiplyMM] with this parameter alongside
+         * any additional transformations that are to be applied.
+         * For example:
+         * ```
+         * val myMatrix = FloatArray(16)
+         * Matrix.orthoM(
+         *      myMatrix, // matrix
+         *      0, // offset starting index into myMatrix
+         *      0f, // left
+         *      bufferInfo.bufferWidth.toFloat(), // right
+         *      0f, // bottom
+         *      bufferInfo.bufferHeight.toFloat(), // top
+         *      -1f, // near
+         *      1f, // far
+         * )
+         * val result = FloatArray(16)
+         * Matrix.multiplyMM(result, 0, myMatrix, 0, transform, 0)
+         * ```
+         */
+        @WorkerThread
+        fun onDrawFrame(
+            eglManager: EGLManager,
+            bufferInfo: BufferInfo,
+            transform: FloatArray
+        )
+
+        /**
+         * Optional callback invoked when rendering to a buffer is complete but before the buffer
+         * is submitted to the hardware compositor.
+         * This provides consumers a mechanism for synchronizing the transaction with other
+         * [SurfaceControlCompat] objects that maybe rendered within the scene.
+         *
+         * @param targetSurfaceControl Handle to the [SurfaceControlCompat] where the
+         * buffer is presented. This can be used to configure various properties
+         * of the [SurfaceControlCompat] like z-ordering or visibility with the corresponding
+         * [SurfaceControlCompat.Transaction].
+         * @param transaction Current [SurfaceControlCompat.Transaction] to apply updated buffered
+         * content to the front buffered layer.
+         * @param frameBuffer The buffer that has been rendered into and is ready to be displayed.
+         * The [HardwareBuffer] backing this [FrameBuffer] is already configured to be presented
+         * for the targetSurfaceControl. That is [SurfaceControlCompat.Transaction.setBuffer] is
+         * already invoked with the given [HardwareBuffer] and optional [SyncFenceCompat] instance
+         * before this method is invoked.
+         * @param syncFence Optional [SyncFenceCompat] is used to determine when rendering
+         * is done and reflected within the given frameBuffer.
+         */
+        @WorkerThread
+        fun onDrawComplete(
+            targetSurfaceControl: SurfaceControlCompat,
+            transaction: SurfaceControlCompat.Transaction,
+            frameBuffer: FrameBuffer,
+            syncFence: SyncFenceCompat?
+        ) {
+            // NO-OP
+        }
+    }
+
+    /**
+     * Provider interface used to delegate creation and potential lifecycle callbacks associated
+     * with the corresponding [SurfaceControlCompat] instance
+     */
+    internal interface SurfaceControlProvider {
+
+        /**
+         * Request a [SurfaceControlCompat] to be created and invokes the corresponding callback
+         * when the created [SurfaceControlCompat] instance is ready for consumption
+         */
+        fun createSurfaceControl(callback: Callback)
+
+        /**
+         * Release resources associated with the [SurfaceControlProvider]
+         */
+        fun release()
+
+        /**
+         * Callbacks invoked by the [SurfaceControlProvider] to consumers of the created
+         * [SurfaceControlCompat] instance
+         */
+        interface Callback {
+
+            /**
+             * Callback invoked when resources associated with the created [SurfaceControlCompat]
+             * instance should be destroyed
+             */
+            fun destroySurfaceControl()
+
+            /**
+             * Callback invoked when the [SurfaceControlCompat] is created. This includes
+             * the logical width/height as well as a [BufferTransformer] instance that provides
+             * the metadata necessary to pre-rotate content
+             */
+            fun onSurfaceControlCreated(
+                surfaceControl: SurfaceControlCompat,
+                width: Int,
+                height: Int,
+                bufferTransformer: BufferTransformer,
+                inverseTransform: Int
+            )
+
+            /**
+             * Requests the consumer of the [SurfaceControlCompat] instance to render content
+             * to be presented by the [SurfaceControlCompat] instance and invoke a callback when
+             * rendering is complete.
+             */
+            fun requestRender(renderComplete: Runnable? = null)
+        }
+    }
+
+    /**
+     * Default [SurfaceControlProvider] instance that returns the dependencies given to it
+     * to the consumer of the [SurfaceControlCompat]
+     */
+    internal class DefaultSurfaceControlProvider(
+        private val surfaceControl: SurfaceControlCompat,
+        private val width: Int,
+        private val height: Int,
+        private val transformHint: Int,
+    ) : SurfaceControlProvider {
+
+        private val bufferTransformer = BufferTransformer()
+
+        override fun createSurfaceControl(callback: SurfaceControlProvider.Callback) {
+            val inverse = bufferTransformer.invertBufferTransform(transformHint)
+            bufferTransformer.computeTransform(width, height, inverse)
+            callback.onSurfaceControlCreated(
+                surfaceControl,
+                width,
+                height,
+                bufferTransformer,
+                inverse
+            )
+        }
+
+        override fun release() {
+            // NO-OP
+        }
+    }
+
+    /**
+     * [SurfaceControlProvider] instance that creates a [SurfaceControlCompat] instance with the
+     * provided SurfaceView as the parent of the created [SurfaceControlCompat]. This implementation
+     * handles all lifecycle callbacks associated with the underlying SurfaceHolder.Callback
+     * attached to the holder on the given SurfaceView.
+     */
+    internal class SurfaceViewProvider(
+        private var surfaceView: SurfaceView?
+    ) : SurfaceControlProvider {
+        private val mTransformResolver = BufferTransformHintResolver()
+
+        private var mSurfaceHolderCallback: SurfaceHolder.Callback2? = null
+
+        internal fun createSurfaceControl(
+            surfaceView: SurfaceView,
+            callback: SurfaceControlProvider.Callback
+        ) {
+            callback.destroySurfaceControl()
+            val width = surfaceView.width
+            val height = surfaceView.height
+            val transformHint = mTransformResolver.getBufferTransformHint(surfaceView)
+            val bufferTransformer = BufferTransformer()
+            val inverse = bufferTransformer.invertBufferTransform(transformHint)
+            bufferTransformer.computeTransform(surfaceView.width, surfaceView.height, inverse)
+            val surfaceControl = SurfaceControlCompat.Builder()
+                .setName("GLFrameBufferRendererTarget")
+                .setParent(surfaceView)
+                .build()
+
+            callback.onSurfaceControlCreated(
+                surfaceControl,
+                width,
+                height,
+                bufferTransformer,
+                inverse
+            )
+        }
+
+        override fun createSurfaceControl(callback: SurfaceControlProvider.Callback) {
+            surfaceView?.let { target ->
+                val surfaceHolderCallback = object : SurfaceHolder.Callback2 {
+                    override fun surfaceCreated(holder: SurfaceHolder) {
+                        // NO-OP wait for surfaceChanged callback
+                    }
+
+                    override fun surfaceChanged(
+                        holder: SurfaceHolder,
+                        surfaceFormat: Int,
+                        width: Int,
+                        height: Int
+                    ) {
+                        createSurfaceControl(target, callback)
+                    }
+
+                    override fun surfaceDestroyed(p0: SurfaceHolder) {
+                        callback.destroySurfaceControl()
+                    }
+
+                    override fun surfaceRedrawNeeded(p0: SurfaceHolder) {
+                        val latch = CountDownLatch(1)
+                        callback.requestRender { latch.countDown() }
+                        latch.await()
+                    }
+
+                    override fun surfaceRedrawNeededAsync(
+                        holder: SurfaceHolder,
+                        drawingFinished: Runnable
+                    ) {
+                        callback.requestRender(drawingFinished)
+                    }
+                }
+                val holder = target.holder
+                holder.addCallback(surfaceHolderCallback)
+                if (holder.surface != null && holder.surface.isValid) {
+                    createSurfaceControl(target, callback)
+                }
+                mSurfaceHolderCallback = surfaceHolderCallback
+            }
+        }
+
+        override fun release() {
+            surfaceView?.holder?.removeCallback(mSurfaceHolderCallback)
+            surfaceView = null
+        }
+    }
+
+    internal companion object {
+        internal val TAG = "GLFrameBufferRenderer"
+
+        // Leverage the same value as HardwareBuffer.USAGE_COMPOSER_OVERLAY.
+        // While this constant was introduced in the SDK in the Android T release, it has
+        // been available within the NDK as part of
+        // AHardwareBuffer_UsageFlags#AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY for quite some time.
+        // This flag is required for usage of ASurfaceTransaction#setBuffer
+        // Use a separate constant with the same value to avoid SDK warnings of accessing the
+        // newly added constant in the SDK.
+        // See:
+        // developer.android.com/ndk/reference/group/a-hardware-buffer#ahardwarebuffer_usageflags
+        private const val USAGE_COMPOSER_OVERLAY: Long = 2048L
+
+        internal const val DefaultFlags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or
+            HardwareBuffer.USAGE_GPU_COLOR_OUTPUT or
+            USAGE_COMPOSER_OVERLAY
+
+        internal const val DefaultNumBuffers = 3
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt
index 92336a6..d71362d 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlCompat.kt
@@ -18,12 +18,14 @@
 
 import android.graphics.Rect
 import android.graphics.Region
+import android.hardware.DataSpace
 import android.hardware.HardwareBuffer
 import android.os.Build
 import android.view.AttachedSurfaceControl
 import android.view.Surface
 import android.view.SurfaceControl
 import android.view.SurfaceView
+import androidx.annotation.FloatRange
 import androidx.annotation.IntDef
 import androidx.annotation.RequiresApi
 import androidx.graphics.lowlatency.FrontBufferUtils
@@ -481,6 +483,79 @@
         }
 
         /**
+         * Sets the desired extended range brightness for the layer. This only applies for layers
+         * that are displaying [HardwareBuffer] instances with a DataSpace of
+         * [DataSpace.RANGE_EXTENDED].
+         *
+         * @param surfaceControl The layer whose extended range brightness is being specified
+         * @param currentBufferRatio The current hdr/sdr ratio of the current buffer. For example
+         * if the buffer was rendered with a target SDR whitepoint of 100 nits and a max display
+         * brightness of 200 nits, this should be set to 2.0f.
+         *
+         * Default value is 1.0f.
+         *
+         * Transfer functions that encode their own brightness ranges,
+         * such as HLG or PQ, should also set this to 1.0f and instead
+         * communicate extended content brightness information via
+         * metadata such as CTA861_3 or SMPTE2086.
+         *
+         * Must be finite && >= 1.0f
+         *
+         * @param desiredRatio The desired hdr/sdr ratio. This can be used to communicate the max
+         * desired brightness range. This is similar to the "max luminance" value in other HDR
+         * metadata formats, but represented as a ratio of the target SDR whitepoint to the max
+         * display brightness. The system may not be able to, or may choose not to, deliver the
+         * requested range.
+         *
+         * While requesting a large desired ratio will result in the most
+         * dynamic range, voluntarily reducing the requested range can help
+         * improve battery life as well as can improve quality by ensuring
+         * greater bit depth is allocated to the luminance range in use.
+         *
+         * Default value is 1.0f and indicates that extended range brightness
+         * is not being used, so the resulting SDR or HDR behavior will be
+         * determined entirely by the dataspace being used (ie, typically SDR
+         * however PQ or HLG transfer functions will still result in HDR)
+         *
+         * Must be finite && >= 1.0f
+         * @return this
+         **/
+        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        fun setExtendedRangeBrightness(
+            surfaceControl: SurfaceControlCompat,
+            @FloatRange(from = 1.0, fromInclusive = true) currentBufferRatio: Float,
+            @FloatRange(from = 1.0, fromInclusive = true) desiredRatio: Float
+        ): Transaction {
+            mImpl.setExtendedRangeBrightness(
+                surfaceControl.scImpl,
+                currentBufferRatio,
+                desiredRatio
+            )
+            return this
+        }
+
+        /**
+         * Set the dataspace for the SurfaceControl. This will control how the buffer
+         * set with [setBuffer] is displayed.
+         *
+         * @param surfaceControl The SurfaceControl to update
+         * @param dataSpace The dataspace to set it to. Must be one of named
+         * [android.hardware.DataSpace] types.
+         *
+         * @see [android.view.SurfaceControl.Transaction.setDataSpace]
+         *
+         * @return this
+         */
+        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+        fun setDataSpace(
+            surfaceControl: SurfaceControlCompat,
+            dataSpace: Int
+        ): Transaction {
+            mImpl.setDataSpace(surfaceControl.scImpl, dataSpace)
+            return this
+        }
+
+        /**
          * Commit the transaction, clearing it's state, and making it usable as a new transaction.
          * This will not release any resources and [SurfaceControlCompat.Transaction.close] must be
          * called to release the transaction.
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
index 460f50a..d236c1e 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
@@ -310,6 +310,25 @@
         ): Transaction
 
         /**
+         * See [SurfaceControlCompat.Transaction.setExtendedRangeBrightness]
+         */
+        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        fun setExtendedRangeBrightness(
+            surfaceControl: SurfaceControlImpl,
+            currentBufferRatio: Float,
+            desiredRatio: Float
+        ): Transaction
+
+        /**
+         * See [SurfaceControlCompat.Transaction.setDataSpace]
+         */
+        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+        fun setDataSpace(
+            surfaceControl: SurfaceControlImpl,
+            dataSpace: Int
+        ): Transaction
+
+        /**
          * Commit the transaction, clearing it's state, and making it usable as a new transaction.
          * This will not release any resources and [SurfaceControlImpl.Transaction.close] must be
          * called to release the transaction.
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
index 8a303de..c9f06f1 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
@@ -361,6 +361,33 @@
         }
 
         /**
+         * See [SurfaceControlCompat.Transaction.setExtendedRangeBrightness]
+         */
+        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        override fun setExtendedRangeBrightness(
+            surfaceControl: SurfaceControlImpl,
+            currentBufferRatio: Float,
+            desiredRatio: Float
+        ): SurfaceControlImpl.Transaction {
+            throw UnsupportedOperationException(
+                "Configuring the extended range brightness is only available on Android U+"
+            )
+        }
+
+        /**
+         * See [SurfaceControlCompat.Transaction.setDataSpace]
+         */
+        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+        override fun setDataSpace(
+            surfaceControl: SurfaceControlImpl,
+            dataSpace: Int
+        ): SurfaceControlImpl.Transaction {
+            throw UnsupportedOperationException(
+                "Configuring the data space is only available on Android T+"
+            )
+        }
+
+        /**
          * See [SurfaceControlWrapper.Transaction.close]
          */
         override fun close() {
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV33.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV33.kt
index 37311f5..2a9e3b0 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV33.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV33.kt
@@ -23,6 +23,7 @@
 import android.os.Build
 import android.view.AttachedSurfaceControl
 import android.view.SurfaceControl
+import android.view.SurfaceControl.Transaction
 import android.view.SurfaceView
 import androidx.annotation.RequiresApi
 import androidx.hardware.SyncFenceImpl
@@ -259,6 +260,52 @@
         }
 
         /**
+         * See [SurfaceControlCompat.Transaction.setExtendedRangeBrightness]
+         */
+        @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        override fun setExtendedRangeBrightness(
+            surfaceControl: SurfaceControlImpl,
+            currentBufferRatio: Float,
+            desiredRatio: Float
+        ): SurfaceControlImpl.Transaction {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                SurfaceControlTransactionVerificationHelperV34.setExtendedRangeBrightness(
+                    mTransaction,
+                    surfaceControl.asFrameworkSurfaceControl(),
+                    currentBufferRatio,
+                    desiredRatio
+                )
+                return this
+            } else {
+                throw UnsupportedOperationException(
+                    "Configuring the extended range brightness is only available on Android U+"
+                )
+            }
+        }
+
+        /**
+         * See [SurfaceControlCompat.Transaction.setDataSpace]
+         */
+        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+        override fun setDataSpace(
+            surfaceControl: SurfaceControlImpl,
+            dataSpace: Int
+        ): SurfaceControlImpl.Transaction {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                SurfaceControlTransactionVerificationHelperV33.setDataSpace(
+                    mTransaction,
+                    surfaceControl.asFrameworkSurfaceControl(),
+                    dataSpace
+                )
+            } else {
+                throw UnsupportedOperationException(
+                    "Configuring the data space is only available on Android T+"
+                )
+            }
+            return this
+        }
+
+        /**
          * See [SurfaceControlImpl.Transaction.commit]
          */
         override fun commit() {
@@ -296,4 +343,27 @@
                 throw IllegalArgumentException("Parent implementation is not for Android T")
             }
     }
+}
+
+@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+private object SurfaceControlTransactionVerificationHelperV34 {
+
+    @androidx.annotation.DoNotInline
+    fun setExtendedRangeBrightness(
+        transaction: Transaction,
+        surfaceControl: SurfaceControl,
+        currentBufferRatio: Float,
+        desiredRatio: Float
+    ) {
+        transaction.setExtendedRangeBrightness(surfaceControl, currentBufferRatio, desiredRatio)
+    }
+}
+
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+private object SurfaceControlTransactionVerificationHelperV33 {
+
+    @androidx.annotation.DoNotInline
+    fun setDataSpace(transaction: Transaction, surfaceControl: SurfaceControl, dataspace: Int) {
+        transaction.setDataSpace(surfaceControl, dataspace)
+    }
 }
\ No newline at end of file
diff --git a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
index 055bc4f..64cb8a1 100644
--- a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
+++ b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
@@ -138,7 +138,7 @@
         @RequiresApi(Build.VERSION_CODES.TIRAMISU)
         @androidx.annotation.DoNotInline
         fun createSyncFenceCompatV33(): SyncFenceCompat {
-            val display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
+            val display = EGL14.eglGetCurrentDisplay()
             if (display == EGL15.EGL_NO_DISPLAY) {
                 throw RuntimeException("no EGL display")
             }
diff --git a/graphics/graphics-path/api/current.txt b/graphics/graphics-path/api/current.txt
new file mode 100644
index 0000000..902f803
--- /dev/null
+++ b/graphics/graphics-path/api/current.txt
@@ -0,0 +1,61 @@
+// Signature format: 4.0
+package androidx.graphics.path {
+
+  @androidx.core.os.BuildCompat.PrereleaseSdkCheck public final class PathIterator implements java.util.Iterator<androidx.graphics.path.PathSegment> kotlin.jvm.internal.markers.KMappedMarker {
+    ctor public PathIterator(android.graphics.Path path, optional androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation, optional float tolerance);
+    method public int calculateSize(optional boolean includeConvertedConics);
+    method public androidx.graphics.path.PathIterator.ConicEvaluation getConicEvaluation();
+    method public android.graphics.Path getPath();
+    method public float getTolerance();
+    method public boolean hasNext();
+    method public androidx.graphics.path.PathSegment next();
+    method public androidx.graphics.path.PathSegment.Type next(float[] points);
+    method public androidx.graphics.path.PathSegment.Type next(float[] points, optional int offset);
+    method public androidx.graphics.path.PathSegment.Type peek();
+    property public final androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation;
+    property public final android.graphics.Path path;
+    property public final float tolerance;
+  }
+
+  public enum PathIterator.ConicEvaluation {
+    method public static androidx.graphics.path.PathIterator.ConicEvaluation valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.graphics.path.PathIterator.ConicEvaluation[] values();
+    enum_constant public static final androidx.graphics.path.PathIterator.ConicEvaluation AsConic;
+    enum_constant public static final androidx.graphics.path.PathIterator.ConicEvaluation AsQuadratics;
+  }
+
+  public final class PathSegment {
+    method public android.graphics.PointF![] getPoints();
+    method public androidx.graphics.path.PathSegment.Type getType();
+    method public float getWeight();
+    property public final android.graphics.PointF![] points;
+    property public final androidx.graphics.path.PathSegment.Type type;
+    property public final float weight;
+  }
+
+  public enum PathSegment.Type {
+    method public static androidx.graphics.path.PathSegment.Type valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.graphics.path.PathSegment.Type[] values();
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Close;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Conic;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Cubic;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Done;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Line;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Move;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Quadratic;
+  }
+
+  public final class PathSegmentUtilities {
+    method public static androidx.graphics.path.PathSegment getCloseSegment();
+    method public static androidx.graphics.path.PathSegment getDoneSegment();
+    property public static final androidx.graphics.path.PathSegment CloseSegment;
+    property public static final androidx.graphics.path.PathSegment DoneSegment;
+  }
+
+  public final class PathUtilities {
+    method @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static operator androidx.graphics.path.PathIterator iterator(android.graphics.Path);
+    method @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static androidx.graphics.path.PathIterator iterator(android.graphics.Path, androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation, optional float tolerance);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/graphics/graphics-path/api/res-current.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to graphics/graphics-path/api/res-current.txt
diff --git a/graphics/graphics-path/api/restricted_current.txt b/graphics/graphics-path/api/restricted_current.txt
new file mode 100644
index 0000000..902f803
--- /dev/null
+++ b/graphics/graphics-path/api/restricted_current.txt
@@ -0,0 +1,61 @@
+// Signature format: 4.0
+package androidx.graphics.path {
+
+  @androidx.core.os.BuildCompat.PrereleaseSdkCheck public final class PathIterator implements java.util.Iterator<androidx.graphics.path.PathSegment> kotlin.jvm.internal.markers.KMappedMarker {
+    ctor public PathIterator(android.graphics.Path path, optional androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation, optional float tolerance);
+    method public int calculateSize(optional boolean includeConvertedConics);
+    method public androidx.graphics.path.PathIterator.ConicEvaluation getConicEvaluation();
+    method public android.graphics.Path getPath();
+    method public float getTolerance();
+    method public boolean hasNext();
+    method public androidx.graphics.path.PathSegment next();
+    method public androidx.graphics.path.PathSegment.Type next(float[] points);
+    method public androidx.graphics.path.PathSegment.Type next(float[] points, optional int offset);
+    method public androidx.graphics.path.PathSegment.Type peek();
+    property public final androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation;
+    property public final android.graphics.Path path;
+    property public final float tolerance;
+  }
+
+  public enum PathIterator.ConicEvaluation {
+    method public static androidx.graphics.path.PathIterator.ConicEvaluation valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.graphics.path.PathIterator.ConicEvaluation[] values();
+    enum_constant public static final androidx.graphics.path.PathIterator.ConicEvaluation AsConic;
+    enum_constant public static final androidx.graphics.path.PathIterator.ConicEvaluation AsQuadratics;
+  }
+
+  public final class PathSegment {
+    method public android.graphics.PointF![] getPoints();
+    method public androidx.graphics.path.PathSegment.Type getType();
+    method public float getWeight();
+    property public final android.graphics.PointF![] points;
+    property public final androidx.graphics.path.PathSegment.Type type;
+    property public final float weight;
+  }
+
+  public enum PathSegment.Type {
+    method public static androidx.graphics.path.PathSegment.Type valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException;
+    method public static androidx.graphics.path.PathSegment.Type[] values();
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Close;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Conic;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Cubic;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Done;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Line;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Move;
+    enum_constant public static final androidx.graphics.path.PathSegment.Type Quadratic;
+  }
+
+  public final class PathSegmentUtilities {
+    method public static androidx.graphics.path.PathSegment getCloseSegment();
+    method public static androidx.graphics.path.PathSegment getDoneSegment();
+    property public static final androidx.graphics.path.PathSegment CloseSegment;
+    property public static final androidx.graphics.path.PathSegment DoneSegment;
+  }
+
+  public final class PathUtilities {
+    method @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static operator androidx.graphics.path.PathIterator iterator(android.graphics.Path);
+    method @androidx.core.os.BuildCompat.PrereleaseSdkCheck public static androidx.graphics.path.PathIterator iterator(android.graphics.Path, androidx.graphics.path.PathIterator.ConicEvaluation conicEvaluation, optional float tolerance);
+  }
+
+}
+
diff --git a/graphics/graphics-path/build.gradle b/graphics/graphics-path/build.gradle
new file mode 100644
index 0000000..392c246
--- /dev/null
+++ b/graphics/graphics-path/build.gradle
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.LibraryType
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+dependencies {
+    api(libs.kotlinStdlib)
+
+    implementation('androidx.appcompat:appcompat:1.6.1')
+    implementation(project(':core:core'))
+
+    androidTestImplementation("androidx.annotation:annotation:1.4.0")
+    androidTestImplementation("androidx.core:core-ktx:1.8.0")
+    androidTestImplementation("androidx.test:core:1.4.0@aar")
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.testRunner)
+    androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.truth)
+}
+
+android {
+    namespace "androidx.graphics.path"
+
+    defaultConfig {
+        minSdkVersion 21 // Limited to 21+ due to native changes before that release
+        externalNativeBuild {
+            cmake {
+                cppFlags.addAll(
+                        [
+                        "-std=c++17",
+                        "-Wno-unused-command-line-argument",
+                        "-Wl,--hash-style=both", // Required to support API levels below 23
+                        "-fno-stack-protector",
+                        "-fno-exceptions",
+                        "-fno-unwind-tables",
+                        "-fno-asynchronous-unwind-tables",
+                        "-fno-rtti",
+                        "-ffast-math",
+                        "-ffp-contract=fast",
+                        "-fvisibility-inlines-hidden",
+                        "-fvisibility=hidden",
+                        "-fomit-frame-pointer",
+                        "-ffunction-sections",
+                        "-fdata-sections",
+                        "-Wl,--gc-sections",
+                        "-Wl,-Bsymbolic-functions",
+                ])
+            }
+        }
+    }
+
+    externalNativeBuild {
+        cmake {
+            path file('src/main/cpp/CMakeLists.txt')
+            version libs.versions.cmake.get()
+        }
+    }
+
+}
+
+androidx {
+    name = "Android Graphics Path"
+    type = LibraryType.PUBLISHED_LIBRARY
+    mavenVersion = LibraryVersions.GRAPHICS_PATH
+    inceptionYear = "2022"
+    description = "Query segment data for android.graphics.Path objects"
+}
diff --git a/graphics/graphics-path/src/androidTest/java/androidx/graphics/path/PathIteratorTest.kt b/graphics/graphics-path/src/androidTest/java/androidx/graphics/path/PathIteratorTest.kt
new file mode 100644
index 0000000..5a58802
--- /dev/null
+++ b/graphics/graphics-path/src/androidTest/java/androidx/graphics/path/PathIteratorTest.kt
@@ -0,0 +1,544 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.graphics.path
+
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PointF
+import android.graphics.RectF
+import android.os.Build
+import androidx.core.graphics.applyCanvas
+import androidx.core.graphics.createBitmap
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import kotlin.math.abs
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private fun assertPointsEquals(p1: PointF, p2: PointF) {
+    assertEquals(p1.x, p2.x, 1e-6f)
+    assertEquals(p1.y, p2.y, 1e-6f)
+}
+
+private fun assertPointsEquals(p1: FloatArray, offset: Int, p2: PointF) {
+    assertEquals(p1[0 + offset * 2], p2.x, 1e-6f)
+    assertEquals(p1[1 + offset * 2], p2.y, 1e-6f)
+}
+
+private fun compareBitmaps(b1: Bitmap, b2: Bitmap) {
+    val epsilon: Int
+    if (Build.VERSION.SDK_INT != 23) {
+        epsilon = 1
+    } else {
+        // There is more AA variability between conics and cubics on API 23, leading
+        // to failures on relatively small visual differences. Increase the error
+        // value for just this release to avoid erroneous bitmap comparison failures.
+        epsilon = 32
+        }
+
+    assertEquals(b1.width, b2.width)
+    assertEquals(b1.height, b2.height)
+
+    val p1 = IntArray(b1.width * b1.height)
+    b1.getPixels(p1, 0, b1.width, 0, 0, b1.width, b1.height)
+
+    val p2 = IntArray(b2.width * b2.height)
+    b2.getPixels(p2, 0, b2.width, 0, 0, b2.width, b2.height)
+
+    for (x in 0 until b1.width) {
+        for (y in 0 until b2.width) {
+            val index = y * b1.width + x
+
+            val c1 = p1[index]
+            val c2 = p2[index]
+
+            assertTrue(abs(Color.red(c1) - Color.red(c2)) <= epsilon)
+            assertTrue(abs(Color.green(c1) - Color.green(c2)) <= epsilon)
+            assertTrue(abs(Color.blue(c1) - Color.blue(c2)) <= epsilon)
+        }
+    }
+}
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PathIteratorTest {
+    @Test
+    fun emptyIterator() {
+        val path = Path()
+
+        val iterator = path.iterator()
+        // TODO: un-comment the hasNext() check when the platform has the behavior change
+        // which ignores final DONE ops in the value for hasNext()
+        // assertFalse(iterator.hasNext())
+        val firstSegment = iterator.next()
+        assertEquals(PathSegment.Type.Done, firstSegment.type)
+
+        var count = 0
+        for (segment in path) {
+            // TODO: remove condition check and just increment count when platform change
+            // is checked in which will not iterate when DONE is the only op left
+            if (segment.type != PathSegment.Type.Done) {
+                // Shouldn't get here; count should remain 0
+                count++
+            }
+        }
+
+        assertEquals(0, count)
+    }
+
+    @Test
+    fun emptyPeek() {
+        val path = Path()
+        val iterator = path.iterator()
+        assertEquals(PathSegment.Type.Done, iterator.peek())
+    }
+
+    @Test
+    fun nonEmptyIterator() {
+        val path = Path().apply {
+            moveTo(1.0f, 1.0f)
+            lineTo(2.0f, 2.0f)
+            close()
+        }
+
+        val iterator = path.iterator()
+        assertTrue(iterator.hasNext())
+
+        val types = arrayOf(
+            PathSegment.Type.Move,
+            PathSegment.Type.Line,
+            PathSegment.Type.Close,
+            PathSegment.Type.Done
+        )
+        val points = arrayOf(
+            PointF(1.0f, 1.0f),
+            PointF(2.0f, 2.0f)
+        )
+
+        var count = 0
+        for (segment in path) {
+            assertEquals(types[count], segment.type)
+            when (segment.type) {
+                PathSegment.Type.Move -> {
+                    assertEquals(points[count], segment.points[0])
+                }
+                PathSegment.Type.Line -> {
+                    assertEquals(points[count - 1], segment.points[0])
+                    assertEquals(points[count], segment.points[1])
+                }
+                else -> { }
+            }
+            // TODO: remove condition and just auto-increment count when platform change is
+            // checked in which ignores DONE during iteration
+            if (segment.type != PathSegment.Type.Done) count++
+        }
+
+        assertEquals(3, count)
+    }
+
+    @Test
+    fun peek() {
+        val path = Path().apply {
+            moveTo(1.0f, 1.0f)
+            lineTo(2.0f, 2.0f)
+            close()
+        }
+
+        val iterator = path.iterator()
+        assertEquals(PathSegment.Type.Move, iterator.peek())
+    }
+
+    @Test
+    fun peekBeyond() {
+        val path = Path()
+        assertEquals(PathSegment.Type.Done, path.iterator().peek())
+
+        path.apply {
+            moveTo(1.0f, 1.0f)
+            lineTo(2.0f, 2.0f)
+            close()
+        }
+
+        val iterator = path.iterator()
+        while (iterator.hasNext()) iterator.next()
+        assertEquals(PathSegment.Type.Done, iterator.peek())
+    }
+
+    @Test
+    fun iteratorStyles() {
+        val path = Path().apply {
+            moveTo(1.0f, 1.0f)
+            lineTo(2.0f, 2.0f)
+            cubicTo(3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f)
+            quadTo(7.0f, 7.0f, 8.0f, 8.0f)
+            moveTo(10.0f, 10.0f)
+            // addRoundRect() will generate conic curves on certain API levels
+            addRoundRect(RectF(12.0f, 12.0f, 36.0f, 36.0f), 8.0f, 8.0f, Path.Direction.CW)
+            close()
+        }
+
+        iteratorStylesImpl(path, PathIterator.ConicEvaluation.AsConic)
+        iteratorStylesImpl(path, PathIterator.ConicEvaluation.AsQuadratics)
+    }
+
+    private fun iteratorStylesImpl(path: Path, conicEvaluation: PathIterator.ConicEvaluation) {
+        val iterator1 = path.iterator(conicEvaluation)
+        val iterator2 = path.iterator(conicEvaluation)
+        val iterator3 = path.iterator(conicEvaluation)
+
+        val points = FloatArray(8)
+        val points2 = FloatArray(16)
+
+        while (iterator1.hasNext() || iterator2.hasNext() || iterator3.hasNext()) {
+            val segment = iterator1.next()
+            val type = iterator2.next(points)
+            val type2 = iterator3.next(points2, 8)
+
+            assertEquals(type, segment.type)
+            assertEquals(type2, segment.type)
+
+            when (type) {
+                PathSegment.Type.Move -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                }
+
+                PathSegment.Type.Line -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                }
+
+                PathSegment.Type.Quadratic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                }
+
+                PathSegment.Type.Conic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    // Weight is stored after all of the points
+                    assertEquals(points[6], segment.weight)
+
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                    // Weight is stored after all of the points
+                    assertEquals(points2[14], segment.weight)
+                }
+
+                PathSegment.Type.Cubic -> {
+                    assertPointsEquals(points, 0, segment.points[0])
+                    assertPointsEquals(points, 1, segment.points[1])
+                    assertPointsEquals(points, 2, segment.points[2])
+                    assertPointsEquals(points, 3, segment.points[3])
+
+                    assertPointsEquals(points2, 4, segment.points[0])
+                    assertPointsEquals(points2, 5, segment.points[1])
+                    assertPointsEquals(points2, 6, segment.points[2])
+                    assertPointsEquals(points2, 7, segment.points[3])
+                }
+
+                PathSegment.Type.Close -> {}
+                PathSegment.Type.Done -> {}
+            }
+        }
+    }
+
+    @Test
+    fun done() {
+        val path = Path().apply {
+            close()
+        }
+
+        val segment = path.iterator().next()
+
+        assertEquals(PathSegment.Type.Done, segment.type)
+        assertEquals(0, segment.points.size)
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun close() {
+        val path = Path().apply {
+            lineTo(10.0f, 12.0f)
+            close()
+        }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+        // Swallow the line
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Close, segment.type)
+        assertEquals(0, segment.points.size)
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun moveTo() {
+        val path = Path().apply {
+            moveTo(10.0f, 12.0f)
+        }
+
+        val segment = path.iterator().next()
+
+        assertEquals(PathSegment.Type.Move, segment.type)
+        assertEquals(1, segment.points.size)
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[0])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun lineTo() {
+        val path = Path().apply {
+            moveTo(4.0f, 6.0f)
+            lineTo(10.0f, 12.0f)
+        }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Line, segment.type)
+        assertEquals(2, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun quadraticTo() {
+        val path = Path().apply {
+            moveTo(4.0f, 6.0f)
+            quadTo(10.0f, 12.0f, 20.0f, 24.0f)
+        }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Quadratic, segment.type)
+        assertEquals(3, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertPointsEquals(PointF(20.0f, 24.0f), segment.points[2])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun cubicTo() {
+        val path = Path().apply {
+            moveTo(4.0f, 6.0f)
+            cubicTo(10.0f, 12.0f, 20.0f, 24.0f, 30.0f, 36.0f)
+        }
+
+        val iterator = path.iterator()
+        // Swallow the move
+        iterator.next()
+
+        val segment = iterator.next()
+
+        assertEquals(PathSegment.Type.Cubic, segment.type)
+        assertEquals(4, segment.points.size)
+        assertPointsEquals(PointF(4.0f, 6.0f), segment.points[0])
+        assertPointsEquals(PointF(10.0f, 12.0f), segment.points[1])
+        assertPointsEquals(PointF(20.0f, 24.0f), segment.points[2])
+        assertPointsEquals(PointF(30.0f, 36.0f), segment.points[3])
+        assertEquals(0.0f, segment.weight)
+    }
+
+    @Test
+    fun conicTo() {
+        if (Build.VERSION.SDK_INT >= 25) {
+            val path = Path().apply {
+                addRoundRect(RectF(12.0f, 12.0f, 24.0f, 24.0f), 8.0f, 8.0f, Path.Direction.CW)
+            }
+
+            val iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)
+            // Swallow the move
+            iterator.next()
+
+            val segment = iterator.next()
+
+            assertEquals(PathSegment.Type.Conic, segment.type)
+            assertEquals(3, segment.points.size)
+
+            assertPointsEquals(PointF(12.0f, 18.0f), segment.points[0])
+            assertPointsEquals(PointF(12.0f, 12.0f), segment.points[1])
+            assertPointsEquals(PointF(18.0f, 12.0f), segment.points[2])
+            assertEquals(0.70710677f, segment.weight)
+        }
+    }
+
+    @Test
+    fun conicAsQuadratics() {
+        val path = Path().apply {
+            addRoundRect(RectF(12.0f, 12.0f, 24.0f, 24.0f), 8.0f, 8.0f, Path.Direction.CW)
+        }
+
+        for (segment in path) {
+            if (segment.type == PathSegment.Type.Conic) fail("Found conic, none expected: $segment")
+        }
+    }
+
+    @Test
+    fun convertedConics() {
+        val path1 = Path().apply {
+            addRoundRect(RectF(12.0f, 12.0f, 64.0f, 64.0f), 12.0f, 12.0f, Path.Direction.CW)
+        }
+
+        val path2 = Path()
+        for (segment in path1) {
+            when (segment.type) {
+                PathSegment.Type.Move -> path2.moveTo(segment.points[0].x, segment.points[0].y)
+                PathSegment.Type.Line -> path2.lineTo(segment.points[1].x, segment.points[1].y)
+                PathSegment.Type.Quadratic -> path2.quadTo(
+                    segment.points[1].x, segment.points[1].y,
+                    segment.points[2].x, segment.points[2].y
+                )
+                PathSegment.Type.Conic -> fail("Unexpected conic! $segment")
+                PathSegment.Type.Cubic -> path2.cubicTo(
+                    segment.points[1].x, segment.points[1].y,
+                    segment.points[2].x, segment.points[2].y,
+                    segment.points[3].x, segment.points[3].y
+                )
+                PathSegment.Type.Close -> path2.close()
+                PathSegment.Type.Done -> { }
+            }
+        }
+
+        // Now with smaller error tolerance
+        val path3 = Path()
+        for (segment in path1.iterator(
+            conicEvaluation = PathIterator.ConicEvaluation.AsQuadratics,
+            .001f
+        )) {
+            when (segment.type) {
+                PathSegment.Type.Move -> path3.moveTo(segment.points[0].x, segment.points[0].y)
+                PathSegment.Type.Line -> path3.lineTo(segment.points[1].x, segment.points[1].y)
+                PathSegment.Type.Quadratic -> path3.quadTo(
+                    segment.points[1].x, segment.points[1].y,
+                    segment.points[2].x, segment.points[2].y
+                )
+                PathSegment.Type.Conic -> fail("Unexpected conic! $segment")
+                PathSegment.Type.Cubic -> path3.cubicTo(
+                    segment.points[1].x, segment.points[1].y,
+                    segment.points[2].x, segment.points[2].y,
+                    segment.points[3].x, segment.points[3].y
+                )
+                PathSegment.Type.Close -> path3.close()
+                PathSegment.Type.Done -> { }
+            }
+        }
+
+        val b1 = createBitmap(76, 76).applyCanvas {
+            drawARGB(255, 255, 255, 255)
+            drawPath(path1, Paint().apply {
+                color = argb(1.0f, 0.0f, 0.0f, 1.0f)
+                strokeWidth = 2.0f
+                isAntiAlias = true
+                style = Paint.Style.STROKE
+            })
+        }
+
+        val b2 = createBitmap(76, 76).applyCanvas {
+            drawARGB(255, 255, 255, 255)
+            drawPath(path2, Paint().apply {
+                color = argb(1.0f, 0.0f, 0.0f, 1.0f)
+                strokeWidth = 2.0f
+                isAntiAlias = true
+                style = Paint.Style.STROKE
+            })
+        }
+
+        compareBitmaps(b1, b2)
+        // Note: b1-vs-b3 is not a valid comparison; default Skia rendering does not use an
+        // error tolerance that low. The test for fine-precision in path3 was just to
+        // ensure that the system could handle the extra data and operations required
+    }
+
+    @Test
+    fun sizes() {
+        val path = Path()
+        var iterator: PathIterator = path.iterator()
+
+        if (iterator.calculateSize() > 0) {
+            assertEquals(PathSegment.Type.Done, iterator.peek())
+        }
+        // TODO: replace above check with below assertEquals after platform change is checked
+        // in which returns a size of zero when there the only op in the path is DONE
+        // assertEquals(0, iterator.size())
+
+        path.addRoundRect(RectF(12.0f, 12.0f, 64.0f, 64.0f), 8.0f, 8.0f,
+                Path.Direction.CW)
+
+        // Skia converted
+        if (Build.VERSION.SDK_INT > 22) {
+            // Preserve conics and count
+            iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)
+            assert(iterator.calculateSize() == 10 || iterator.calculateSize() == 11)
+            // TODO: replace assert() above with assertEquals below once platform change exists
+            // which does not count final DONE in the size
+            // assertEquals(10, iterator.size())
+            assertEquals(iterator.calculateSize(true), iterator.calculateSize())
+        }
+
+        // Convert conics and count
+        iterator = path.iterator(PathIterator.ConicEvaluation.AsQuadratics)
+        if (Build.VERSION.SDK_INT > 22) {
+            // simple size, not including conic conversion
+            assert(iterator.calculateSize(false) == 10 || iterator.calculateSize(false) == 11)
+            // TODO: replace assert() above with assertEquals below once platform change exists
+            // which does not count final DONE in the size
+            // assertEquals(10, iterator.size(false))
+        } else {
+            // round rects pre-API22 used line/quad/quad for each corner
+            assertEquals(14, iterator.calculateSize())
+        }
+        // now get the size with converted conics
+        val size = iterator.calculateSize()
+        assert(size == 14 || size == 15)
+        // TODO: replace assert() above with assertEquals below once platform change exists
+        // which does not count final DONE in the size
+        // assertEquals(14, iterator.size())
+    }
+}
+
+fun argb(alpha: Float, red: Float, green: Float, blue: Float) =
+    ((alpha * 255.0f + 0.5f).toInt() shl 24) or
+    ((red * 255.0f + 0.5f).toInt() shl 16) or
+    ((green * 255.0f + 0.5f).toInt() shl 8) or
+     (blue * 255.0f + 0.5f).toInt()
diff --git a/graphics/graphics-path/src/main/androidx/graphics/androidx-graphics-graphics-path-documentation.md b/graphics/graphics-path/src/main/androidx/graphics/androidx-graphics-graphics-path-documentation.md
new file mode 100644
index 0000000..6c44750
--- /dev/null
+++ b/graphics/graphics-path/src/main/androidx/graphics/androidx-graphics-graphics-path-documentation.md
@@ -0,0 +1,117 @@
+# Package androidx.graphics.paths
+
+Androidx Graphics Path is an Android library that provides new functionalities around the
+[Path](https://developer.android.com/reference/android/graphics/Path) API. Specifically, it
+allows paths to be queried for the segment data they contain,
+
+The library is compatible with API 21+.
+
+## Iterating over a Path
+
+With Pathway you can easily iterate over a `Path` object to inspect its segments
+(curves or commands):
+
+```kotlin
+val path = Path().apply {
+    // Build path content
+}
+
+for (segment in path) {
+    val type = segment.type // The type of segment (move, cubic, quadratic, line, close, etc.)
+    val points = segment.points // The points describing the segment geometry
+}
+```
+
+This type of iteration is easy to use but may create an allocation per segment iterated over.
+If you must avoid allocations, Pathway provides a lower-level API to do so:
+
+```kotlin
+val path = Path().apply {
+    // Build path content
+}
+
+val iterator = path.iterator
+val points = FloatArray(8)
+
+while (iterator.hasNext()) {
+    val type = iterator.next(points) // The type of segment
+    // Read the segment geometry from the points array depending on the type
+}
+
+```
+
+### Path segments
+
+Each segment in a `Path` can be of one of the following types:
+
+#### Move
+
+Move command. The path segment contains 1 point indicating the move destination.
+The weight is set 0.0f and not meaningful.
+
+#### Line
+
+Line curve. The path segment contains 2 points indicating the two extremities of
+the line. The weight is set 0.0f and not meaningful.
+
+#### Quadratic
+
+Quadratic curve. The path segment contains 3 points in the following order:
+- Start point
+- Control point
+- End point
+
+The weight is set 0.0f and not meaningful.
+
+#### Conic
+
+Conic curve. The path segment contains 3 points in the following order:
+- Start point
+- Control point
+- End point
+
+The curve is weighted by the `PathSegment.weight` property.
+
+Conic curves are automatically converted to quadratic curves by default, see
+[Handling conic segments](#handling-conic-segments) below for more information.
+
+#### Cubic
+
+Cubic curve. The path segment contains 4 points in the following order:
+- Start point
+- First control point
+- Second control point
+- End point
+
+The weight is set to 0.0f and is not meaningful.
+
+#### Close
+
+Close command. Close the current contour by joining the last point added to the
+path with the first point of the current contour. The segment does not contain
+any point. The weight is set 0.0f and not meaningful.
+
+#### Done
+
+Done command. This optional command indicates that no further segment will be
+found in the path. It typically indicates the end of an iteration over a path
+and can be ignored.
+
+## Handling conic segments
+
+In some API levels, paths may contain conic curves (weighted quadratics) but the
+`Path` API does not offer a way to add conics to a `Path` object. To work around
+this, Pathway automatically converts conics into several quadratics by default.
+
+The conic to quadratic conversion is an approximation controlled by a tolerance
+threshold, set by default to 0.25f (sub-pixel). If you want to preserve conics
+or control the tolerance, you can use the following APIs:
+
+```kotlin
+// Preserve conics
+val iterator = path.iterator(PathIterator.ConicEvaluation.AsConic)
+
+// Control the tolerance of the conic to quadratic conversion
+val iterator = path.iterator(PathIterator.ConicEvaluation.AsQuadratics, 2.0f)
+
+```
diff --git a/graphics/graphics-path/src/main/cpp/CMakeLists.txt b/graphics/graphics-path/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..e77704f
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.18.1)
+project("androidx.graphics.path")
+
+add_library(
+        androidx.graphics.path
+        SHARED
+        Conic.cpp
+        PathIterator.cpp
+        pathway.cpp
+)
+
+find_library(
+        log-lib
+        log
+)
+
+target_link_libraries(
+        androidx.graphics.path
+        ${log-lib}
+)
diff --git a/graphics/graphics-path/src/main/cpp/Conic.cpp b/graphics/graphics-path/src/main/cpp/Conic.cpp
new file mode 100644
index 0000000..a6d15b6
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/Conic.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2006 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.
+ */
+
+#include "Conic.h"
+
+#include "scalar.h"
+
+#include "math/vec2.h"
+
+#include <cmath>
+#include <cstring>
+
+using namespace filament::math;
+
+constexpr int kMaxConicToQuadCount = 5;
+
+constexpr bool isFinite(const Point points[], int count) noexcept {
+    return isFinite(&points[0].x, count << 1);
+}
+
+constexpr bool isFinite(const Point& point) noexcept {
+    float a = 0.0f;
+    a *= point.x;
+    a *= point.y;
+    return a == 0.0f;
+}
+
+constexpr Point toPoint(const float2& v) noexcept {
+    return { .x = v.x, .y = v.y };
+}
+
+constexpr float2 fromPoint(const Point& v) noexcept {
+    return float2{v.x, v.y};
+}
+
+int conicToQuadratics(
+    const Point conicPoints[3], Point *quadraticPoints, int bufferSize,
+    float weight, float tolerance
+) noexcept {
+    Conic conic(conicPoints[0], conicPoints[1], conicPoints[2], weight);
+
+    int count = conic.computeQuadraticCount(tolerance);
+    int quadraticCount = 1 << count;
+    if (quadraticCount > bufferSize) {
+        // Buffer not large enough; return necessary size to resize and try again
+        return quadraticCount;
+    }
+    quadraticCount = conic.splitIntoQuadratics(quadraticPoints, count);
+
+    return quadraticCount;
+}
+
+int Conic::computeQuadraticCount(float tolerance) const noexcept {
+    if (tolerance <= 0.0f || !isFinite(tolerance) || !isFinite(points, 3)) return 0;
+
+    float a = weight - 1.0f;
+    float k = a / (4.0f * (2.0f + a));
+    float x = k * (points[0].x - 2.0f * points[1].x + points[2].x);
+    float y = k * (points[0].y - 2.0f * points[1].y + points[2].y);
+
+    float error = std::sqrtf(x * x + y * y);
+    int count = 0;
+    for ( ; count < kMaxConicToQuadCount; count++) {
+        if (error <= tolerance) break;
+        error *= 0.25f;
+    }
+
+    return count;
+}
+
+static Point* subdivide(const Conic& src, Point pts[], int level) {
+    if (level == 0) {
+        memcpy(pts, &src.points[1], 2 * sizeof(Point));
+        return pts + 2;
+    } else {
+        Conic dst[2];
+        src.split(dst);
+        const float startY = src.points[0].y;
+        const float endY = src.points[2].y;
+        if (between(startY, src.points[1].y, endY)) {
+            float midY = dst[0].points[2].y;
+            if (!between(startY, midY, endY)) {
+                float closerY = tabs(midY - startY) < tabs(midY - endY) ? startY : endY;
+                dst[0].points[2].y = dst[1].points[0].y = closerY;
+            }
+            if (!between(startY, dst[0].points[1].y, dst[0].points[2].y)) {
+                dst[0].points[1].y = startY;
+            }
+            if (!between(dst[1].points[0].y, dst[1].points[1].y, endY)) {
+                dst[1].points[1].y = endY;
+            }
+        }
+        --level;
+        pts = subdivide(dst[0], pts, level);
+        return subdivide(dst[1], pts, level);
+    }
+}
+
+void Conic::split(Conic* __restrict__ dst) const noexcept {
+    float2 scale{1.0f / (1.0f + weight)};
+    float newW = std::sqrtf(0.5f + weight * 0.5f);
+
+    float2 p0 = fromPoint(points[0]);
+    float2 p1 = fromPoint(points[1]);
+    float2 p2 = fromPoint(points[2]);
+    float2 ww(weight);
+
+    float2 wp1 = ww * p1;
+    float2 m = (p0 + (wp1 + wp1) + p2) * scale * float2(0.5f);
+    Point pt = toPoint(m);
+    if (!isFinite(pt)) {
+        double w_d = weight;
+        double w_2 = w_d * 2.0;
+        double scale_half = 1.0 / (1.0 + w_d) * 0.5;
+        pt.x = float((points[0].x + w_2 * points[1].x + points[2].x) * scale_half);
+        pt.y = float((points[0].y + w_2 * points[1].y + points[2].y) * scale_half);
+    }
+    dst[0].points[0] = points[0];
+    dst[0].points[1] = toPoint((p0 + wp1) * scale);
+    dst[0].points[2] = dst[1].points[0] = pt;
+    dst[1].points[1] = toPoint((wp1 + p2) * scale);
+    dst[1].points[2] = points[2];
+
+    dst[0].weight = dst[1].weight = newW;
+}
+
+int Conic::splitIntoQuadratics(Point dstPoints[], int count) const noexcept {
+    *dstPoints = points[0];
+
+    if (count >= kMaxConicToQuadCount) {
+        Conic dst[2];
+        split(dst);
+
+        if (equals(dst[0].points[1], dst[0].points[2]) &&
+                equals(dst[1].points[0], dst[1].points[1])) {
+            dstPoints[1] = dstPoints[2] = dstPoints[3] = dst[0].points[1];
+            dstPoints[4] = dst[1].points[2];
+            count = 1;
+            goto commonFinitePointCheck;
+        }
+    }
+
+    subdivide(*this, dstPoints + 1, count);
+
+commonFinitePointCheck:
+    const int quadCount = 1 << count;
+    const int pointCount = 2 * quadCount + 1;
+
+    if (!isFinite(dstPoints, pointCount)) {
+        for (int i = 1; i < pointCount - 1; ++i) {
+            dstPoints[i] = points[1];
+        }
+    }
+
+    return quadCount;
+}
\ No newline at end of file
diff --git a/graphics/graphics-path/src/main/cpp/Conic.h b/graphics/graphics-path/src/main/cpp/Conic.h
new file mode 100644
index 0000000..548fea2
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/Conic.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PATH_CONIC_H
+#define PATH_CONIC_H
+
+#include "Path.h"
+
+#include <vector>
+
+constexpr int kDefaultQuadraticCount = 8;
+
+int conicToQuadratics(
+        const Point conicPoints[3], Point *quadraticPoints, int bufferSize,
+        float weight, float tolerance
+) noexcept;
+
+class ConicConverter {
+public:
+    ConicConverter() noexcept { }
+
+private:
+    std::vector<Point> mStorage{1 + 2 * kDefaultQuadraticCount};
+};
+
+struct Conic {
+    Conic() noexcept { }
+
+    Conic(Point p0, Point p1, Point p2, float weight) noexcept {
+        points[0] = p0;
+        points[1] = p1;
+        points[2] = p2;
+        this->weight = weight;
+    }
+
+    void split(Conic* __restrict__ dst) const noexcept;
+    int computeQuadraticCount(float tolerance) const noexcept;
+    int splitIntoQuadratics(Point dstPoints[], int count) const noexcept;
+
+    Point points[3];
+    float weight;
+};
+
+#endif //PATH_CONIC_H
diff --git a/graphics/graphics-path/src/main/cpp/Path.h b/graphics/graphics-path/src/main/cpp/Path.h
new file mode 100644
index 0000000..f25d708
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/Path.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PATH_PATH_H
+#define PATH_PATH_H
+
+#include <stdint.h>
+
+// The following structures declare the minimum we need + a marker (generationId) to
+// validate the data during debugging. There may be more fields in the Skia structures
+// but we just ignore them for now. Some fields declared in older API levels (isFinite
+// for instance) may not show up in the declarations for newer API levels if the field
+// still exist but was moved after the data we need.
+
+enum class Verb : uint8_t {
+    Move,
+    Line,
+    Quadratic,
+    Conic,
+    Cubic,
+    Close,
+    Done
+};
+
+struct Point {
+    float x;
+    float y;
+};
+
+struct PathRef21 {
+    __unused intptr_t pointer;      // Virtual tables
+    __unused int32_t refCount;
+    __unused float left;
+    __unused float top;
+    __unused float right;
+    __unused float bottom;
+    __unused uint8_t segmentMask;    // Some of the unused fields are in a different order in 22/23
+    __unused uint8_t boundsIsDirty;
+    __unused uint8_t isFinite;
+    __unused uint8_t isOval;
+             Point* points;
+             Verb* verbs;
+             int verbCount;
+    __unused int pointCount;
+    __unused size_t freeSpace;
+             float* conicWeights;
+    __unused int conicWeightsReserve;
+    __unused int conicWeightsCount;
+    __unused uint32_t generationId;
+};
+
+struct PathRef24 {
+    __unused intptr_t pointer;
+    __unused int32_t refCount;
+    __unused float left;
+    __unused float top;
+    __unused float right;
+    __unused float bottom;
+             Point* points;
+             Verb* verbs;
+             int verbCount;
+    __unused int pointCount;
+    __unused size_t freeSpace;
+             float* conicWeights;
+    __unused int conicWeightsReserve;
+    __unused int conicWeightsCount;
+    __unused uint32_t generationId;
+};
+
+struct PathRef26 {
+    __unused int32_t refCount;
+    __unused float left;
+    __unused float top;
+    __unused float right;
+    __unused float bottom;
+             Point* points;
+             Verb* verbs;
+             int verbCount;
+    __unused int pointCount;
+    __unused size_t freeSpace;
+             float* conicWeights;
+    __unused int conicWeightsReserve;
+    __unused int conicWeightsCount;
+    __unused uint32_t generationId;
+};
+
+struct PathRef30 {
+    __unused int32_t refCount;
+    __unused float left;
+    __unused float top;
+    __unused float right;
+    __unused float bottom;
+             Point* points;
+    __unused int pointReserve;
+    __unused int pointCount;
+             Verb* verbs;
+    __unused int verbReserve;
+             int verbCount;
+             float* conicWeights;
+    __unused int conicWeightsReserve;
+    __unused int conicWeightsCount;
+    __unused uint32_t generationId;
+};
+
+struct Path {
+    PathRef21* pathRef;
+};
+
+#endif //PATH_PATH_H
diff --git a/graphics/graphics-path/src/main/cpp/PathIterator.cpp b/graphics/graphics-path/src/main/cpp/PathIterator.cpp
new file mode 100644
index 0000000..a77e251
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/PathIterator.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PathIterator.h"
+
+int PathIterator::count() noexcept {
+    int count = 0;
+    const Verb* verbs = mVerbs;
+    const Point* points = mPoints;
+    const float* conicWeights = mConicWeights;
+
+    for (int i = 0; i < mCount; i++) {
+        Verb verb = *(mDirection == VerbDirection::Forward ? verbs++ : --verbs);
+        switch (verb) {
+            case Verb::Move:
+            case Verb::Line:
+                points += 1;
+                count++;
+                break;
+            case Verb::Quadratic:
+                points += 2;
+                count++;
+                break;
+            case Verb::Conic:
+                points += 2;
+                count++;
+                break;
+            case Verb::Cubic:
+                points += 3;
+                count++;
+                break;
+            case Verb::Close:
+            case Verb::Done:
+                count++;
+                break;
+        }
+    }
+
+    return count;
+}
+
+Verb PathIterator::next(Point points[4]) noexcept {
+    if (mIndex <= 0) {
+        return Verb::Done;
+    }
+    mIndex--;
+
+    Verb verb = *(mDirection == VerbDirection::Forward ? mVerbs++ : --mVerbs);
+    switch (verb) {
+        case Verb::Move:
+            points[0] = mPoints[0];
+            mPoints += 1;
+            break;
+        case Verb::Line:
+            points[0] = mPoints[-1];
+            points[1] = mPoints[0];
+            mPoints += 1;
+            break;
+        case Verb::Quadratic:
+            points[0] = mPoints[-1];
+            points[1] = mPoints[0];
+            points[2] = mPoints[1];
+            mPoints += 2;
+            break;
+        case Verb::Conic:
+            points[0] = mPoints[-1];
+            points[1] = mPoints[0];
+            points[2] = mPoints[1];
+            points[3].x = *mConicWeights;
+            points[3].y = *mConicWeights;
+            mConicWeights++;
+            mPoints += 2;
+            break;
+        case Verb::Cubic:
+            points[0] = mPoints[-1];
+            points[1] = mPoints[0];
+            points[2] = mPoints[1];
+            points[3] = mPoints[2];
+            mPoints += 3;
+            break;
+        case Verb::Close:
+        case Verb::Done:
+            break;
+    }
+
+    return verb;
+}
diff --git a/graphics/graphics-path/src/main/cpp/PathIterator.h b/graphics/graphics-path/src/main/cpp/PathIterator.h
new file mode 100644
index 0000000..f814863
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/PathIterator.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PATH_PATH_ITERATOR_H
+#define PATH_PATH_ITERATOR_H
+
+#include "Path.h"
+#include "Conic.h"
+
+class PathIterator {
+public:
+    enum class VerbDirection : uint8_t  {
+        Forward, // API >=30
+        Backward // API < 30
+    };
+
+    PathIterator(
+            Point* points,
+            Verb* verbs,
+            float* conicWeights,
+            int count,
+            VerbDirection direction
+    ) noexcept
+            : mPoints(points),
+              mVerbs(verbs),
+              mConicWeights(conicWeights),
+              mIndex(count),
+              mCount(count),
+              mDirection(direction) {
+    }
+
+    int rawCount() const noexcept { return mCount; }
+
+    int count() noexcept;
+
+    bool hasNext() const noexcept { return mIndex > 0; }
+
+    Verb peek() const noexcept {
+        auto verbs = mDirection == VerbDirection::Forward ? mVerbs : mVerbs - 1;
+        return mIndex > 0 ? *verbs : Verb::Done;
+    }
+
+    Verb next(Point points[4]) noexcept;
+
+private:
+    const Point* mPoints;
+    const Verb* mVerbs;
+    const float* mConicWeights;
+    int mIndex;
+    const int mCount;
+    const VerbDirection mDirection;
+    ConicConverter mConverter;
+};
+
+#endif //PATH_PATH_ITERATOR_H
diff --git a/graphics/graphics-path/src/main/cpp/math/TVecHelpers.h b/graphics/graphics-path/src/main/cpp/math/TVecHelpers.h
new file mode 100644
index 0000000..be00ebd
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/math/TVecHelpers.h
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef TNT_MATH_TVECHELPERS_H
+#define TNT_MATH_TVECHELPERS_H
+
+#include "compiler.h"
+
+#include <cmath>            // for std:: namespace
+
+#include <math.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace filament {
+namespace math {
+namespace details {
+// -------------------------------------------------------------------------------------
+
+template<typename U>
+inline constexpr U min(U a, U b) noexcept {
+    return a < b ? a : b;
+}
+
+template<typename U>
+inline constexpr U max(U a, U b) noexcept {
+    return a > b ? a : b;
+}
+
+template<typename T, typename U>
+struct arithmetic_result {
+    using type = decltype(std::declval<T>() + std::declval<U>());
+};
+
+template<typename T, typename U>
+using arithmetic_result_t = typename arithmetic_result<T, U>::type;
+
+template<typename A, typename B = int, typename C = int, typename D = int>
+using enable_if_arithmetic_t = std::enable_if_t<
+        is_arithmetic<A>::value &&
+        is_arithmetic<B>::value &&
+        is_arithmetic<C>::value &&
+        is_arithmetic<D>::value>;
+
+/*
+ * No user serviceable parts here.
+ *
+ * Don't use this file directly, instead include math/vec{2|3|4}.h
+ */
+
+/*
+ * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
+ * operators on a vector of type BASE<T>.
+ *
+ * BASE only needs to implement operator[] and size().
+ * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
+ * get all the functionality here.
+ */
+
+template<template<typename T> class VECTOR, typename T>
+class TVecAddOperators {
+public:
+    /* compound assignment from a another vector of the same size but different
+     * element type.
+     */
+    template<typename U>
+    constexpr VECTOR<T>& operator+=(const VECTOR<U>& v) {
+        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
+        for (size_t i = 0; i < lhs.size(); i++) {
+            lhs[i] += v[i];
+        }
+        return lhs;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    constexpr VECTOR<T>& operator+=(U v) {
+        return operator+=(VECTOR<U>(v));
+    }
+
+    template<typename U>
+    constexpr VECTOR<T>& operator-=(const VECTOR<U>& v) {
+        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
+        for (size_t i = 0; i < lhs.size(); i++) {
+            lhs[i] -= v[i];
+        }
+        return lhs;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    constexpr VECTOR<T>& operator-=(U v) {
+        return operator-=(VECTOR<U>(v));
+    }
+
+private:
+    /*
+     * NOTE: the functions below ARE NOT member methods. They are friend functions
+     * with they definition inlined with their declaration. This makes these
+     * template functions available to the compiler when (and only when) this class
+     * is instantiated, at which point they're only templated on the 2nd parameter
+     * (the first one, BASE<T> being known).
+     */
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator+(const VECTOR<T>& lv, const VECTOR<U>& rv)
+    {
+        VECTOR<arithmetic_result_t<T, U>> res(lv);
+        res += rv;
+        return res;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator+(const VECTOR<T>& lv, U rv) {
+        return lv + VECTOR<U>(rv);
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator+(U lv, const VECTOR<T>& rv) {
+        return VECTOR<U>(lv) + rv;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator-(const VECTOR<T>& lv, const VECTOR<U>& rv)
+    {
+        VECTOR<arithmetic_result_t<T, U>> res(lv);
+        res -= rv;
+        return res;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator-(const VECTOR<T>& lv, U rv) {
+        return lv - VECTOR<U>(rv);
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator-(U lv, const VECTOR<T>& rv) {
+        return VECTOR<U>(lv) - rv;
+    }
+};
+
+template<template<typename T> class VECTOR, typename T>
+class TVecProductOperators {
+public:
+    /* compound assignment from a another vector of the same size but different
+     * element type.
+     */
+    template<typename U>
+    constexpr VECTOR<T>& operator*=(const VECTOR<U>& v) {
+        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
+        for (size_t i = 0; i < lhs.size(); i++) {
+            lhs[i] *= v[i];
+        }
+        return lhs;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    constexpr VECTOR<T>& operator*=(U v) {
+        return operator*=(VECTOR<U>(v));
+    }
+
+    template<typename U>
+    constexpr VECTOR<T>& operator/=(const VECTOR<U>& v) {
+        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
+        for (size_t i = 0; i < lhs.size(); i++) {
+            lhs[i] /= v[i];
+        }
+        return lhs;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    constexpr VECTOR<T>& operator/=(U v) {
+        return operator/=(VECTOR<U>(v));
+    }
+
+private:
+    /*
+     * NOTE: the functions below ARE NOT member methods. They are friend functions
+     * with they definition inlined with their declaration. This makes these
+     * template functions available to the compiler when (and only when) this class
+     * is instantiated, at which point they're only templated on the 2nd parameter
+     * (the first one, BASE<T> being known).
+     */
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator*(const VECTOR<T>& lv, const VECTOR<U>& rv)
+    {
+        VECTOR<arithmetic_result_t<T, U>> res(lv);
+        res *= rv;
+        return res;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator*(const VECTOR<T>& lv, U rv) {
+        return lv * VECTOR<U>(rv);
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator*(U lv, const VECTOR<T>& rv) {
+        return VECTOR<U>(lv) * rv;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator/(const VECTOR<T>& lv, const VECTOR<U>& rv)
+    {
+        VECTOR<arithmetic_result_t<T, U>> res(lv);
+        res /= rv;
+        return res;
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator/(const VECTOR<T>& lv, U rv) {
+        return lv / VECTOR<U>(rv);
+    }
+
+    template<typename U, typename = enable_if_arithmetic_t<U>>
+    friend inline constexpr
+    VECTOR<arithmetic_result_t<T, U>> MATH_PURE operator/(U lv, const VECTOR<T>& rv) {
+        return VECTOR<U>(lv) / rv;
+    }
+};
+
+/*
+ * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
+ *
+ * BASE only needs to implement operator[] and size().
+ * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
+ * get all the functionality here.
+ *
+ * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
+ */
+template<template<typename T> class VECTOR, typename T>
+class TVecUnaryOperators {
+public:
+    constexpr VECTOR<T> operator-() const {
+        VECTOR<T> r{};
+        VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
+        for (size_t i = 0; i < r.size(); i++) {
+            r[i] = -rv[i];
+        }
+        return r;
+    }
+};
+
+/*
+ * TVecComparisonOperators implements relational/comparison operators
+ * on a vector of type BASE<T>.
+ *
+ * BASE only needs to implement operator[] and size().
+ * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
+ * get all the functionality here.
+ */
+template<template<typename T> class VECTOR, typename T>
+class TVecComparisonOperators {
+private:
+    /*
+     * NOTE: the functions below ARE NOT member methods. They are friend functions
+     * with they definition inlined with their declaration. This makes these
+     * template functions available to the compiler when (and only when) this class
+     * is instantiated, at which point they're only templated on the 2nd parameter
+     * (the first one, BASE<T> being known).
+     */
+    template<typename U>
+    friend inline constexpr
+    bool MATH_PURE operator==(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        // w/ inlining we end-up with many branches that will pollute the BPU cache
+        MATH_NOUNROLL
+        for (size_t i = 0; i < lv.size(); i++) {
+            if (lv[i] != rv[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    bool MATH_PURE operator!=(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        return !operator==(lv, rv);
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<bool> MATH_PURE equal(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] == rv[i];
+        }
+        return r;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<bool> MATH_PURE notEqual(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] != rv[i];
+        }
+        return r;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<bool> MATH_PURE lessThan(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] < rv[i];
+        }
+        return r;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<bool> MATH_PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] <= rv[i];
+        }
+        return r;
+    }
+
+    template<typename U>
+    friend inline constexpr
+    VECTOR<bool> MATH_PURE greaterThan(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r;
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] > rv[i];
+        }
+        return r;
+    }
+
+    template<typename U>
+    friend inline
+    VECTOR<bool> MATH_PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        VECTOR<bool> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r[i] = lv[i] >= rv[i];
+        }
+        return r;
+    }
+};
+
+/*
+ * TVecFunctions implements functions on a vector of type BASE<T>.
+ *
+ * BASE only needs to implement operator[] and size().
+ * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
+ * get all the functionality here.
+ */
+template<template<typename T> class VECTOR, typename T>
+class TVecFunctions {
+private:
+    /*
+     * NOTE: the functions below ARE NOT member methods. They are friend functions
+     * with they definition inlined with their declaration. This makes these
+     * template functions available to the compiler when (and only when) this class
+     * is instantiated, at which point they're only templated on the 2nd parameter
+     * (the first one, BASE<T> being known).
+     */
+    template<typename U>
+    friend constexpr inline
+    arithmetic_result_t<T, U> MATH_PURE dot(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        arithmetic_result_t<T, U> r{};
+        for (size_t i = 0; i < lv.size(); i++) {
+            r += lv[i] * rv[i];
+        }
+        return r;
+    }
+
+    friend inline T MATH_PURE norm(const VECTOR<T>& lv) {
+        return std::sqrt(dot(lv, lv));
+    }
+
+    friend inline T MATH_PURE length(const VECTOR<T>& lv) {
+        return norm(lv);
+    }
+
+    friend inline constexpr T MATH_PURE norm2(const VECTOR<T>& lv) {
+        return dot(lv, lv);
+    }
+
+    friend inline constexpr T MATH_PURE length2(const VECTOR<T>& lv) {
+        return norm2(lv);
+    }
+
+    template<typename U>
+    friend inline constexpr
+    arithmetic_result_t<T, U> MATH_PURE distance(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        return length(rv - lv);
+    }
+
+    template<typename U>
+    friend inline constexpr
+    arithmetic_result_t<T, U> MATH_PURE distance2(const VECTOR<T>& lv, const VECTOR<U>& rv) {
+        return length2(rv - lv);
+    }
+
+    friend inline VECTOR<T> MATH_PURE normalize(const VECTOR<T>& lv) {
+        return lv * (T(1) / length(lv));
+    }
+
+    friend inline VECTOR<T> MATH_PURE rcp(VECTOR<T> v) {
+        return T(1) / v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE abs(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = v[i] < 0 ? -v[i] : v[i];
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE floor(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::floor(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE ceil(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::ceil(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE round(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::round(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE inversesqrt(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = T(1) / std::sqrt(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE sqrt(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::sqrt(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE cbrt(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::cbrt(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE exp(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::exp(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE pow(VECTOR<T> v, T p) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::pow(v[i], p);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE pow(T v, VECTOR<T> p) {
+        for (size_t i = 0; i < p.size(); i++) {
+            p[i] = std::pow(v, p[i]);
+        }
+        return p;
+    }
+
+    friend inline VECTOR<T> MATH_PURE pow(VECTOR<T> v, VECTOR<T> p) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::pow(v[i], p[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE log(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::log(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE log10(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::log10(v[i]);
+        }
+        return v;
+    }
+
+    friend inline VECTOR<T> MATH_PURE log2(VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = std::log2(v[i]);
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE saturate(const VECTOR<T>& lv) {
+        return clamp(lv, T(0), T(1));
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE clamp(VECTOR<T> v, T min, T max) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = details::min(max, details::max(min, v[i]));
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE clamp(VECTOR<T> v, VECTOR<T> min, VECTOR<T> max) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = details::min(max[i], details::max(min[i], v[i]));
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv,
+            VECTOR<T> a) {
+        for (size_t i = 0; i < lv.size(); i++) {
+            a[i] += (lv[i] * rv[i]);
+        }
+        return a;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE min(const VECTOR<T>& u, VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = details::min(u[i], v[i]);
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE max(const VECTOR<T>& u, VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = details::max(u[i], v[i]);
+        }
+        return v;
+    }
+
+    friend inline constexpr T MATH_PURE max(const VECTOR<T>& v) {
+        T r(v[0]);
+        for (size_t i = 1; i < v.size(); i++) {
+            r = max(r, v[i]);
+        }
+        return r;
+    }
+
+    friend inline constexpr T MATH_PURE min(const VECTOR<T>& v) {
+        T r(v[0]);
+        for (size_t i = 1; i < v.size(); i++) {
+            r = min(r, v[i]);
+        }
+        return r;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE mix(const VECTOR<T>& u, VECTOR<T> v, T a) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = u[i] * (T(1) - a) + v[i] * a;
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE smoothstep(T edge0, T edge1, VECTOR<T> v) {
+        VECTOR<T> t = saturate((v - edge0) / (edge1 - edge0));
+        return t * t * (T(3) - T(2) * t);
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE step(T edge, VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = v[i] < edge ? T(0) : T(1);
+        }
+        return v;
+    }
+
+    friend inline constexpr VECTOR<T> MATH_PURE step(VECTOR<T> edge, VECTOR<T> v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            v[i] = v[i] < edge[i] ? T(0) : T(1);
+        }
+        return v;
+    }
+
+    friend inline constexpr bool MATH_PURE any(const VECTOR<T>& v) {
+        for (size_t i = 0; i < v.size(); i++) {
+            if (v[i] != T(0)) return true;
+        }
+        return false;
+    }
+
+    friend inline constexpr bool MATH_PURE all(const VECTOR<T>& v) {
+        bool result = true;
+        for (size_t i = 0; i < v.size(); i++) {
+            result &= (v[i] != T(0));
+        }
+        return result;
+    }
+};
+
+// -------------------------------------------------------------------------------------
+}  // namespace details
+}  // namespace math
+}  // namespace filament
+
+#endif  // TNT_MATH_TVECHELPERS_H
diff --git a/graphics/graphics-path/src/main/cpp/math/compiler.h b/graphics/graphics-path/src/main/cpp/math/compiler.h
new file mode 100644
index 0000000..d6e18aa
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/math/compiler.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PATH_MATH_COMPILER_H
+#define PATH_MATH_COMPILER_H
+
+#include <type_traits>
+
+#if defined (WIN32)
+
+#ifdef max
+#undef max
+#endif
+
+#ifdef min
+#undef min
+#endif
+
+#ifdef far
+#undef far
+#endif
+
+#ifdef near
+#undef near
+#endif
+
+#endif
+
+// compatibility with non-clang compilers...
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+#if __has_builtin(__builtin_expect)
+#   ifdef __cplusplus
+#      define MATH_LIKELY( exp )    (__builtin_expect( !!(exp), true ))
+#      define MATH_UNLIKELY( exp )  (__builtin_expect( !!(exp), false ))
+#   else
+#      define MATH_LIKELY( exp )    (__builtin_expect( !!(exp), 1 ))
+#      define MATH_UNLIKELY( exp )  (__builtin_expect( !!(exp), 0 ))
+#   endif
+#else
+#   define MATH_LIKELY( exp )    (exp)
+#   define MATH_UNLIKELY( exp )  (exp)
+#endif
+
+#if __has_attribute(unused)
+#   define MATH_UNUSED __attribute__((unused))
+#else
+#   define MATH_UNUSED
+#endif
+
+#if __has_attribute(pure)
+#   define MATH_PURE __attribute__((pure))
+#else
+#   define MATH_PURE
+#endif
+
+#ifdef _MSC_VER
+#   define MATH_EMPTY_BASES __declspec(empty_bases)
+
+// MSVC does not support loop unrolling hints
+#   define MATH_NOUNROLL
+
+// Sadly, MSVC does not support __builtin_constant_p
+#   ifndef MAKE_CONSTEXPR
+#       define MAKE_CONSTEXPR(e) (e)
+#   endif
+
+// About value initialization, the C++ standard says:
+//   if T is a class type with a default constructor that is neither user-provided nor deleted
+//   (that is, it may be a class with an implicitly-defined or defaulted default constructor),
+//   the object is zero-initialized and then it is default-initialized
+//   if it has a non-trivial default constructor;
+// Unfortunately, MSVC always calls the default constructor, even if it is trivial, which
+// breaks constexpr-ness. To workaround this, we're always zero-initializing TVecN<>
+#   define MATH_CONSTEXPR_INIT {}
+#   define MATH_DEFAULT_CTOR {}
+#   define MATH_DEFAULT_CTOR_CONSTEXPR constexpr
+#   define CONSTEXPR_IF_NOT_MSVC // when declared constexpr, msvc fails with
+                                 // "failure was caused by cast of object of dynamic type"
+
+#else // _MSC_VER
+
+#   define MATH_EMPTY_BASES
+// C++11 allows pragmas to be specified as part of defines using the _Pragma syntax.
+#   define MATH_NOUNROLL _Pragma("nounroll")
+
+#   ifndef MAKE_CONSTEXPR
+#       define MAKE_CONSTEXPR(e) __builtin_constant_p(e) ? (e) : (e)
+#   endif
+
+#   define MATH_CONSTEXPR_INIT
+#   define MATH_DEFAULT_CTOR = default;
+#   define MATH_DEFAULT_CTOR_CONSTEXPR
+#   define CONSTEXPR_IF_NOT_MSVC constexpr
+
+#endif // _MSC_VER
+
+namespace filament::math {
+
+// MSVC 2019 16.4 doesn't seem to like it when we specialize std::is_arithmetic for
+// filament::math::half, so we're forced to create our own is_arithmetic here and specialize it
+// inside of half.h.
+template<typename T>
+struct is_arithmetic : std::integral_constant<bool,
+        std::is_integral<T>::value || std::is_floating_point<T>::value> {
+};
+
+} // filament::math
+
+#endif // PATH_MATH_COMPILER_H
diff --git a/graphics/graphics-path/src/main/cpp/math/vec2.h b/graphics/graphics-path/src/main/cpp/math/vec2.h
new file mode 100644
index 0000000..3228b09
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/math/vec2.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef TNT_MATH_VEC2_H
+#define TNT_MATH_VEC2_H
+
+#include "TVecHelpers.h"
+
+#include <type_traits>
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace filament {
+namespace math {
+// -------------------------------------------------------------------------------------
+
+namespace details {
+
+template<typename T>
+class MATH_EMPTY_BASES TVec2 :
+        public TVecProductOperators<TVec2, T>,
+        public TVecAddOperators<TVec2, T>,
+        public TVecUnaryOperators<TVec2, T>,
+        public TVecComparisonOperators<TVec2, T>,
+        public TVecFunctions<TVec2, T> {
+public:
+    typedef T value_type;
+    typedef T& reference;
+    typedef T const& const_reference;
+    typedef size_t size_type;
+    static constexpr size_t SIZE = 2;
+
+    union {
+        T v[SIZE] MATH_CONSTEXPR_INIT;
+        struct { T x, y; };
+        struct { T s, t; };
+        struct { T r, g; };
+    };
+
+    inline constexpr size_type size() const { return SIZE; }
+
+    // array access
+    inline constexpr T const& operator[](size_t i) const noexcept {
+        assert(i < SIZE);
+        return v[i];
+    }
+
+    inline constexpr T& operator[](size_t i) noexcept {
+        assert(i < SIZE);
+        return v[i];
+    }
+
+    // constructors
+
+    // default constructor
+    MATH_DEFAULT_CTOR_CONSTEXPR TVec2() MATH_DEFAULT_CTOR
+
+    // handles implicit conversion to a tvec4. must not be explicit.
+    template<typename A, typename = enable_if_arithmetic_t<A>>
+    constexpr TVec2(A v) noexcept : v{ T(v), T(v) } {}
+
+    template<typename A, typename B, typename = enable_if_arithmetic_t<A, B>>
+    constexpr TVec2(A x, B y) noexcept : v{ T(x), T(y) } {}
+
+    template<typename A, typename = enable_if_arithmetic_t<A>>
+    constexpr TVec2(const TVec2<A>& v) noexcept : v{ T(v[0]), T(v[1]) } {}
+
+    // cross product works only on vectors of size 2 or 3
+    template<typename U>
+    friend inline constexpr
+    arithmetic_result_t<T, U> cross(const TVec2& u, const TVec2<U>& v) noexcept {
+        return u[0] * v[1] - u[1] * v[0];
+    }
+};
+
+}  // namespace details
+
+// ----------------------------------------------------------------------------------------
+
+template<typename T, typename = details::enable_if_arithmetic_t<T>>
+using vec2 = details::TVec2<T>;
+
+using double2 = vec2<double>;
+using float2 = vec2<float>;
+using int2 = vec2<int32_t>;
+using uint2 = vec2<uint32_t>;
+using short2 = vec2<int16_t>;
+using ushort2 = vec2<uint16_t>;
+using byte2 = vec2<int8_t>;
+using ubyte2 = vec2<uint8_t>;
+using bool2 = vec2<bool>;
+
+// ----------------------------------------------------------------------------------------
+}  // namespace math
+}  // namespace filament
+
+#endif  // TNT_MATH_VEC2_H
diff --git a/graphics/graphics-path/src/main/cpp/pathway.cpp b/graphics/graphics-path/src/main/cpp/pathway.cpp
new file mode 100644
index 0000000..9997387
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/pathway.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PathIterator.h"
+
+#include <jni.h>
+
+#include <sys/system_properties.h>
+
+#include <mutex>
+
+#define JNI_CLASS_NAME "androidx/graphics/path/PathIteratorPreApi34Impl"
+#define JNI_CLASS_NAME_CONVERTER "androidx/graphics/path/ConicConverter"
+
+#if !defined(NDEBUG)
+#include <android/log.h>
+#define ANDROID_LOG_TAG "PathIterator"
+#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, ANDROID_LOG_TAG, __VA_ARGS__)
+#endif
+
+struct {
+    jclass jniClass;
+    jfieldID nativePath;
+} sPath{};
+
+uint32_t sApiLevel = 0;
+std::once_flag sApiLevelOnceFlag;
+
+static uint32_t api_level() {
+    std::call_once(sApiLevelOnceFlag, []() {
+        char sdkVersion[PROP_VALUE_MAX];
+        __system_property_get("ro.build.version.sdk", sdkVersion);
+        sApiLevel = atoi(sdkVersion); // NOLINT(cert-err34-c)
+    });
+    return sApiLevel;
+}
+
+static jlong createPathIterator(JNIEnv* env, jobject,
+        jobject path_, jint conicEvaluation_, jfloat tolerance_) {
+
+    auto nativePath = static_cast<intptr_t>(env->GetLongField(path_, sPath.nativePath));
+    auto* path = reinterpret_cast<Path*>(nativePath);
+
+    Point* points;
+    Verb* verbs;
+    float* conicWeights;
+    int count;
+    PathIterator::VerbDirection direction;
+
+    const uint32_t apiLevel = api_level();
+    if (apiLevel >= 30) {
+        auto* ref = reinterpret_cast<PathRef30*>(path->pathRef);
+        points = ref->points;
+        verbs = ref->verbs;
+        conicWeights = ref->conicWeights;
+        count = ref->verbCount;
+        direction = PathIterator::VerbDirection::Forward;
+    } else if (apiLevel >= 26) {
+        auto* ref = reinterpret_cast<PathRef26*>(path->pathRef);
+        points = ref->points;
+        verbs = ref->verbs;
+        conicWeights = ref->conicWeights;
+        count = ref->verbCount;
+        direction = PathIterator::VerbDirection::Backward;
+    } else if (apiLevel >= 24) {
+        auto* ref = reinterpret_cast<PathRef24*>(path->pathRef);
+        points = ref->points;
+        verbs = ref->verbs;
+        conicWeights = ref->conicWeights;
+        count = ref->verbCount;
+        direction = PathIterator::VerbDirection::Backward;
+    } else {
+        auto* ref = path->pathRef;
+        points = ref->points;
+        verbs = ref->verbs;
+        conicWeights = ref->conicWeights;
+        count = ref->verbCount;
+        direction = PathIterator::VerbDirection::Backward;
+    }
+
+    return jlong(new PathIterator(points, verbs, conicWeights, count, direction));
+}
+
+static void destroyPathIterator(JNIEnv*, jobject, jlong pathIterator_) {
+    delete reinterpret_cast<PathIterator*>(pathIterator_);
+}
+
+static jboolean pathIteratorHasNext(JNIEnv*, jobject, jlong pathIterator_) {
+    return reinterpret_cast<PathIterator*>(pathIterator_)->hasNext();
+}
+
+static jint conicToQuadraticsWrapper(JNIEnv* env, jobject,
+                                      jfloatArray conicPoints, jfloatArray quadraticPoints,
+                                      jfloat weight, jfloat tolerance, jint offset) {
+    float *conicData1 = env->GetFloatArrayElements(conicPoints, JNI_FALSE);
+    float *quadData1 = env->GetFloatArrayElements(quadraticPoints, JNI_FALSE);
+    int quadDataSize = env->GetArrayLength(quadraticPoints);
+
+    int count = conicToQuadratics(reinterpret_cast<Point *>(conicData1 + offset),
+                                  reinterpret_cast<Point *>(quadData1),
+                                  env->GetArrayLength(quadraticPoints),
+                                  weight, tolerance);
+
+    env->ReleaseFloatArrayElements(conicPoints, conicData1, 0);
+    env->ReleaseFloatArrayElements(quadraticPoints, quadData1, 0);
+
+    return count;
+}
+
+static jint pathIteratorNext(JNIEnv* env, jobject,
+                             jlong pathIterator_, jfloatArray points_, jint offset_) {
+    auto pathIterator = reinterpret_cast<PathIterator*>(pathIterator_);
+    Point pointsData[4];
+    Verb verb = pathIterator->next(pointsData);
+
+    if (verb != Verb::Done && verb != Verb::Close) {
+        auto* floatsData = reinterpret_cast<jfloat*>(pointsData);
+        env->SetFloatArrayRegion(points_, offset_, 8, floatsData);
+    }
+
+    return static_cast<jint>(verb);
+}
+
+static jint pathIteratorPeek(JNIEnv*, jobject, jlong pathIterator_) {
+    return static_cast<jint>(reinterpret_cast<PathIterator *>(pathIterator_)->peek());
+}
+
+static jint pathIteratorRawSize(JNIEnv*, jobject, jlong pathIterator_) {
+    return static_cast<jint>(reinterpret_cast<PathIterator *>(pathIterator_)->rawCount());
+}
+
+static jint pathIteratorSize(JNIEnv*, jobject, jlong pathIterator_) {
+    return static_cast<jint>(reinterpret_cast<PathIterator *>(pathIterator_)->count());
+}
+
+JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
+    JNIEnv* env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        return -1;
+    }
+
+    sPath.jniClass = env->FindClass("android/graphics/Path");
+    if (sPath.jniClass == nullptr) return JNI_ERR;
+
+    sPath.nativePath = env->GetFieldID(sPath.jniClass, "mNativePath", "J");
+    if (sPath.nativePath == nullptr) return JNI_ERR;
+
+    {
+        jclass pathsClass = env->FindClass(JNI_CLASS_NAME);
+        if (pathsClass == nullptr) return JNI_ERR;
+
+        static const JNINativeMethod methods[] = {
+                {
+                    (char*) "createInternalPathIterator",
+                    (char*) "(Landroid/graphics/Path;IF)J",
+                    reinterpret_cast<void*>(createPathIterator)
+                },
+                {
+                    (char*) "destroyInternalPathIterator",
+                    (char*) "(J)V",
+                    reinterpret_cast<void*>(destroyPathIterator)
+                },
+                {
+                    (char*) "internalPathIteratorHasNext",
+                    (char*) "(J)Z",
+                    reinterpret_cast<void*>(pathIteratorHasNext)
+                },
+                {
+                    (char*) "internalPathIteratorNext",
+                    (char*) "(J[FI)I",
+                    reinterpret_cast<void*>(pathIteratorNext)
+                },
+                {
+                    (char*) "internalPathIteratorPeek",
+                    (char*) "(J)I",
+                    reinterpret_cast<void*>(pathIteratorPeek)
+                },
+                {
+                    (char*) "internalPathIteratorRawSize",
+                    (char*) "(J)I",
+                    reinterpret_cast<void*>(pathIteratorRawSize)
+                },
+                {
+                    (char*) "internalPathIteratorSize",
+                    (char*) "(J)I",
+                    reinterpret_cast<void*>(pathIteratorSize)
+                },
+        };
+
+        int result = env->RegisterNatives(
+                pathsClass, methods, sizeof(methods) / sizeof(JNINativeMethod)
+        );
+        if (result != JNI_OK) return result;
+
+        env->DeleteLocalRef(pathsClass);
+
+        jclass converterClass = env->FindClass(JNI_CLASS_NAME_CONVERTER);
+        if (converterClass == nullptr) return JNI_ERR;
+        static const JNINativeMethod methods2[] = {
+                {
+                    (char *) "internalConicToQuadratics",
+                    (char *) "([F[FFFI)I",
+                    reinterpret_cast<void *>(conicToQuadraticsWrapper)
+                },
+        };
+
+        result = env->RegisterNatives(
+                converterClass, methods2, sizeof(methods2) / sizeof(JNINativeMethod)
+        );
+        if (result != JNI_OK) return result;
+
+        env->DeleteLocalRef(converterClass);
+    }
+
+    return JNI_VERSION_1_6;
+}
diff --git a/graphics/graphics-path/src/main/cpp/scalar.h b/graphics/graphics-path/src/main/cpp/scalar.h
new file mode 100644
index 0000000..0342d13
--- /dev/null
+++ b/graphics/graphics-path/src/main/cpp/scalar.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PATH_SCALAR_H
+#define PATH_SCALAR_H
+
+union floatIntUnion {
+    float   value;
+    int32_t signBitInt;
+};
+
+static inline int32_t float2Bits(float x) noexcept {
+    floatIntUnion data; // NOLINT(cppcoreguidelines-pro-type-member-init)
+    data.value = x;
+    return data.signBitInt;
+}
+
+constexpr bool isFloatFinite(int32_t bits) noexcept {
+    constexpr int32_t kFloatBitsExponentMask = 0x7F800000;
+    return (bits & kFloatBitsExponentMask) != kFloatBitsExponentMask;
+}
+
+static inline bool isFinite(float v) noexcept {
+    return isFloatFinite(float2Bits(v));
+}
+
+#pragma clang diagnostic push
+#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
+static bool canNormalize(float dx, float dy) noexcept {
+    return (isFinite(dx) && isFinite(dy)) && (dx || dy);
+}
+#pragma clang diagnostic pop
+
+static bool equals(const Point& p1, const Point& p2) noexcept {
+    return !canNormalize(p1.x - p2.x, p1.y - p2.y);
+}
+
+constexpr bool isFinite(const float array[], int count) noexcept {
+    float prod = 0.0f;
+    for (int i = 0; i < count; i++) {
+        prod *= array[i];
+    }
+    return prod == 0.0f;
+}
+
+template<typename T>
+constexpr T tabs(T value) noexcept {
+    if (value < 0) {
+        value = -value;
+    }
+    return value;
+}
+
+constexpr bool between(float a, float b, float c) noexcept {
+    return (a - b) * (c - b) <= 0.0f;
+}
+
+#endif //PATH_SCALAR_H
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt
new file mode 100644
index 0000000..445bd47
--- /dev/null
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/ConicConverter.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.graphics.path
+
+import android.util.Log
+
+/**
+ * This class converts a given Conic object to the equivalent set of Quadratic objects.
+ * It stores all quadratics from a conversion in the call to [convert], but returns only
+ * one at a time, from nextQuadratic(), storing the rest for later retrieval (since a
+ * PathIterator only retrieves one object at a time).
+ *
+ * This object is stateful, using quadraticCount, currentQuadratic, and quadraticData
+ * to send back the next quadratic when requested, in [nextQuadratic].
+ */
+internal class ConicConverter() {
+
+    private val LOG_TAG = "ConicConverter"
+    private val DEBUG = false
+
+    /**
+     * The total number of quadratics currently stored in the converter
+     */
+    var quadraticCount: Int = 0
+        private set
+
+    /**
+     * The index of the current Quadratic; this is the next quadratic to be returned
+     * in the call to nextQuadratic().
+     */
+    var currentQuadratic = 0
+
+    /**
+     * Storage for all quadratics for a particular conic. Set to reasonable
+     * default size, will need to resize if we ever get a return count larger
+     * than the current size.
+     * Initial size holds up to 5 quadratics: 2 floats/point, 3 points/quadratic
+     * where all quadratics overlap in one point except the ends.
+     */
+    private var quadraticData = FloatArray(1)
+
+    /**
+     * This function stores the next converted quadratic in the given points array,
+     * returning true if this happened, false if there was no quadratic to be returned.
+     */
+    fun nextQuadratic(points: FloatArray, offset: Int = 0): Boolean {
+        if (currentQuadratic < quadraticCount) {
+            val index = currentQuadratic * 2 * 2
+            points[0 + offset] = quadraticData[index]
+            points[1 + offset] = quadraticData[index + 1]
+            points[2 + offset] = quadraticData[index + 2]
+            points[3 + offset] = quadraticData[index + 3]
+            points[4 + offset] = quadraticData[index + 4]
+            points[5 + offset] = quadraticData[index + 5]
+            currentQuadratic++
+            return true
+        }
+        return false
+    }
+
+    /**
+     * Converts the conic in [points] to a series of quadratics, which will all be stored
+     */
+    fun convert(points: FloatArray, weight: Float, tolerance: Float, offset: Int = 0) {
+        quadraticCount = internalConicToQuadratics(points, quadraticData, weight, tolerance, offset)
+        if (quadraticCount > quadraticData.size) {
+            if (DEBUG) Log.d(LOG_TAG, "Resizing quadraticData buffer to $quadraticCount")
+            quadraticData = FloatArray(quadraticCount * 4 * 2)
+            quadraticCount = internalConicToQuadratics(points, quadraticData, weight, tolerance,
+                offset)
+        }
+        currentQuadratic = 0
+        if (DEBUG) Log.d("ConicConverter", "internalConicToQuadratics returned " + quadraticCount)
+    }
+
+    /**
+     * The actual conversion from conic to quadratic data happens in native code, in the library
+     * loaded elsewhere. This JNI function wraps that native functionality.
+     */
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalConicToQuadratics(
+        conicPoints: FloatArray,
+        quadraticPoints: FloatArray,
+        weight: Float,
+        tolerance: Float,
+        offset: Int
+    ): Int
+}
\ No newline at end of file
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIterator.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIterator.kt
new file mode 100644
index 0000000..6567419
--- /dev/null
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIterator.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:JvmName("PathUtilities")
+package androidx.graphics.path
+
+import android.graphics.Path
+import androidx.core.os.BuildCompat
+import androidx.core.os.BuildCompat.PrereleaseSdkCheck
+
+/**
+ * A path iterator can be used to iterate over all the [segments][PathSegment] that make up
+ * a path. Those segments may in turn define multiple contours inside the path. Conic segments
+ * are by default evaluated as approximated quadratic segments. To preserve conic segments as
+ * conics, set [conicEvaluation] to [AsConic][ConicEvaluation.AsConic]. The error of the
+ * approximation is controlled by [tolerance].
+ *
+ * [PathIterator] objects are created implicitly through a given [Path] object; to create a
+ * [PathIterator], call one of the two [Path.iterator] extension functions.
+ */
+@Suppress("NotCloseable", "IllegalExperimentalApiUsage")
+@PrereleaseSdkCheck
+class PathIterator constructor(
+    val path: Path,
+    val conicEvaluation: ConicEvaluation = ConicEvaluation.AsQuadratics,
+    val tolerance: Float = 0.25f
+) : Iterator<PathSegment> {
+
+    internal val implementation: PathIteratorImpl
+    init {
+        implementation =
+            when {
+                // TODO: replace isAtLeastU() check with below or similar when U is released
+                // Build.VERSION.SDK_INT >= 34 -> {
+                BuildCompat.isAtLeastU() -> {
+                    PathIteratorApi34Impl(path, conicEvaluation, tolerance)
+                }
+                else -> {
+                    PathIteratorPreApi34Impl(path, conicEvaluation, tolerance)
+                }
+            }
+    }
+
+    enum class ConicEvaluation {
+        /**
+         * Conic segments are returned as conic segments.
+         */
+        AsConic,
+
+        /**
+         * Conic segments are returned as quadratic approximations. The quality of the
+         * approximation is defined by a tolerance value.
+         */
+        AsQuadratics
+    }
+
+    /**
+     * Returns the number of verbs present in this iterator, i.e. the number of calls to
+     * [next] required to complete the iteration.
+     *
+     * By default, [calculateSize] returns the true number of operations in the iterator. Deriving
+     * this result requires converting any conics to quadratics, if [conicEvaluation] is
+     * set to [ConicEvaluation.AsQuadratics], which takes extra processing time. Set
+     * [includeConvertedConics] to false if an approximate size, not including conic
+     * conversion, is sufficient.
+     *
+     * @param includeConvertedConics The returned size includes any required conic conversions.
+     * Default is true, so it will return the exact size, at the cost of iterating through
+     * all elements and converting any conics as appropriate. Set to false to save on processing,
+     * at the cost of a less exact result.
+     */
+    fun calculateSize(includeConvertedConics: Boolean = true) =
+        implementation.calculateSize(includeConvertedConics)
+
+    /**
+     * Returns `true` if the iteration has more elements.
+     */
+    override fun hasNext(): Boolean = implementation.hasNext()
+
+    /**
+     * Returns the type of the current segment in the iteration, or [Done][PathSegment.Type.Done]
+     * if the iteration is finished.
+     */
+    fun peek() = implementation.peek()
+
+    /**
+     * Returns the [type][PathSegment.Type] of the next [path segment][PathSegment] in the iteration
+     * and fills [points] with the points specific to the segment type. Each pair of floats in
+     * the [points] array represents a point for the given segment. The number of pairs of floats
+     * depends on the [PathSegment.Type]:
+     * - [Move][PathSegment.Type.Move]: 1 pair (indices 0 to 1)
+     * - [Move][PathSegment.Type.Line]: 2 pairs (indices 0 to 3)
+     * - [Move][PathSegment.Type.Quadratic]: 3 pairs (indices 0 to 5)
+     * - [Move][PathSegment.Type.Conic]: 4 pairs (indices 0 to 7), the last pair contains the
+     *   [weight][PathSegment.weight] twice
+     * - [Move][PathSegment.Type.Cubic]: 4 pairs (indices 0 to 7)
+     * - [Close][PathSegment.Type.Close]: 0 pair
+     * - [Done][PathSegment.Type.Done]: 0 pair
+     * This method does not allocate any memory.
+     *
+     * @param points A [FloatArray] large enough to hold 8 floats starting at [offset],
+     *               throws an [IllegalStateException] otherwise.
+     * @param offset Offset in [points] where to store the result
+     */
+    @JvmOverloads
+    fun next(points: FloatArray, offset: Int = 0): PathSegment.Type =
+        implementation.next(points, offset)
+
+    /**
+     * Returns the next [path segment][PathSegment] in the iteration, or [DoneSegment] if
+     * the iteration is finished. To save on allocations, use the alternative [next] function, which
+     * takes a [FloatArray].
+     */
+    override fun next(): PathSegment = implementation.next()
+}
+
+/**
+ * Creates a new [PathIterator] for this [path][android.graphics.Path] that evaluates
+ * conics as quadratics. To preserve conics, use the [Path.iterator] function that takes a
+ * [PathIterator.ConicEvaluation] parameter.
+ */
+@Suppress("IllegalExperimentalApiUsage")
+@PrereleaseSdkCheck
+operator fun Path.iterator() = PathIterator(this)
+
+/**
+ * Creates a new [PathIterator] for this [path][android.graphics.Path]. To preserve conics as
+ * conics (not convert them to quadratics), set [conicEvaluation] to
+ * [PathIterator.ConicEvaluation.AsConic].
+ */
+@Suppress("IllegalExperimentalApiUsage")
+@PrereleaseSdkCheck
+fun Path.iterator(conicEvaluation: PathIterator.ConicEvaluation, tolerance: Float = 0.25f) =
+    PathIterator(this, conicEvaluation, tolerance)
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIteratorImpl.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIteratorImpl.kt
new file mode 100644
index 0000000..65fa2c1
--- /dev/null
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathIteratorImpl.kt
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.graphics.path
+
+import android.graphics.Path
+import android.graphics.PathIterator as PlatformPathIterator
+import android.graphics.PointF
+import androidx.annotation.RequiresApi
+import androidx.core.os.BuildCompat
+import androidx.graphics.path.PathIterator.ConicEvaluation
+
+/**
+ * Base class for API-version-specific PathIterator implementation classes. All functionality
+ * is implemented in the subclasses except for [next], which relies on shared native code
+ * to perform conic conversion.
+ */
+@Suppress("IllegalExperimentalApiUsage")
+@BuildCompat.PrereleaseSdkCheck
+internal abstract class PathIteratorImpl(
+    val path: Path,
+    val conicEvaluation: ConicEvaluation = ConicEvaluation.AsQuadratics,
+    val tolerance: Float = 0.25f
+) {
+    /**
+     * An iterator's ConicConverter converts from a conic to a series of
+     * quadratics. It keeps track of the resulting quadratics and iterates through
+     * them on ensuing calls to next(). The converter is only ever called if
+     * [conicEvaluation] is set to [ConicEvaluation.AsQuadratics].
+     */
+    var conicConverter = ConicConverter()
+
+    /**
+     * pointsData is used internally when the no-arg variant of next() is called,
+     * to avoid allocating a new array every time.
+     */
+    val pointsData = FloatArray(8)
+
+    private companion object {
+        init {
+            /**
+             * The native library is used mainly for pre-API34, but we also rely
+             * on the conic conversion code in API34+, thus it is initialized here.
+             */
+            System.loadLibrary("androidx.graphics.path")
+        }
+    }
+
+    abstract fun calculateSize(includeConvertedConics: Boolean): Int
+
+    abstract fun hasNext(): Boolean
+    abstract fun peek(): PathSegment.Type
+
+    /**
+     * The core functionality of [next] is in API-specific subclasses. But we implement [next]
+     * at this level to share the same conic conversion implementation across all versions.
+     * This happens by calling [nextImpl] to get the next segment from the subclasses, then
+     * calling the shared [ConicConverter] code when appropriate to get and return the
+     * converted segments.
+     */
+    abstract fun nextImpl(points: FloatArray, offset: Int = 0): PathSegment.Type
+
+    fun next(points: FloatArray, offset: Int = 0): PathSegment.Type {
+        check(points.size - offset >= 8) { "The points array must contain at least 8 floats" }
+        // First check to see if we are currently iterating through converted conics
+        if (conicConverter.currentQuadratic < conicConverter.quadraticCount
+        ) {
+            conicConverter.nextQuadratic(points, offset)
+            return (pathSegmentTypes[PathSegment.Type.Quadratic.ordinal])
+        } else {
+            val typeValue = nextImpl(points, offset)
+            if (typeValue == PathSegment.Type.Conic &&
+                conicEvaluation == ConicEvaluation.AsQuadratics
+            ) {
+                with(conicConverter) {
+                    convert(points, points[6 + offset], tolerance, offset)
+                    if (quadraticCount > 0) {
+                        nextQuadratic(points, offset)
+                    }
+                }
+                return PathSegment.Type.Quadratic
+            }
+            return typeValue
+        }
+    }
+
+    fun next(): PathSegment {
+        val type = next(pointsData, 0)
+        if (type == PathSegment.Type.Done) return DoneSegment
+        if (type == PathSegment.Type.Close) return CloseSegment
+        val weight = if (type == PathSegment.Type.Conic) pointsData[6] else 0.0f
+        return PathSegment(type, floatsToPoints(pointsData, type), weight)
+    }
+
+    /**
+     * Utility function to convert a FloatArray to an array of PointF objects, where
+     * every two Floats in the FloatArray correspond to a single PointF in the resulting
+     * point array. The FloatArray is used internally to process a next() call, the
+     * array of points is used to create a PathSegment from the operation.
+     */
+    private fun floatsToPoints(pointsData: FloatArray, type: PathSegment.Type): Array<PointF> {
+        val points = when (type) {
+            PathSegment.Type.Move -> {
+                arrayOf(PointF(pointsData[0], pointsData[1]))
+            }
+
+            PathSegment.Type.Line -> {
+                arrayOf(
+                    PointF(pointsData[0], pointsData[1]),
+                    PointF(pointsData[2], pointsData[3])
+                )
+            }
+
+            PathSegment.Type.Quadratic,
+            PathSegment.Type.Conic -> {
+                arrayOf(
+                    PointF(pointsData[0], pointsData[1]),
+                    PointF(pointsData[2], pointsData[3]),
+                    PointF(pointsData[4], pointsData[5])
+                )
+            }
+
+            PathSegment.Type.Cubic -> {
+                arrayOf(
+                    PointF(pointsData[0], pointsData[1]),
+                    PointF(pointsData[2], pointsData[3]),
+                    PointF(pointsData[4], pointsData[5]),
+                    PointF(pointsData[6], pointsData[7])
+                )
+            }
+            // This should not happen because of the early returns above
+            else -> emptyArray()
+        }
+        return points
+    }
+}
+
+/**
+ * In API level 34, we can use new platform functionality for most of what PathIterator does.
+ * The exceptions are conic conversion (which is handled in the base impl class) and
+ * [calculateSize], which is implemented here.
+ */
+@RequiresApi(34)
+@Suppress("IllegalExperimentalApiUsage")
+@BuildCompat.PrereleaseSdkCheck
+internal class PathIteratorApi34Impl(
+    path: Path,
+    conicEvaluation: ConicEvaluation = ConicEvaluation.AsQuadratics,
+    tolerance: Float = 0.25f
+) : PathIteratorImpl(path, conicEvaluation, tolerance) {
+
+    /**
+     * The platform iterator handles most of what we need for iterating. We hold an instance
+     * of that object in this class.
+     */
+    private val platformIterator: PlatformPathIterator
+
+    init {
+        platformIterator = path.pathIterator
+    }
+
+    /**
+     * The platform does not expose a calculateSize() method, so we implement our own. In the
+     * simplest case, this is done by simply iterating through all segments until done. However, if
+     * the caller requested the true size (including any conic conversion) and if there are any
+     * conics in the path segments, then there is more work to do since we have to convert and count
+     * those segments as well.
+     */
+    override fun calculateSize(includeConvertedConics: Boolean): Int {
+        val convertConics = includeConvertedConics &&
+            conicEvaluation == ConicEvaluation.AsQuadratics
+        var numVerbs = 0
+        val tempIterator = path.pathIterator
+        val tempFloats = FloatArray(8)
+        while (tempIterator.hasNext()) {
+            val type = tempIterator.next(tempFloats, 0)
+            if (type == PlatformPathIterator.VERB_CONIC && convertConics) {
+                with(conicConverter) {
+                    convert(tempFloats, tempFloats[6], tolerance)
+                    numVerbs += quadraticCount
+                }
+            } else {
+                numVerbs++
+            }
+        }
+        return numVerbs
+    }
+
+    /**
+     * [nextImpl] is called by [next] in the base class to do the work of actually getting the
+     * next segment, for which we defer to the platform iterator.
+     */
+    override fun nextImpl(points: FloatArray, offset: Int): PathSegment.Type {
+        return platformToAndroidXSegmentType(platformIterator.next(points, offset))
+    }
+
+    override fun hasNext(): Boolean {
+        return platformIterator.hasNext()
+    }
+
+    override fun peek(): PathSegment.Type {
+        val platformType = platformIterator.peek()
+        return platformToAndroidXSegmentType(platformType)
+    }
+
+    /**
+     * Callers need the AndroidX segment types, so we must convert from the platform types.
+     */
+    private fun platformToAndroidXSegmentType(platformType: Int): PathSegment.Type {
+        return when (platformType) {
+            PlatformPathIterator.VERB_CLOSE -> PathSegment.Type.Close
+            PlatformPathIterator.VERB_CONIC -> PathSegment.Type.Conic
+            PlatformPathIterator.VERB_CUBIC -> PathSegment.Type.Cubic
+            PlatformPathIterator.VERB_DONE -> PathSegment.Type.Done
+            PlatformPathIterator.VERB_LINE -> PathSegment.Type.Line
+            PlatformPathIterator.VERB_MOVE -> PathSegment.Type.Move
+            PlatformPathIterator.VERB_QUAD -> PathSegment.Type.Quadratic
+            else -> {
+                throw IllegalArgumentException("Unknown path segment type $platformType")
+            }
+        }
+    }
+}
+
+/**
+ * Most of the functionality for pre-34 iteration is handled in the native code. The only
+ * exception, similar to the API34 implementation, is the calculateSize(). There is a size()
+ * function in native code which is very quick (it simply tracks the number of verbs in the native
+ * structure). But if the caller wants conic conversion, then we need to iterate through
+ * and convert appropriately, counting as we iterate.
+ */
+@Suppress("IllegalExperimentalApiUsage")
+@BuildCompat.PrereleaseSdkCheck
+internal class PathIteratorPreApi34Impl(
+    path: Path,
+    conicEvaluation: ConicEvaluation = ConicEvaluation.AsQuadratics,
+    tolerance: Float = 0.25f
+) : PathIteratorImpl(path, conicEvaluation, tolerance) {
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun createInternalPathIterator(
+        path: Path,
+        conicEvaluation: Int,
+        tolerance: Float
+    ): Long
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun destroyInternalPathIterator(internalPathIterator: Long)
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalPathIteratorHasNext(internalPathIterator: Long): Boolean
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalPathIteratorNext(
+        internalPathIterator: Long,
+        points: FloatArray,
+        offset: Int
+    ): Int
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalPathIteratorPeek(internalPathIterator: Long): Int
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalPathIteratorRawSize(internalPathIterator: Long): Int
+
+    @Suppress("KotlinJniMissingFunction")
+    private external fun internalPathIteratorSize(internalPathIterator: Long): Int
+    /**
+     * Defines the type of evaluation to apply to conic segments during iteration.
+     */
+
+    private val internalPathIterator =
+        createInternalPathIterator(path, ConicEvaluation.AsConic.ordinal, tolerance)
+
+    /**
+     * Returns the number of verbs present in this iterator's path. If [includeConvertedConics]
+     * property is false and the path has any conic elements, the returned size might be smaller
+     * than the number of calls to [next] required to fully iterate over the path. An accurate
+     * size can be computed by setting the parameter to true instead, at a performance cost.
+     * Including converted conics requires iterating through the entire path, including converting
+     * any conics along the way, to calculate the true size.
+     */
+    override fun calculateSize(includeConvertedConics: Boolean): Int {
+        var numVerbs = 0
+        if (!includeConvertedConics || conicEvaluation == ConicEvaluation.AsConic) {
+            numVerbs = internalPathIteratorSize(internalPathIterator)
+        } else {
+            val tempIterator =
+                createInternalPathIterator(path, ConicEvaluation.AsConic.ordinal, tolerance)
+            val tempFloats = FloatArray(8)
+            while (internalPathIteratorHasNext(tempIterator)) {
+                val segment = internalPathIteratorNext(tempIterator, tempFloats, 0)
+                when (pathSegmentTypes[segment]) {
+                    PathSegment.Type.Conic -> {
+                        conicConverter.convert(tempFloats, tempFloats[7], tolerance)
+                        numVerbs += conicConverter.quadraticCount
+                    }
+                    else -> numVerbs++
+                }
+            }
+        }
+        return numVerbs
+    }
+
+    /**
+     * Returns `true` if the iteration has more elements.
+     */
+    override fun hasNext(): Boolean = internalPathIteratorHasNext(internalPathIterator)
+
+    /**
+     * Returns the type of the current segment in the iteration, or [Done][PathSegment.Type.Done]
+     * if the iteration is finished.
+     */
+    override fun peek() = pathSegmentTypes[internalPathIteratorPeek(internalPathIterator)]
+
+    /**
+     * This is where the actual work happens to get the next segment in the path, which happens
+     * in native code. This function is called by [next] in the base class, which then converts
+     * the resulting segment from conics to quadratics as necessary.
+     */
+    override fun nextImpl(points: FloatArray, offset: Int): PathSegment.Type {
+        return pathSegmentTypes[internalPathIteratorNext(internalPathIterator, points, offset)]
+    }
+
+    protected fun finalize() {
+        destroyInternalPathIterator(internalPathIterator)
+    }
+}
\ No newline at end of file
diff --git a/graphics/graphics-path/src/main/java/androidx/graphics/path/PathSegment.kt b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathSegment.kt
new file mode 100644
index 0000000..863d6d0
--- /dev/null
+++ b/graphics/graphics-path/src/main/java/androidx/graphics/path/PathSegment.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("PathSegmentUtilities")
+package androidx.graphics.path
+
+import android.graphics.PointF
+
+/**
+ * A path segment represents a curve (line, cubic, quadratic or conic) or a command inside
+ * a fully formed [path][android.graphics.Path] object.
+ *
+ * A segment is identified by a [type][PathSegment.Type] which in turns defines how many
+ * [points] are available (from 0 to 3) and whether the [weight] is meaningful. Please refer
+ * to the documentation of each [type][PathSegment.Type] for more information.
+ *
+ * A segment with the [Move][Type.Move] or [Close][Type.Close] is usually represented by
+ * the singletons [DoneSegment] and [CloseSegment] respectively.
+ *
+ * @property type The type that identifies this segment and defines the number of points.
+ * @property points An array of points describing this segment, whose size depends on [type].
+ * @property weight Conic weight, only valid if [type] is [Type.Conic].
+ */
+class PathSegment internal constructor(
+    val type: Type,
+    @get:Suppress("ArrayReturn") val points: Array<PointF>,
+    val weight: Float
+) {
+
+    /**
+     * Type of a given segment in a [path][android.graphics.Path], either a command
+     * ([Type.Move], [Type.Close], [Type.Done]) or a curve ([Type.Line], [Type.Cubic],
+     * [Type.Quadratic], [Type.Conic]).
+     */
+    enum class Type {
+        /**
+         * Move command, the path segment contains 1 point indicating the move destination.
+         * The weight is set 0.0f and not meaningful.
+         */
+        Move,
+        /**
+         * Line curve, the path segment contains 2 points indicating the two extremities of
+         * the line. The weight is set 0.0f and not meaningful.
+         */
+        Line,
+        /**
+         * Quadratic curve, the path segment contains 3 points in the following order:
+         * - Start point
+         * - Control point
+         * - End point
+         *
+         * The weight is set 0.0f and not meaningful.
+         */
+        Quadratic,
+        /**
+         * Conic curve, the path segment contains 3 points in the following order:
+         * - Start point
+         * - Control point
+         * - End point
+         *
+         * The curve is weighted by the [weight][PathSegment.weight] property.
+         */
+        Conic,
+        /**
+         * Cubic curve, the path segment contains 4 points in the following order:
+         * - Start point
+         * - First control point
+         * - Second control point
+         * - End point
+         *
+         * The weight is set 0.0f and not meaningful.
+         */
+        Cubic,
+        /**
+         * Close command, close the current contour by joining the last point added to the
+         * path with the first point of the current contour. The segment does not contain
+         * any point. The weight is set 0.0f and not meaningful.
+         */
+        Close,
+        /**
+         * Done command, which indicates that no further segment will be
+         * found in the path. It typically indicates the end of an iteration over a path
+         * and can be ignored.
+         */
+        Done
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+
+        other as PathSegment
+
+        if (type != other.type) return false
+        if (!points.contentEquals(other.points)) return false
+        if (weight != other.weight) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = type.hashCode()
+        result = 31 * result + points.contentHashCode()
+        result = 31 * result + weight.hashCode()
+        return result
+    }
+
+    override fun toString(): String {
+        return "PathSegment(type=$type, points=${points.contentToString()}, weight=$weight)"
+    }
+}
+
+/**
+ * A [PathSegment] containing the [Done][PathSegment.Type.Done] command.
+ * This static object exists to avoid allocating a new segment when returning a
+ * [Done][PathSegment.Type.Done] result from [PathIterator.next].
+ */
+val DoneSegment = PathSegment(PathSegment.Type.Done, emptyArray(), 0.0f)
+
+/**
+ * A [PathSegment] containing the [Close][PathSegment.Type.Close] command.
+ * This static object exists to avoid allocating a new segment when returning a
+ * [Close][PathSegment.Type.Close] result from [PathIterator.next].
+ */
+val CloseSegment = PathSegment(PathSegment.Type.Close, emptyArray(), 0.0f)
+
+/**
+ * Cache of [PathSegment.Type] values to avoid internal allocation on each use.
+ */
+internal val pathSegmentTypes = PathSegment.Type.values()
\ No newline at end of file
diff --git a/graphics/integration-tests/testapp-compose/lint-baseline.xml b/graphics/integration-tests/testapp-compose/lint-baseline.xml
new file mode 100644
index 0000000..77a40dc
--- /dev/null
+++ b/graphics/integration-tests/testapp-compose/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method MorphComposable has parameter &apos;progress&apos; with type Function0&lt;Float>."
+        errorLine1="    progress: () -> Float,"
+        errorLine2="              ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;clickFn&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    val clickFn: (Int) -> Unit = remember {"
+        errorLine2="                 ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt"/>
+    </issue>
+
+</issues>
diff --git a/graphics/integration-tests/testapp-compose/src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt b/graphics/integration-tests/testapp-compose/src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt
index 0a2f23a..d49c55a 100644
--- a/graphics/integration-tests/testapp-compose/src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt
+++ b/graphics/integration-tests/testapp-compose/src/main/java/androidx/graphics/shapes/testcompose/MainActivity.kt
@@ -69,7 +69,6 @@
 @Composable
 private fun MorphComposable(
     sizedMorph: SizedMorph,
-    @Suppress("PrimitiveInLambda")
     progress: () -> Float,
     modifier: Modifier = Modifier,
     isDebug: Boolean = false
@@ -320,7 +319,6 @@
     }
 
     val scope = rememberCoroutineScope()
-    @Suppress("PrimitiveInLambda")
     val clickFn: (Int) -> Unit = remember {
             { shapeIx ->
             scope.launch {
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index 138be5e..b2e3d40 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -16,9 +16,6 @@
     method public default static int getSdkStatus(android.content.Context context);
     method public default static int getSdkStatus(android.content.Context context, optional String providerPackageName);
     method public suspend Object? insertRecords(java.util.List<? extends androidx.health.connect.client.records.Record> records, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.InsertRecordsResponse>);
-    method @Deprecated public default static boolean isApiSupported();
-    method @Deprecated public default static boolean isProviderAvailable(android.content.Context context);
-    method @Deprecated public default static boolean isProviderAvailable(android.content.Context context, optional String providerPackageName);
     method public suspend <T extends androidx.health.connect.client.records.Record> Object? readRecord(kotlin.reflect.KClass<T> recordType, String recordId, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.ReadRecordResponse<T>>);
     method public suspend <T extends androidx.health.connect.client.records.Record> Object? readRecords(androidx.health.connect.client.request.ReadRecordsRequest<T> request, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.ReadRecordsResponse<T>>);
     method public suspend Object? updateRecords(java.util.List<? extends androidx.health.connect.client.records.Record> records, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -36,9 +33,6 @@
     method public androidx.health.connect.client.HealthConnectClient getOrCreate(android.content.Context context, optional String providerPackageName);
     method public int getSdkStatus(android.content.Context context);
     method public int getSdkStatus(android.content.Context context, optional String providerPackageName);
-    method @Deprecated public boolean isApiSupported();
-    method @Deprecated public boolean isProviderAvailable(android.content.Context context);
-    method @Deprecated public boolean isProviderAvailable(android.content.Context context, optional String providerPackageName);
     property public final String ACTION_HEALTH_CONNECT_SETTINGS;
     field public static final int SDK_AVAILABLE = 3; // 0x3
     field public static final int SDK_UNAVAILABLE = 1; // 0x1
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 4da244d..8aa9f5d 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -16,9 +16,6 @@
     method public default static int getSdkStatus(android.content.Context context);
     method public default static int getSdkStatus(android.content.Context context, optional String providerPackageName);
     method public suspend Object? insertRecords(java.util.List<? extends androidx.health.connect.client.records.Record> records, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.InsertRecordsResponse>);
-    method @Deprecated public default static boolean isApiSupported();
-    method @Deprecated public default static boolean isProviderAvailable(android.content.Context context);
-    method @Deprecated public default static boolean isProviderAvailable(android.content.Context context, optional String providerPackageName);
     method public suspend <T extends androidx.health.connect.client.records.Record> Object? readRecord(kotlin.reflect.KClass<T> recordType, String recordId, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.ReadRecordResponse<T>>);
     method public suspend <T extends androidx.health.connect.client.records.Record> Object? readRecords(androidx.health.connect.client.request.ReadRecordsRequest<T> request, kotlin.coroutines.Continuation<? super androidx.health.connect.client.response.ReadRecordsResponse<T>>);
     method public suspend Object? updateRecords(java.util.List<? extends androidx.health.connect.client.records.Record> records, kotlin.coroutines.Continuation<? super kotlin.Unit>);
@@ -36,9 +33,6 @@
     method public androidx.health.connect.client.HealthConnectClient getOrCreate(android.content.Context context, optional String providerPackageName);
     method public int getSdkStatus(android.content.Context context);
     method public int getSdkStatus(android.content.Context context, optional String providerPackageName);
-    method @Deprecated public boolean isApiSupported();
-    method @Deprecated public boolean isProviderAvailable(android.content.Context context);
-    method @Deprecated public boolean isProviderAvailable(android.content.Context context, optional String providerPackageName);
     property public final String ACTION_HEALTH_CONNECT_SETTINGS;
     field public static final int SDK_AVAILABLE = 3; // 0x3
     field public static final int SDK_UNAVAILABLE = 1; // 0x1
diff --git a/health/connect/connect-client/build.gradle b/health/connect/connect-client/build.gradle
index f3b4530..16260ad 100644
--- a/health/connect/connect-client/build.gradle
+++ b/health/connect/connect-client/build.gradle
@@ -40,6 +40,7 @@
     implementation(libs.guavaAndroid)
     implementation(libs.kotlinCoroutinesAndroid)
     implementation(libs.kotlinCoroutinesGuava)
+    implementation("androidx.core:core-ktx:1.8.0")
 
     testImplementation(libs.testCore)
     testImplementation(libs.testRunner)
@@ -55,6 +56,13 @@
     testImplementation(libs.espressoIntents)
     testImplementation(libs.kotlinReflect)
 
+    androidTestImplementation(libs.testExtJunit)
+    androidTestImplementation(libs.kotlinCoroutinesTest)
+    androidTestImplementation(libs.kotlinReflect)
+    androidTestImplementation(libs.kotlinTest)
+    androidTestImplementation(libs.junit)
+    androidTestImplementation(libs.truth)
+
     samples(project(":health:connect:connect-client-samples"))
 }
 
diff --git a/health/connect/connect-client/lint-baseline.xml b/health/connect/connect-client/lint-baseline.xml
index c3fe024..dfb1ec9 100644
--- a/health/connect/connect-client/lint-baseline.xml
+++ b/health/connect/connect-client/lint-baseline.xml
@@ -11,6 +11,42 @@
     </issue>
 
     <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/health/connect/client/PermissionController.kt"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/health/connect/client/PermissionController.kt"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/health/connect/client/PermissionController.kt"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/health/connect/client/PermissionController.kt"/>
+    </issue>
+
+    <issue
         id="RequireUnstableAidlAnnotation"
         message="Unstable AIDL files must be annotated with `@RequiresOptIn` marker"
         errorLine1="parcelable AggregateDataRequest;"
diff --git a/health/connect/connect-client/src/androidTest/AndroidManifest.xml b/health/connect/connect-client/src/androidTest/AndroidManifest.xml
index 4d68dc2..e235b8d 100644
--- a/health/connect/connect-client/src/androidTest/AndroidManifest.xml
+++ b/health/connect/connect-client/src/androidTest/AndroidManifest.xml
@@ -15,5 +15,107 @@
   limitations under the License.
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <activity android:name=".EmptyActivity"
+            android:label="EmptyActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW_PERMISSION_USAGE"/>
+                <category android:name="android.intent.category.HEALTH_PERMISSIONS"/>
+            </intent-filter>
+        </activity>
+    </application>
 
+    <!-- Read permissions for ACTIVITY. -->
+    <uses-permission android:name="android.permission.health.READ_ACTIVE_CALORIES_BURNED"/>
+    <uses-permission android:name="android.permission.health.READ_DISTANCE"/>
+    <uses-permission android:name="android.permission.health.READ_ELEVATION_GAINED"/>
+    <uses-permission android:name="android.permission.health.READ_EXERCISE"/>
+    <uses-permission android:name="android.permission.health.READ_FLOORS_CLIMBED"/>
+    <uses-permission android:name="android.permission.health.READ_STEPS"/>
+    <uses-permission android:name="android.permission.health.READ_TOTAL_CALORIES_BURNED"/>
+    <uses-permission android:name="android.permission.health.READ_VO2_MAX"/>
+    <uses-permission android:name="android.permission.health.READ_WHEELCHAIR_PUSHES"/>
+    <uses-permission android:name="android.permission.health.READ_POWER"/>
+    <uses-permission android:name="android.permission.health.READ_SPEED"/>
+
+    <!-- Read permissions for BODY_MEASUREMENTS. -->
+    <uses-permission android:name="android.permission.health.READ_BASAL_METABOLIC_RATE"/>
+    <uses-permission android:name="android.permission.health.READ_BODY_FAT"/>
+    <uses-permission android:name="android.permission.health.READ_BODY_WATER_MASS"/>
+    <uses-permission android:name="android.permission.health.READ_BONE_MASS"/>
+    <uses-permission android:name="android.permission.health.READ_HEIGHT"/>
+    <uses-permission android:name="android.permission.health.READ_LEAN_BODY_MASS"/>
+    <uses-permission android:name="android.permission.health.READ_WEIGHT"/>
+
+    <!-- Read permissions for CYCLE_TRACKING. -->
+    <uses-permission android:name="android.permission.health.READ_CERVICAL_MUCUS"/>
+    <uses-permission android:name="android.permission.health.READ_MENSTRUATION"/>
+    <uses-permission android:name="android.permission.health.READ_OVULATION_TEST"/>
+    <uses-permission android:name="android.permission.health.READ_SEXUAL_ACTIVITY"/>
+
+    <!-- Read permissions for NUTRITION. -->
+    <uses-permission android:name="android.permission.health.READ_HYDRATION"/>
+    <uses-permission android:name="android.permission.health.READ_NUTRITION"/>
+
+    <!-- Read permissions for SLEEP. -->
+    <uses-permission android:name="android.permission.health.READ_SLEEP"/>
+
+    <!-- Read permissions for VITALS. -->
+    <uses-permission android:name="android.permission.health.READ_BASAL_BODY_TEMPERATURE"/>
+    <uses-permission android:name="android.permission.health.READ_BLOOD_GLUCOSE"/>
+    <uses-permission android:name="android.permission.health.READ_BLOOD_PRESSURE"/>
+    <uses-permission android:name="android.permission.health.READ_BODY_TEMPERATURE"/>
+    <uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
+    <uses-permission android:name="android.permission.health.READ_HEART_RATE_VARIABILITY"/>
+    <uses-permission android:name="android.permission.health.READ_OXYGEN_SATURATION"/>
+    <uses-permission android:name="android.permission.health.READ_RESPIRATORY_RATE"/>
+    <uses-permission android:name="android.permission.health.READ_RESTING_HEART_RATE"/>
+
+    <!-- Write permissions for ACTIVITY. -->
+    <uses-permission android:name="android.permission.health.WRITE_ACTIVE_CALORIES_BURNED"/>
+    <uses-permission android:name="android.permission.health.WRITE_DISTANCE"/>
+    <uses-permission android:name="android.permission.health.WRITE_ELEVATION_GAINED"/>
+    <uses-permission android:name="android.permission.health.WRITE_EXERCISE"/>
+    <uses-permission android:name="android.permission.health.WRITE_FLOORS_CLIMBED"/>
+    <uses-permission android:name="android.permission.health.WRITE_STEPS"/>
+    <uses-permission android:name="android.permission.health.WRITE_TOTAL_CALORIES_BURNED"/>
+    <uses-permission android:name="android.permission.health.WRITE_VO2_MAX"/>
+    <uses-permission android:name="android.permission.health.WRITE_WHEELCHAIR_PUSHES"/>
+    <uses-permission android:name="android.permission.health.WRITE_POWER"/>
+    <uses-permission android:name="android.permission.health.WRITE_SPEED"/>
+
+    <!-- Write permissions for BODY_MEASUREMENTS. -->
+    <uses-permission android:name="android.permission.health.WRITE_BASAL_METABOLIC_RATE"/>
+    <uses-permission android:name="android.permission.health.WRITE_BODY_FAT"/>
+    <uses-permission android:name="android.permission.health.WRITE_BODY_WATER_MASS"/>
+    <uses-permission android:name="android.permission.health.WRITE_BONE_MASS"/>
+    <uses-permission android:name="android.permission.health.WRITE_HEIGHT"/>
+    <uses-permission android:name="android.permission.health.WRITE_LEAN_BODY_MASS"/>
+    <uses-permission android:name="android.permission.health.WRITE_WEIGHT"/>
+
+    <!-- Write permissions for CYCLE_TRACKING. -->
+    <uses-permission android:name="android.permission.health.WRITE_CERVICAL_MUCUS"/>
+    <uses-permission android:name="android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING"/>
+    <uses-permission android:name="android.permission.health.WRITE_MENSTRUATION"/>
+    <uses-permission android:name="android.permission.health.WRITE_OVULATION_TEST"/>
+    <uses-permission android:name="android.permission.health.WRITE_SEXUAL_ACTIVITY"/>
+
+    <!-- Write permissions for NUTRITION. -->
+    <uses-permission android:name="android.permission.health.WRITE_HYDRATION"/>
+    <uses-permission android:name="android.permission.health.WRITE_NUTRITION"/>
+
+    <!-- Write permissions for SLEEP. -->
+    <uses-permission android:name="android.permission.health.WRITE_SLEEP"/>
+
+    <!-- Write permissions for VITALS. -->
+    <uses-permission android:name="android.permission.health.WRITE_BASAL_BODY_TEMPERATURE"/>
+    <uses-permission android:name="android.permission.health.WRITE_BLOOD_GLUCOSE"/>
+    <uses-permission android:name="android.permission.health.WRITE_BLOOD_PRESSURE"/>
+    <uses-permission android:name="android.permission.health.WRITE_BODY_TEMPERATURE"/>
+    <uses-permission android:name="android.permission.health.WRITE_HEART_RATE"/>
+    <uses-permission android:name="android.permission.health.WRITE_HEART_RATE_VARIABILITY"/>
+    <uses-permission android:name="android.permission.health.WRITE_OXYGEN_SATURATION"/>
+    <uses-permission android:name="android.permission.health.WRITE_RESPIRATORY_RATE"/>
+    <uses-permission android:name="android.permission.health.WRITE_RESTING_HEART_RATE"/>
 </manifest>
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/ClassFinder.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/ClassFinder.kt
new file mode 100644
index 0000000..5539e49
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/ClassFinder.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client
+
+import androidx.health.connect.client.records.Record
+import java.io.File
+import java.net.URL
+import java.util.zip.ZipEntry
+import java.util.zip.ZipInputStream
+import kotlin.reflect.KClass
+
+@Suppress("UNCHECKED_CAST")
+val RECORD_CLASSES: List<KClass<out Record>> by lazy {
+    findClasses("androidx.health.connect.client.records")
+        .filterNot { it.java.isInterface }
+        .filter { it.simpleName.orEmpty().endsWith("Record") }
+        .map { it as KClass<out Record> }
+}
+
+fun findClasses(packageName: String): Set<KClass<*>> {
+    val resources =
+        requireNotNull(Thread.currentThread().contextClassLoader)
+            .getResources(packageName.replace('.', '/'))
+
+    return buildSet {
+        while (resources.hasMoreElements()) {
+            val classNames = findClasses(resources.nextElement().file, packageName)
+            for (className in classNames) {
+                add(Class.forName(className).kotlin)
+            }
+        }
+    }
+}
+
+private fun findClasses(directory: String, packageName: String): Set<String> = buildSet {
+    if (directory.startsWith("file:") && ('!' in directory)) {
+        addAll(unzipClasses(path = directory, packageName = packageName))
+    }
+
+    for (file in File(directory).takeIf(File::exists)?.listFiles() ?: emptyArray()) {
+        if (file.isDirectory) {
+            addAll(findClasses(file.absolutePath, "$packageName.${file.name}"))
+        } else if (file.name.endsWith(".class")) {
+            add("$packageName.${file.name.dropLast(6)}")
+        }
+    }
+}
+
+private fun unzipClasses(path: String, packageName: String): Set<String> =
+    ZipInputStream(URL(path.substringBefore('!')).openStream()).use { zip ->
+        buildSet {
+            while (true) {
+                val entry = zip.nextEntry ?: break
+                val className = entry.formatClassName()
+                if ((className != null) && className.startsWith(packageName)) {
+                    add(className)
+                }
+            }
+        }
+    }
+
+private fun ZipEntry.formatClassName(): String? =
+    name
+        .takeIf { it.endsWith(".class") }
+        ?.replace("[$].*".toRegex(), "")
+        ?.replace("[.]class".toRegex(), "")
+        ?.replace('/', '.')
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/EmptyActivity.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/EmptyActivity.kt
new file mode 100644
index 0000000..8033fc6
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/EmptyActivity.kt
@@ -0,0 +1,22 @@
+/*
+ * 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.health.connect.client.impl
+
+import android.app.Activity
+
+/** Empty activity to serve as a placeholder for permission usage in the test app. */
+class EmptyActivity : Activity()
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImplTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImplTest.kt
new file mode 100644
index 0000000..00f6c95
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImplTest.kt
@@ -0,0 +1,548 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.content.pm.PackageManager
+import android.os.Build
+import androidx.health.connect.client.HealthConnectClient
+import androidx.health.connect.client.changes.DeletionChange
+import androidx.health.connect.client.changes.UpsertionChange
+import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_PREFIX
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.WeightRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import androidx.health.connect.client.records.metadata.Metadata
+import androidx.health.connect.client.request.AggregateGroupByDurationRequest
+import androidx.health.connect.client.request.AggregateGroupByPeriodRequest
+import androidx.health.connect.client.request.AggregateRequest
+import androidx.health.connect.client.request.ChangesTokenRequest
+import androidx.health.connect.client.request.ReadRecordsRequest
+import androidx.health.connect.client.time.TimeRangeFilter
+import androidx.health.connect.client.units.Energy
+import androidx.health.connect.client.units.Mass
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.rule.GrantPermissionRule
+import com.google.common.truth.Truth.assertThat
+import java.time.Duration
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.Period
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.temporal.ChronoUnit
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@MediumTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class HealthConnectClientUpsideDownImplTest {
+
+    private companion object {
+        private const val TOLERANCE = 1.0e-9
+
+        private val START_TIME =
+            LocalDate.now().minusDays(5).atStartOfDay().toInstant(ZoneOffset.UTC)
+        private val ZONE_OFFSET = ZoneOffset.UTC
+        private val ZONE_ID = ZoneId.of(ZONE_OFFSET.id)
+    }
+
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val allHealthPermissions =
+        context.packageManager
+            .getPackageInfo(
+                context.packageName,
+                PackageManager.PackageInfoFlags.of(PackageManager.GET_PERMISSIONS.toLong())
+            )
+            .requestedPermissions
+            .filter { it.startsWith(PERMISSION_PREFIX) }
+            .toTypedArray()
+
+    // Grant every permission as deletion by id checks for every permission
+    @get:Rule
+    val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(*allHealthPermissions)
+
+    private lateinit var healthConnectClient: HealthConnectClient
+
+    @Before
+    fun setUp() {
+        healthConnectClient = HealthConnectClientUpsideDownImpl(context)
+    }
+
+    @After
+    fun tearDown() = runTest {
+        healthConnectClient.deleteRecords(StepsRecord::class, TimeRangeFilter.none())
+        healthConnectClient.deleteRecords(HeartRateRecord::class, TimeRangeFilter.none())
+        healthConnectClient.deleteRecords(NutritionRecord::class, TimeRangeFilter.none())
+    }
+
+    @Test
+    fun insertRecords() = runTest {
+        val response =
+            healthConnectClient.insertRecords(
+                listOf(
+                    StepsRecord(
+                        count = 10,
+                        startTime = START_TIME,
+                        startZoneOffset = null,
+                        endTime = START_TIME + 1.minutes,
+                        endZoneOffset = null
+                    )
+                )
+            )
+        assertThat(response.recordIdsList).hasSize(1)
+    }
+
+    @Test
+    fun deleteRecords_byId() = runTest {
+        val recordIds =
+            healthConnectClient
+                .insertRecords(
+                    listOf(
+                        StepsRecord(
+                            count = 10,
+                            startTime = START_TIME,
+                            startZoneOffset = null,
+                            endTime = START_TIME + 1.minutes,
+                            endZoneOffset = null
+                        ),
+                        StepsRecord(
+                            count = 15,
+                            startTime = START_TIME + 2.minutes,
+                            startZoneOffset = null,
+                            endTime = START_TIME + 3.minutes,
+                            endZoneOffset = null
+                        ),
+                        StepsRecord(
+                            count = 20,
+                            startTime = START_TIME + 4.minutes,
+                            startZoneOffset = null,
+                            endTime = START_TIME + 5.minutes,
+                            endZoneOffset = null,
+                            metadata = Metadata(clientRecordId = "clientId")
+                        ),
+                    )
+                )
+                .recordIdsList
+
+        val initialRecords =
+            healthConnectClient
+                .readRecords(ReadRecordsRequest(StepsRecord::class, TimeRangeFilter.none()))
+                .records
+
+        healthConnectClient.deleteRecords(
+            StepsRecord::class,
+            listOf(recordIds[1]),
+            listOf("clientId")
+        )
+
+        assertThat(
+                healthConnectClient
+                    .readRecords(ReadRecordsRequest(StepsRecord::class, TimeRangeFilter.none()))
+                    .records
+            )
+            .containsExactly(initialRecords[0])
+    }
+
+    @Test
+    fun deleteRecords_byTimeRange() = runTest {
+        healthConnectClient
+            .insertRecords(
+                listOf(
+                    StepsRecord(
+                        count = 100,
+                        startTime = START_TIME,
+                        startZoneOffset = ZoneOffset.UTC,
+                        endTime = START_TIME + 1.minutes,
+                        endZoneOffset = ZoneOffset.UTC
+                    ),
+                    StepsRecord(
+                        count = 150,
+                        startTime = START_TIME + 2.minutes,
+                        startZoneOffset = ZoneOffset.UTC,
+                        endTime = START_TIME + 3.minutes,
+                        endZoneOffset = ZoneOffset.UTC
+                    ),
+                )
+            )
+            .recordIdsList
+
+        val initialRecords =
+            healthConnectClient
+                .readRecords(ReadRecordsRequest(StepsRecord::class, TimeRangeFilter.none()))
+                .records
+
+        healthConnectClient.deleteRecords(
+            StepsRecord::class,
+            TimeRangeFilter.before(START_TIME + 1.minutes + 30.seconds)
+        )
+
+        assertThat(
+                healthConnectClient
+                    .readRecords(ReadRecordsRequest(StepsRecord::class, TimeRangeFilter.none()))
+                    .records
+            )
+            .containsExactly(initialRecords[1])
+    }
+
+    @Test
+    fun updateRecords() = runTest {
+        val id =
+            healthConnectClient
+                .insertRecords(
+                    listOf(
+                        StepsRecord(
+                            count = 10,
+                            startTime = START_TIME,
+                            startZoneOffset = null,
+                            endTime = START_TIME + 30.seconds,
+                            endZoneOffset = null
+                        )
+                    )
+                )
+                .recordIdsList[0]
+
+        val insertedRecord = healthConnectClient.readRecord(StepsRecord::class, id).record
+
+        healthConnectClient.updateRecords(
+            listOf(
+                StepsRecord(
+                    count = 5,
+                    startTime = START_TIME,
+                    startZoneOffset = null,
+                    endTime = START_TIME + 30.seconds,
+                    endZoneOffset = null,
+                    metadata = Metadata(id, insertedRecord.metadata.dataOrigin)
+                )
+            )
+        )
+
+        val updatedRecord = healthConnectClient.readRecord(StepsRecord::class, id).record
+
+        assertThat(updatedRecord.count).isEqualTo(5L)
+    }
+
+    @Test
+    fun readRecord_withId() = runTest {
+        val insertResponse =
+            healthConnectClient.insertRecords(
+                listOf(
+                    StepsRecord(
+                        count = 10,
+                        startTime = START_TIME,
+                        startZoneOffset = ZoneOffset.UTC,
+                        endTime = START_TIME + 1.minutes,
+                        endZoneOffset = ZoneOffset.UTC
+                    )
+                )
+            )
+
+        val readResponse =
+            healthConnectClient.readRecord(StepsRecord::class, insertResponse.recordIdsList[0])
+
+        with(readResponse.record) {
+            assertThat(count).isEqualTo(10)
+            assertThat(startTime).isEqualTo(START_TIME.truncatedTo(ChronoUnit.MILLIS))
+            assertThat(startZoneOffset).isEqualTo(ZoneOffset.UTC)
+            assertThat(endTime).isEqualTo((START_TIME + 1.minutes).truncatedTo(ChronoUnit.MILLIS))
+            assertThat(endZoneOffset).isEqualTo(ZoneOffset.UTC)
+        }
+    }
+
+    @Test
+    fun readRecords_withFilters() = runTest {
+        healthConnectClient.insertRecords(
+            listOf(
+                StepsRecord(
+                    count = 10,
+                    startTime = START_TIME,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 1.minutes,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+                StepsRecord(
+                    count = 5,
+                    startTime = START_TIME + 2.minutes,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 3.minutes,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+            )
+        )
+
+        val readResponse =
+            healthConnectClient.readRecords(
+                ReadRecordsRequest(
+                    StepsRecord::class,
+                    TimeRangeFilter.after(START_TIME + 1.minutes + 30.seconds)
+                )
+            )
+
+        assertThat(readResponse.records[0].count).isEqualTo(5)
+    }
+
+    @Test
+    fun aggregateRecords() = runTest {
+        healthConnectClient.insertRecords(
+            listOf(
+                StepsRecord(
+                    count = 10,
+                    startTime = START_TIME,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 30.seconds,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+                StepsRecord(
+                    count = 5,
+                    startTime = START_TIME + 1.minutes,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 1.minutes + 30.seconds,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+                HeartRateRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 30.seconds,
+                    endZoneOffset = ZoneOffset.UTC,
+                    samples =
+                        listOf(
+                            HeartRateRecord.Sample(START_TIME, 57L),
+                            HeartRateRecord.Sample(START_TIME + 15.seconds, 120L)
+                        )
+                ),
+                HeartRateRecord(
+                    startTime = START_TIME + 1.minutes,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 1.minutes + 30.seconds,
+                    endZoneOffset = ZoneOffset.UTC,
+                    samples =
+                        listOf(
+                            HeartRateRecord.Sample(START_TIME + 1.minutes, 47L),
+                            HeartRateRecord.Sample(START_TIME + 1.minutes + 15.seconds, 48L)
+                        )
+                ),
+                NutritionRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 1.minutes,
+                    endZoneOffset = ZoneOffset.UTC,
+                    energy = Energy.kilocalories(200.0)
+                ),
+                WeightRecord(
+                    time = START_TIME,
+                    zoneOffset = ZoneOffset.UTC,
+                    weight = Mass.kilograms(100.0)
+                ),
+            )
+        )
+
+        val aggregateResponse =
+            healthConnectClient.aggregate(
+                AggregateRequest(
+                    setOf(
+                        StepsRecord.COUNT_TOTAL,
+                        HeartRateRecord.BPM_MIN,
+                        HeartRateRecord.BPM_MAX,
+                        NutritionRecord.ENERGY_TOTAL,
+                        NutritionRecord.CAFFEINE_TOTAL,
+                        WeightRecord.WEIGHT_MAX,
+                        WheelchairPushesRecord.COUNT_TOTAL,
+                    ),
+                    TimeRangeFilter.none()
+                )
+            )
+
+        with(aggregateResponse) {
+            assertThat(this[StepsRecord.COUNT_TOTAL]).isEqualTo(15L)
+            assertThat(this[HeartRateRecord.BPM_MIN]).isEqualTo(47L)
+            assertThat(this[HeartRateRecord.BPM_MAX]).isEqualTo(120L)
+            assertThat(this[NutritionRecord.ENERGY_TOTAL]).isEqualTo(Energy.kilocalories(200.0))
+            assertThat(this[NutritionRecord.CAFFEINE_TOTAL]!!.inGrams).isWithin(TOLERANCE).of(0.0)
+            assertThat(this[WeightRecord.WEIGHT_MAX]).isEqualTo(Mass.kilograms(100.0))
+
+            assertThat(contains(WheelchairPushesRecord.COUNT_TOTAL)).isFalse()
+        }
+    }
+
+    @Test
+    fun aggregateRecordsGroupByDuration() = runTest {
+        healthConnectClient.insertRecords(
+            listOf(
+                StepsRecord(
+                    count = 1,
+                    startTime = START_TIME,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 10.seconds,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+                StepsRecord(
+                    count = 2,
+                    startTime = START_TIME + 15.seconds,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 25.seconds,
+                    endZoneOffset = ZoneOffset.UTC
+                ),
+                StepsRecord(
+                    count = 5,
+                    startTime = START_TIME + 40.seconds,
+                    startZoneOffset = ZoneOffset.UTC,
+                    endTime = START_TIME + 1.minutes,
+                    endZoneOffset = ZoneOffset.UTC
+                )
+            )
+        )
+
+        val aggregateResponse =
+            healthConnectClient.aggregateGroupByDuration(
+                AggregateGroupByDurationRequest(
+                    setOf(StepsRecord.COUNT_TOTAL),
+                    TimeRangeFilter.between(START_TIME, START_TIME + 1.minutes),
+                    Duration.ofSeconds(30),
+                    setOf()
+                )
+            )
+
+        with(aggregateResponse) {
+            assertThat(this).hasSize(2)
+            assertThat(this[0].result[StepsRecord.COUNT_TOTAL]).isEqualTo(3)
+            assertThat(this[1].result[StepsRecord.COUNT_TOTAL]).isEqualTo(5)
+        }
+    }
+
+    @Test
+    fun aggregateRecordsGroupByPeriod() = runTest {
+        healthConnectClient.insertRecords(
+            listOf(
+                StepsRecord(
+                    count = 100,
+                    startTime = START_TIME,
+                    startZoneOffset = ZONE_OFFSET,
+                    endTime = START_TIME + 5.minutes,
+                    endZoneOffset = ZONE_OFFSET
+                ),
+                StepsRecord(
+                    count = 200,
+                    startTime = START_TIME + 10.minutes,
+                    startZoneOffset = ZONE_OFFSET,
+                    endTime = START_TIME + 30.minutes,
+                    endZoneOffset = ZONE_OFFSET
+                ),
+                StepsRecord(
+                    count = 50,
+                    startTime = START_TIME + 1.days,
+                    startZoneOffset = ZONE_OFFSET,
+                    endTime = START_TIME + 1.days + 10.minutes,
+                    endZoneOffset = ZONE_OFFSET
+                )
+            )
+        )
+
+        val aggregateResponse =
+            healthConnectClient.aggregateGroupByPeriod(
+                AggregateGroupByPeriodRequest(
+                    setOf(StepsRecord.COUNT_TOTAL),
+                    TimeRangeFilter.between(
+                        LocalDateTime.ofInstant(START_TIME, ZONE_ID),
+                        LocalDateTime.ofInstant(START_TIME + 2.days, ZONE_ID),
+                    ),
+                    timeRangeSlicer = Period.ofDays(1)
+                )
+            )
+
+        with(aggregateResponse) {
+            assertThat(this).hasSize(2)
+            assertThat(this[0].result[StepsRecord.COUNT_TOTAL]).isEqualTo(300)
+            assertThat(this[1].result[StepsRecord.COUNT_TOTAL]).isEqualTo(50)
+        }
+    }
+
+    @Test
+    fun getChangesToken() = runTest {
+        val token =
+            healthConnectClient.getChangesToken(
+                ChangesTokenRequest(setOf(StepsRecord::class), setOf())
+            )
+        assertThat(token).isNotEmpty()
+    }
+
+    @Test
+    fun getChanges() = runTest {
+        var token =
+            healthConnectClient.getChangesToken(
+                ChangesTokenRequest(setOf(StepsRecord::class), setOf())
+            )
+
+        val insertedRecordId =
+            healthConnectClient
+                .insertRecords(
+                    listOf(
+                        StepsRecord(
+                            count = 10,
+                            startTime = START_TIME,
+                            startZoneOffset = ZoneOffset.UTC,
+                            endTime = START_TIME + 5.minutes,
+                            endZoneOffset = ZoneOffset.UTC
+                        )
+                    )
+                )
+                .recordIdsList[0]
+
+        val record = healthConnectClient.readRecord(StepsRecord::class, insertedRecordId).record
+
+        assertThat(healthConnectClient.getChanges(token).changes)
+            .containsExactly(UpsertionChange(record))
+
+        token =
+            healthConnectClient.getChangesToken(
+                ChangesTokenRequest(setOf(StepsRecord::class), setOf())
+            )
+
+        healthConnectClient.deleteRecords(StepsRecord::class, listOf(insertedRecordId), emptyList())
+
+        assertThat(healthConnectClient.getChanges(token).changes)
+            .containsExactly(DeletionChange(insertedRecordId))
+    }
+
+    @Test
+    fun getGrantedPermissions() = runTest {
+        assertThat(healthConnectClient.permissionController.getGrantedPermissions())
+            .containsExactlyElementsIn(allHealthPermissions)
+    }
+
+    private val Int.seconds: Duration
+        get() = Duration.ofSeconds(this.toLong())
+
+    private val Int.minutes: Duration
+        get() = Duration.ofMinutes(this.toLong())
+
+    private val Int.days: Duration
+        get() = Duration.ofDays(this.toLong())
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/PermissionControllerUpsideDownTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/PermissionControllerUpsideDownTest.kt
new file mode 100644
index 0000000..e364fd6
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/PermissionControllerUpsideDownTest.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl
+
+import android.annotation.TargetApi
+import android.health.connect.HealthPermissions
+import android.os.Build
+import androidx.health.connect.client.PermissionController
+import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_PREFIX
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.rule.GrantPermissionRule
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@MediumTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class PermissionControllerUpsideDownTest {
+
+    @get:Rule
+    val grantPermissionRule: GrantPermissionRule =
+        GrantPermissionRule.grant(HealthPermissions.WRITE_STEPS, HealthPermissions.READ_DISTANCE)
+
+    @Test
+    fun getGrantedPermissions() = runTest {
+        val permissionController: PermissionController =
+            HealthConnectClientUpsideDownImpl(ApplicationProvider.getApplicationContext())
+        // Permissions may have been granted by the other instrumented test in this directory.
+        // Since there is no way to revoke permissions with grantPermissionRule, use containsAtLeast
+        // instead of containsExactly.
+        assertThat(permissionController.getGrantedPermissions())
+            .containsAtLeast(HealthPermissions.WRITE_STEPS, HealthPermissions.READ_DISTANCE)
+    }
+
+    @Test
+    fun revokeAllPermissions_revokesHealthPermissions() = runTest {
+        val revokedPermissions: MutableList<String> = mutableListOf()
+        val permissionController: PermissionController =
+            HealthConnectClientUpsideDownImpl(ApplicationProvider.getApplicationContext()) {
+                permissionsToRevoke ->
+                revokedPermissions.addAll(permissionsToRevoke)
+            }
+        permissionController.revokeAllPermissions()
+        assertThat(revokedPermissions.all { it.startsWith(PERMISSION_PREFIX) }).isTrue()
+    }
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/RequestExerciseRouteUpsideDownCakeTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/RequestExerciseRouteUpsideDownCakeTest.kt
new file mode 100644
index 0000000..ea4548d
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/RequestExerciseRouteUpsideDownCakeTest.kt
@@ -0,0 +1,125 @@
+/*
+ * 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.health.connect.client.impl
+
+import android.annotation.TargetApi
+import android.content.Context
+import android.content.Intent
+import android.health.connect.HealthConnectManager
+import android.os.Build
+import androidx.health.connect.client.impl.platform.records.PlatformExerciseRoute
+import androidx.health.connect.client.impl.platform.records.PlatformExerciseRouteLocationBuilder
+import androidx.health.connect.client.impl.platform.records.PlatformLength
+import androidx.health.connect.client.permission.platform.RequestExerciseRouteUpsideDownCake
+import androidx.health.connect.client.records.ExerciseRoute
+import androidx.health.connect.client.units.Length
+import androidx.test.core.app.ApplicationProvider
+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 java.time.Instant
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@MediumTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class RequestExerciseRouteUpsideDownCakeTest {
+
+    private lateinit var context: Context
+
+    @Before
+    fun setUp() {
+        context = ApplicationProvider.getApplicationContext()
+    }
+
+    @Test
+    fun createIntentTest() {
+        val requestRouteContract = RequestExerciseRouteUpsideDownCake()
+        val intent = requestRouteContract.createIntent(context, "someUid")
+        assertThat(intent.action).isEqualTo("android.health.connect.action.REQUEST_EXERCISE_ROUTE")
+        assertThat(intent.getStringExtra("android.health.connect.extra.SESSION_ID"))
+            .isEqualTo("someUid")
+    }
+
+    @Test
+    fun parseIntent_null() {
+        val requestRouteContract = RequestExerciseRouteUpsideDownCake()
+        val result = requestRouteContract.parseResult(0, null)
+        assertThat(result).isNull()
+    }
+
+    @Test
+    fun parseIntent_emptyIntent() {
+        val requestRouteContract = RequestExerciseRouteUpsideDownCake()
+        val result = requestRouteContract.parseResult(0, Intent())
+        assertThat(result).isNull()
+    }
+
+    @Test
+    fun parseIntent_emptyRoute() {
+        val requestRouteContract = RequestExerciseRouteUpsideDownCake()
+        val intent = Intent()
+        intent.putExtra(HealthConnectManager.EXTRA_EXERCISE_ROUTE, PlatformExerciseRoute(listOf()))
+        val result = requestRouteContract.parseResult(0, intent)
+        assertThat(result).isEqualTo(ExerciseRoute(listOf()))
+    }
+
+    @Test
+    fun parseIntent() {
+        val requestRouteContract = RequestExerciseRouteUpsideDownCake()
+        val intent = Intent()
+        val location1 =
+            PlatformExerciseRouteLocationBuilder(Instant.ofEpochMilli(1234L), 23.4, -23.4)
+                .setAltitude(PlatformLength.fromMeters(12.3))
+                .setHorizontalAccuracy(PlatformLength.fromMeters(0.9))
+                .setVerticalAccuracy(PlatformLength.fromMeters(0.3))
+                .build()
+        val location2 =
+            PlatformExerciseRouteLocationBuilder(Instant.ofEpochMilli(3456L), 23.45, -23.45).build()
+
+        intent.putExtra(
+            HealthConnectManager.EXTRA_EXERCISE_ROUTE,
+            PlatformExerciseRoute(listOf(location1, location2))
+        )
+        val result = requestRouteContract.parseResult(0, intent)
+        assertThat(result)
+            .isEqualTo(
+                ExerciseRoute(
+                    listOf(
+                        ExerciseRoute.Location(
+                            time = Instant.ofEpochMilli(1234L),
+                            latitude = 23.4,
+                            longitude = -23.4,
+                            horizontalAccuracy = Length.meters(0.9),
+                            verticalAccuracy = Length.meters(0.3),
+                            altitude = Length.meters(12.3)
+                        ),
+                        ExerciseRoute.Location(
+                            time = Instant.ofEpochMilli(3456L),
+                            latitude = 23.45,
+                            longitude = -23.45,
+                        )
+                    )
+                )
+            )
+    }
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/MetadataConvertersTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/MetadataConvertersTest.kt
new file mode 100644
index 0000000..af0b765
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/MetadataConvertersTest.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.annotation.TargetApi
+import android.os.Build
+import androidx.health.connect.client.records.metadata.DataOrigin
+import androidx.health.connect.client.records.metadata.Device
+import androidx.health.connect.client.records.metadata.Metadata
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.time.Instant
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@SmallTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class MetadataConvertersTest {
+
+    fun metadata_convertToPlatform() {
+        val metadata =
+            Metadata(
+                id = "someId",
+                dataOrigin = DataOrigin("origin package name"),
+                lastModifiedTime = Instant.ofEpochMilli(6666L),
+                clientRecordId = "clientId",
+                clientRecordVersion = 2L,
+                recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED,
+                device =
+                    Device(
+                        manufacturer = "Awesome-watches",
+                        model = "AwesomeOne",
+                        type = Device.TYPE_WATCH
+                    )
+            )
+
+        with(metadata.toPlatformMetadata()) {
+            assertThat(id).isEqualTo("someId")
+            assertThat(dataOrigin)
+                .isEqualTo(
+                    PlatformDataOriginBuilder().setPackageName("origin package name").build()
+                )
+            assertThat(clientRecordId).isEqualTo("clientId")
+            assertThat(clientRecordVersion).isEqualTo(2L)
+            assertThat(recordingMethod)
+                .isEqualTo(PlatformMetadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED)
+            assertThat(device)
+                .isEqualTo(
+                    PlatformDeviceBuilder()
+                        .setManufacturer("Awesome-watches")
+                        .setModel("AwesomeOne")
+                        .setType(PlatformDevice.DEVICE_TYPE_WATCH)
+                        .build()
+                )
+        }
+    }
+
+    @Test
+    fun metadata_convertToPlatform_noDevice() {
+        val metadata =
+            Metadata(
+                id = "someId",
+                dataOrigin = DataOrigin("origin package name"),
+                lastModifiedTime = Instant.ofEpochMilli(6666L),
+                clientRecordId = "clientId",
+                clientRecordVersion = 2L
+            )
+
+        with(metadata.toPlatformMetadata()) {
+            assertThat(id).isEqualTo("someId")
+            assertThat(dataOrigin)
+                .isEqualTo(
+                    PlatformDataOriginBuilder().setPackageName("origin package name").build()
+                )
+            assertThat(clientRecordId).isEqualTo("clientId")
+            assertThat(clientRecordVersion).isEqualTo(2L)
+            assertThat(device).isEqualTo(PlatformDeviceBuilder().build())
+        }
+    }
+
+    @Test
+    fun metadata_convertToSdk() {
+        val metadata =
+            PlatformMetadataBuilder()
+                .apply {
+                    setId("someId")
+                    setDataOrigin(
+                        PlatformDataOriginBuilder().setPackageName("origin package name").build()
+                    )
+                    setLastModifiedTime(Instant.ofEpochMilli(6666L))
+                    setClientRecordId("clientId")
+                    setClientRecordVersion(2L)
+                    setRecordingMethod(PlatformMetadata.RECORDING_METHOD_MANUAL_ENTRY)
+                    setDevice(
+                        PlatformDeviceBuilder()
+                            .setManufacturer("AwesomeTech")
+                            .setModel("AwesomeTwo")
+                            .setType(PlatformDevice.DEVICE_TYPE_WATCH)
+                            .build()
+                    )
+                }
+                .build()
+
+        with(metadata.toSdkMetadata()) {
+            assertThat(id).isEqualTo("someId")
+            assertThat(dataOrigin).isEqualTo(DataOrigin("origin package name"))
+            assertThat(lastModifiedTime).isEqualTo(Instant.ofEpochMilli(6666L))
+            assertThat(clientRecordId).isEqualTo("clientId")
+            assertThat(clientRecordVersion).isEqualTo(2L)
+            assertThat(recordingMethod).isEqualTo(Metadata.RECORDING_METHOD_MANUAL_ENTRY)
+            assertThat(device)
+                .isEqualTo(
+                    Device(
+                        manufacturer = "AwesomeTech",
+                        model = "AwesomeTwo",
+                        type = Device.TYPE_WATCH
+                    )
+                )
+        }
+    }
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RecordConvertersTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RecordConvertersTest.kt
new file mode 100644
index 0000000..892ed70
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RecordConvertersTest.kt
@@ -0,0 +1,1750 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.annotation.TargetApi
+import android.os.Build
+import androidx.health.connect.client.RECORD_CLASSES
+import androidx.health.connect.client.records.ActiveCaloriesBurnedRecord
+import androidx.health.connect.client.records.BasalBodyTemperatureRecord
+import androidx.health.connect.client.records.BasalMetabolicRateRecord
+import androidx.health.connect.client.records.BloodGlucoseRecord
+import androidx.health.connect.client.records.BloodPressureRecord
+import androidx.health.connect.client.records.BodyFatRecord
+import androidx.health.connect.client.records.BodyTemperatureMeasurementLocation
+import androidx.health.connect.client.records.BodyTemperatureRecord
+import androidx.health.connect.client.records.BodyWaterMassRecord
+import androidx.health.connect.client.records.BoneMassRecord
+import androidx.health.connect.client.records.CervicalMucusRecord
+import androidx.health.connect.client.records.CyclingPedalingCadenceRecord
+import androidx.health.connect.client.records.DistanceRecord
+import androidx.health.connect.client.records.ElevationGainedRecord
+import androidx.health.connect.client.records.ExerciseLap
+import androidx.health.connect.client.records.ExerciseRoute
+import androidx.health.connect.client.records.ExerciseSegment
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.FloorsClimbedRecord
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.HeartRateVariabilityRmssdRecord
+import androidx.health.connect.client.records.HeightRecord
+import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.InstantaneousRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
+import androidx.health.connect.client.records.IntervalRecord
+import androidx.health.connect.client.records.LeanBodyMassRecord
+import androidx.health.connect.client.records.MealType
+import androidx.health.connect.client.records.MenstruationFlowRecord
+import androidx.health.connect.client.records.MenstruationPeriodRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.OvulationTestRecord
+import androidx.health.connect.client.records.OxygenSaturationRecord
+import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.RespiratoryRateRecord
+import androidx.health.connect.client.records.RestingHeartRateRecord
+import androidx.health.connect.client.records.SexualActivityRecord
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.SpeedRecord
+import androidx.health.connect.client.records.StepsCadenceRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.TotalCaloriesBurnedRecord
+import androidx.health.connect.client.records.Vo2MaxRecord
+import androidx.health.connect.client.records.WeightRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import androidx.health.connect.client.records.metadata.DataOrigin
+import androidx.health.connect.client.records.metadata.Metadata
+import androidx.health.connect.client.units.BloodGlucose
+import androidx.health.connect.client.units.Energy
+import androidx.health.connect.client.units.Length
+import androidx.health.connect.client.units.Mass
+import androidx.health.connect.client.units.Percentage
+import androidx.health.connect.client.units.Power
+import androidx.health.connect.client.units.Pressure
+import androidx.health.connect.client.units.Temperature
+import androidx.health.connect.client.units.Velocity
+import androidx.health.connect.client.units.Volume
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Correspondence
+import com.google.common.truth.Truth.assertThat
+import java.time.Instant
+import java.time.ZoneOffset
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@SmallTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class RecordConvertersTest {
+
+    private val tolerance = 1.0e-9
+
+    @Test
+    fun toPlatformRecordClass_supportsAllRecordTypes() {
+        RECORD_CLASSES.forEach { assertThat(it.toPlatformRecordClass()).isNotNull() }
+    }
+
+    @Test
+    fun stepsRecordClass_convertToPlatform() {
+        val stepsSdkClass = StepsRecord::class
+        val stepsPlatformClass = PlatformStepsRecord::class.java
+        assertThat(stepsSdkClass.toPlatformRecordClass()).isEqualTo(stepsPlatformClass)
+    }
+
+    @Test
+    fun activeCaloriesBurnedRecord_convertToPlatform() {
+        val platformActiveCaloriesBurned =
+            ActiveCaloriesBurnedRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    energy = Energy.calories(200.0),
+                )
+                .toPlatformRecord() as PlatformActiveCaloriesBurnedRecord
+
+        assertPlatformRecord(platformActiveCaloriesBurned) {
+            assertThat(energy).isEqualTo(PlatformEnergy.fromCalories(200.0))
+        }
+    }
+
+    @Test
+    fun basalBodyTemperatureRecord_convertToPlatform() {
+        val platformBasalBodyTemperature =
+            BasalBodyTemperatureRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    temperature = Temperature.celsius(37.0),
+                    measurementLocation =
+                        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FINGER
+                )
+                .toPlatformRecord() as PlatformBasalBodyTemperatureRecord
+
+        assertPlatformRecord(platformBasalBodyTemperature) {
+            assertThat(temperature).isEqualTo(PlatformTemperature.fromCelsius(37.0))
+            assertThat(measurementLocation)
+                .isEqualTo(PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FINGER)
+        }
+    }
+
+    @Test
+    fun basalMetabolicRateRecord_convertToPlatform() {
+        val platformBasalMetabolicRate =
+            BasalMetabolicRateRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    basalMetabolicRate = Power.watts(300.0),
+                )
+                .toPlatformRecord() as PlatformBasalMetabolicRateRecord
+
+        assertPlatformRecord(platformBasalMetabolicRate) {
+            assertThat(basalMetabolicRate).isEqualTo(PlatformPower.fromWatts(300.0))
+        }
+    }
+
+    @Test
+    fun bloodGlucoseRecord_convertToPlatform() {
+        val platformBloodGlucose =
+            BloodGlucoseRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    level = BloodGlucose.millimolesPerLiter(34.0),
+                    specimenSource = BloodGlucoseRecord.SPECIMEN_SOURCE_TEARS,
+                    mealType = MealType.MEAL_TYPE_BREAKFAST,
+                    relationToMeal = BloodGlucoseRecord.RELATION_TO_MEAL_AFTER_MEAL,
+                )
+                .toPlatformRecord() as PlatformBloodGlucoseRecord
+
+        assertPlatformRecord(platformBloodGlucose) {
+            assertThat(level).isEqualTo(PlatformBloodGlucose.fromMillimolesPerLiter(34.0))
+            assertThat(specimenSource)
+                .isEqualTo(PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_TEARS)
+            assertThat(mealType).isEqualTo(PlatformMealType.MEAL_TYPE_BREAKFAST)
+            assertThat(relationToMeal)
+                .isEqualTo(PlatformBloodGlucoseRelationToMealType.RELATION_TO_MEAL_AFTER_MEAL)
+        }
+    }
+
+    @Test
+    fun bloodPressureRecord_convertToPlatform() {
+        val platformBloodPressure =
+            BloodPressureRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    systolic = Pressure.millimetersOfMercury(23.0),
+                    diastolic = Pressure.millimetersOfMercury(24.0),
+                    bodyPosition = BloodPressureRecord.BODY_POSITION_STANDING_UP,
+                    measurementLocation = BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST,
+                )
+                .toPlatformRecord() as PlatformBloodPressureRecord
+
+        assertPlatformRecord(platformBloodPressure) {
+            assertThat(systolic).isEqualTo(PlatformPressure.fromMillimetersOfMercury(23.0))
+            assertThat(diastolic).isEqualTo(PlatformPressure.fromMillimetersOfMercury(24.0))
+            assertThat(bodyPosition)
+                .isEqualTo(PlatformBloodPressureBodyPosition.BODY_POSITION_STANDING_UP)
+            assertThat(measurementLocation)
+                .isEqualTo(
+                    PlatformBloodPressureMeasurementLocation
+                        .BLOOD_PRESSURE_MEASUREMENT_LOCATION_LEFT_WRIST
+                )
+        }
+    }
+
+    @Test
+    fun bodyFatRecord_convertToPlatform() {
+        val platformBodyFat =
+            BodyFatRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    percentage = Percentage(99.0),
+                )
+                .toPlatformRecord() as PlatformBodyFatRecord
+
+        assertPlatformRecord(platformBodyFat) {
+            assertThat(percentage).isEqualTo(PlatformPercentage.fromValue(99.0))
+        }
+    }
+
+    @Test
+    fun bodyTemperatureRecord_convertToPlatform() {
+        val platformBodyTemperature =
+            BodyTemperatureRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    temperature = Temperature.celsius(30.0),
+                    measurementLocation =
+                        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_ARMPIT,
+                )
+                .toPlatformRecord() as PlatformBodyTemperatureRecord
+
+        assertPlatformRecord(platformBodyTemperature) {
+            PlatformTemperature.fromCelsius(30.0)
+            assertThat(measurementLocation)
+                .isEqualTo(PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_ARMPIT)
+        }
+    }
+
+    @Test
+    fun bodyWaterMassRecord_convertToPlatform() {
+        val platformBodyWaterMass =
+            BodyWaterMassRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    mass = Mass.grams(40.0),
+                )
+                .toPlatformRecord() as PlatformBodyWaterMassRecord
+
+        assertPlatformRecord(platformBodyWaterMass) {
+            assertThat(bodyWaterMass).isEqualTo(PlatformMass.fromGrams(40.0))
+        }
+    }
+
+    @Test
+    fun boneMassRecord_convertToPlatform() {
+        val platformBoneMass =
+            BoneMassRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    mass = Mass.grams(5.0),
+                )
+                .toPlatformRecord() as PlatformBoneMassRecord
+
+        assertPlatformRecord(platformBoneMass) {
+            assertThat(mass).isEqualTo(PlatformMass.fromGrams(5.0))
+        }
+    }
+
+    @Test
+    fun cervicalMucusRecord_convertToPlatform() {
+        val platformCervicalMucus =
+            CervicalMucusRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    appearance = CervicalMucusRecord.APPEARANCE_CREAMY,
+                    sensation = CervicalMucusRecord.SENSATION_LIGHT,
+                )
+                .toPlatformRecord() as PlatformCervicalMucusRecord
+
+        assertPlatformRecord(platformCervicalMucus) {
+            assertThat(appearance).isEqualTo(PlatformCervicalMucusAppearance.APPEARANCE_CREAMY)
+            assertThat(sensation).isEqualTo(PlatformCervicalMucusSensation.SENSATION_LIGHT)
+        }
+    }
+
+    @Test
+    fun cyclingPedalingCadenceRecord_convertToPlatform() {
+        val platformCyclingPedalingCadence =
+            CyclingPedalingCadenceRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    samples =
+                        listOf(
+                            CyclingPedalingCadenceRecord.Sample(START_TIME, 3.0),
+                            CyclingPedalingCadenceRecord.Sample(END_TIME, 9.0)
+                        ),
+                )
+                .toPlatformRecord() as PlatformCyclingPedalingCadenceRecord
+
+        assertPlatformRecord(platformCyclingPedalingCadence) {
+            assertThat(samples)
+                .comparingElementsUsing(
+                    Correspondence.from<
+                        PlatformCyclingPedalingCadenceSample, PlatformCyclingPedalingCadenceSample
+                    >(
+                        { actual, expected ->
+                            actual!!.revolutionsPerMinute == expected!!.revolutionsPerMinute &&
+                                actual.time == expected.time
+                        },
+                        "has same RPM and same time as"
+                    )
+                )
+                .containsExactly(
+                    PlatformCyclingPedalingCadenceSample(3.0, START_TIME),
+                    PlatformCyclingPedalingCadenceSample(9.0, END_TIME)
+                )
+        }
+    }
+
+    @Test
+    fun distanceRecord_convertToPlatform() {
+        val platformDistance =
+            DistanceRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    distance = Length.meters(50.0),
+                )
+                .toPlatformRecord() as PlatformDistanceRecord
+
+        assertPlatformRecord(platformDistance) {
+            assertThat(distance).isEqualTo(PlatformLength.fromMeters(50.0))
+        }
+    }
+
+    @Test
+    fun elevationGainedRecord_convertToPlatform() {
+        val platformElevationGained =
+            ElevationGainedRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    elevation = Length.meters(10.0),
+                )
+                .toPlatformRecord() as PlatformElevationGainedRecord
+
+        assertPlatformRecord(platformElevationGained) {
+            assertThat(elevation).isEqualTo(PlatformLength.fromMeters(10.0))
+        }
+    }
+
+    @Test
+    fun exerciseSessionRecord_convertToPlatform() {
+        val platformExerciseSession =
+            ExerciseSessionRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    exerciseType =
+                        ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+                    title = "HIIT training",
+                    notes = "Hard workout",
+                    laps =
+                        listOf(
+                            ExerciseLap(
+                                START_TIME.plusMillis(6),
+                                START_TIME.plusMillis(10),
+                                Length.meters(1.0)
+                            ),
+                            ExerciseLap(
+                                START_TIME.plusMillis(11),
+                                START_TIME.plusMillis(15),
+                                Length.meters(1.5)
+                            )
+                        ),
+                    segments =
+                        listOf(
+                            ExerciseSegment(
+                                START_TIME.plusMillis(1),
+                                START_TIME.plusMillis(10),
+                                ExerciseSegment.EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
+                                10
+                            )
+                        ),
+                    route =
+                        ExerciseRoute(
+                            listOf(
+                                ExerciseRoute.Location(
+                                    START_TIME,
+                                    latitude = 23.5,
+                                    longitude = -23.6,
+                                    altitude = Length.meters(20.0),
+                                    horizontalAccuracy = Length.meters(2.0),
+                                    verticalAccuracy = Length.meters(3.0)
+                                )
+                            )
+                        )
+                )
+                .toPlatformRecord() as PlatformExerciseSessionRecord
+
+        assertPlatformRecord(platformExerciseSession) {
+            assertThat(title).isEqualTo("HIIT training")
+            assertThat(notes).isEqualTo("Hard workout")
+            assertThat(exerciseType)
+                .isEqualTo(
+                    PlatformExerciseSessionType
+                        .EXERCISE_SESSION_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
+                )
+            assertThat(laps)
+                .containsExactly(
+                    PlatformExerciseLapBuilder(START_TIME.plusMillis(6), START_TIME.plusMillis(10))
+                        .setLength(PlatformLength.fromMeters(1.0))
+                        .build(),
+                    PlatformExerciseLapBuilder(START_TIME.plusMillis(11), START_TIME.plusMillis(15))
+                        .setLength(PlatformLength.fromMeters(1.5))
+                        .build()
+                )
+            assertThat(segments)
+                .containsExactly(
+                    PlatformExerciseSegmentBuilder(
+                            START_TIME.plusMillis(1),
+                            START_TIME.plusMillis(10),
+                            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS
+                        )
+                        .setRepetitionsCount(10)
+                        .build()
+                )
+            assertThat(route)
+                .isEqualTo(
+                    PlatformExerciseRoute(
+                        listOf(
+                            PlatformExerciseRouteLocationBuilder(START_TIME, 23.5, -23.6)
+                                .setAltitude(PlatformLength.fromMeters(20.0))
+                                .setHorizontalAccuracy(PlatformLength.fromMeters(2.0))
+                                .setVerticalAccuracy(PlatformLength.fromMeters(3.0))
+                                .build()
+                        )
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun floorsClimbedRecord_convertToPlatform() {
+        val platformFloorsClimbed =
+            FloorsClimbedRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    floors = 3.9,
+                )
+                .toPlatformRecord() as PlatformFloorsClimbedRecord
+
+        assertPlatformRecord(platformFloorsClimbed) { assertThat(floors).isEqualTo(3.9) }
+    }
+
+    @Test
+    fun heartRateRecord_convertToPlatform() {
+        val heartRate =
+            HeartRateRecord(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                metadata = METADATA,
+                samples =
+                    listOf(
+                        HeartRateRecord.Sample(Instant.ofEpochMilli(1234L), 55L),
+                        HeartRateRecord.Sample(Instant.ofEpochMilli(5678L), 57L)
+                    )
+            )
+
+        val platformHeartRate = heartRate.toPlatformRecord() as PlatformHeartRateRecord
+
+        assertPlatformRecord(platformHeartRate) {
+            assertThat(samples)
+                .comparingElementsUsing(
+                    Correspondence.from<PlatformHeartRateSample, PlatformHeartRateSample>(
+                        { actual, expected ->
+                            actual!!.beatsPerMinute == expected!!.beatsPerMinute &&
+                                actual.time == expected.time
+                        },
+                        "has same BPM and same time as"
+                    )
+                )
+                .containsExactly(
+                    PlatformHeartRateSample(55L, Instant.ofEpochMilli(1234L)),
+                    PlatformHeartRateSample(57L, Instant.ofEpochMilli(5678L))
+                )
+        }
+    }
+
+    @Test
+    fun heartRateVariabilityRmssdRecord_convertToPlatform() {
+        val platformHeartRateVariabilityRmssd =
+            HeartRateVariabilityRmssdRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    heartRateVariabilityMillis = 1.0,
+                )
+                .toPlatformRecord() as PlatformHeartRateVariabilityRmssdRecord
+
+        assertPlatformRecord(platformHeartRateVariabilityRmssd) {
+            assertThat(heartRateVariabilityMillis).isEqualTo(1.0)
+        }
+    }
+
+    @Test
+    fun heightRecord_convertToPlatform() {
+        val platformHeight =
+            HeightRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    height = Length.meters(1.8),
+                )
+                .toPlatformRecord() as PlatformHeightRecord
+
+        assertPlatformRecord(platformHeight) {
+            assertThat(height).isEqualTo(PlatformLength.fromMeters(1.8))
+        }
+    }
+
+    @Test
+    fun hydrationRecord_convertToPlatform() {
+        val platformHydration =
+            HydrationRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    volume = Volume.liters(90.0),
+                )
+                .toPlatformRecord() as PlatformHydrationRecord
+
+        assertPlatformRecord(platformHydration) {
+            assertThat(volume).isEqualTo(PlatformVolume.fromLiters(90.0))
+        }
+    }
+
+    @Test
+    fun intermenstrualBleedingRecord_convertToPlatform() {
+        val platformIntermenstrualBleeding =
+            IntermenstrualBleedingRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                )
+                .toPlatformRecord() as PlatformIntermenstrualBleedingRecord
+
+        assertPlatformRecord(platformIntermenstrualBleeding)
+    }
+
+    @Test
+    fun leanBodyMassRecord_convertToPlatform() {
+        val platformLeanBodyMass =
+            LeanBodyMassRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    mass = Mass.grams(21.3),
+                )
+                .toPlatformRecord() as PlatformLeanBodyMassRecord
+
+        assertPlatformRecord(platformLeanBodyMass) {
+            assertThat(mass).isEqualTo(PlatformMass.fromGrams(21.3))
+        }
+    }
+
+    @Test
+    fun menstruationFlowRecord_convertToPlatform() {
+        val platformMenstruationFlow =
+            MenstruationFlowRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    flow = MenstruationFlowRecord.FLOW_MEDIUM,
+                )
+                .toPlatformRecord() as PlatformMenstruationFlowRecord
+
+        assertPlatformRecord(platformMenstruationFlow) {
+            assertThat(flow).isEqualTo(PlatformMenstruationFlowType.FLOW_MEDIUM)
+        }
+    }
+
+    @Test
+    fun menstruationPeriodRecord_convertToPlatform() {
+        val platformMenstruationPeriod =
+            MenstruationPeriodRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA
+                )
+                .toPlatformRecord() as PlatformMenstruationPeriodRecord
+
+        assertPlatformRecord(platformMenstruationPeriod)
+    }
+
+    @Test
+    fun nutritionRecord_convertToPlatform() {
+        val nutrition =
+            NutritionRecord(
+                startTime = START_TIME,
+                startZoneOffset = START_ZONE_OFFSET,
+                endTime = END_TIME,
+                endZoneOffset = END_ZONE_OFFSET,
+                metadata = METADATA,
+                calcium = Mass.grams(15.0),
+                caffeine = Mass.grams(20.0),
+                chloride = Mass.grams(25.0),
+                cholesterol = Mass.grams(30.0),
+                chromium = Mass.grams(35.0),
+                copper = Mass.grams(40.0),
+                molybdenum = Mass.grams(45.0),
+                monounsaturatedFat = Mass.grams(50.0),
+                energy = Energy.calories(300.0)
+            )
+
+        val platformNutrition = nutrition.toPlatformRecord() as PlatformNutritionRecord
+
+        assertPlatformRecord(platformNutrition) {
+            assertThat(calcium!!.inGrams).isWithin(tolerance).of(15.0)
+            assertThat(caffeine!!.inGrams).isWithin(tolerance).of(20.0)
+            assertThat(chloride!!.inGrams).isWithin(tolerance).of(25.0)
+            assertThat(cholesterol!!.inGrams).isWithin(tolerance).of(30.0)
+            assertThat(chromium!!.inGrams).isWithin(tolerance).of(35.0)
+            assertThat(copper!!.inGrams).isWithin(tolerance).of(40.0)
+            assertThat(molybdenum!!.inGrams).isWithin(tolerance).of(45.0)
+            assertThat(monounsaturatedFat!!.inGrams).isWithin(tolerance).of(50.0)
+            assertThat(energy!!.inCalories).isWithin(tolerance).of(300.0)
+        }
+    }
+
+    @Test
+    fun ovulationTestRecord_convertToPlatform() {
+        val platformOvulationTest =
+            OvulationTestRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    result = OvulationTestRecord.RESULT_POSITIVE,
+                )
+                .toPlatformRecord() as PlatformOvulationTestRecord
+
+        assertPlatformRecord(platformOvulationTest) {
+            assertThat(result).isEqualTo(PlatformOvulationTestResult.RESULT_POSITIVE)
+        }
+    }
+
+    @Test
+    fun oxygenSaturationRecord_convertToPlatform() {
+        val platformOxygenSaturation =
+            OxygenSaturationRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    percentage = Percentage(15.0),
+                )
+                .toPlatformRecord() as PlatformOxygenSaturationRecord
+
+        assertPlatformRecord(platformOxygenSaturation) {
+            assertThat(percentage).isEqualTo(PlatformPercentage.fromValue(15.0))
+        }
+    }
+
+    @Test
+    fun powerRecord_convertToPlatform() {
+        val platformPowerRecord =
+            PowerRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    samples = listOf(PowerRecord.Sample(START_TIME, Power.watts(300.0))),
+                )
+                .toPlatformRecord() as PlatformPowerRecord
+
+        assertPlatformRecord(platformPowerRecord) {
+            assertThat(samples)
+                .containsExactly(
+                    PlatformPowerRecordSample(PlatformPower.fromWatts(300.0), START_TIME)
+                )
+        }
+    }
+
+    @Test
+    fun respiratoryRateRecord_convertToPlatform() {
+        val platformRespiratoryRate =
+            RespiratoryRateRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    rate = 12.0,
+                )
+                .toPlatformRecord() as PlatformRespiratoryRateRecord
+
+        assertPlatformRecord(platformRespiratoryRate) { assertThat(rate).isEqualTo(12.0) }
+    }
+
+    @Test
+    fun restingHeartRateRecord_convertToPlatform() {
+        val platformRestingHeartRate =
+            RestingHeartRateRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    beatsPerMinute = 57L,
+                )
+                .toPlatformRecord() as PlatformRestingHeartRateRecord
+
+        assertPlatformRecord(platformRestingHeartRate) { assertThat(beatsPerMinute).isEqualTo(57L) }
+    }
+
+    @Test
+    fun sexualActivityRecord_convertToPlatform() {
+        val platformSexualActivity =
+            SexualActivityRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    protectionUsed = SexualActivityRecord.PROTECTION_USED_PROTECTED,
+                )
+                .toPlatformRecord() as PlatformSexualActivityRecord
+
+        assertPlatformRecord(platformSexualActivity) {
+            assertThat(protectionUsed)
+                .isEqualTo(PlatformSexualActivityProtectionUsed.PROTECTION_USED_PROTECTED)
+        }
+    }
+
+    @Test
+    fun sleepSessionRecord_convertToPlatform() {
+        val platformSleepSession =
+            SleepSessionRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    title = "Night night",
+                    notes = "Many dreams",
+                    stages =
+                        listOf(
+                            SleepSessionRecord.Stage(
+                                START_TIME,
+                                START_TIME.plusMillis(40),
+                                SleepSessionRecord.STAGE_TYPE_DEEP
+                            )
+                        )
+                )
+                .toPlatformRecord() as PlatformSleepSessionRecord
+
+        assertPlatformRecord(platformSleepSession) {
+            assertThat(title).isEqualTo("Night night")
+            assertThat(notes).isEqualTo("Many dreams")
+            assertThat(stages)
+                .containsExactly(
+                    PlatformSleepSessionStage(
+                        START_TIME,
+                        START_TIME.plusMillis(40),
+                        PlatformSleepStageType.STAGE_TYPE_SLEEPING_DEEP
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun speedRecord_convertToPlatform() {
+        val platformSpeed =
+            SpeedRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    samples = listOf(SpeedRecord.Sample(END_TIME, Velocity.metersPerSecond(3.0))),
+                )
+                .toPlatformRecord() as PlatformSpeedRecord
+
+        assertPlatformRecord(platformSpeed) {
+            assertThat(samples)
+                .comparingElementsUsing(
+                    Correspondence.from<PlatformSpeedSample, PlatformSpeedSample>(
+                        { actual, expected ->
+                            actual!!.speed.inMetersPerSecond ==
+                                expected!!.speed.inMetersPerSecond && actual.time == expected.time
+                        },
+                        "has same speed and same time as"
+                    )
+                )
+                .containsExactly(
+                    PlatformSpeedSample(PlatformVelocity.fromMetersPerSecond(3.0), END_TIME)
+                )
+        }
+    }
+
+    @Test
+    fun stepsRecord_convertToPlatform() {
+        val platformSteps =
+            StepsRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    count = 10,
+                )
+                .toPlatformRecord() as PlatformStepsRecord
+
+        assertPlatformRecord(platformSteps) { assertThat(count).isEqualTo(10) }
+    }
+
+    @Test
+    fun stepsCadenceRecord_convertToPlatform() {
+        val platformStepsCadence =
+            StepsCadenceRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    samples = listOf(StepsCadenceRecord.Sample(END_TIME, 99.0)),
+                )
+                .toPlatformRecord() as PlatformStepsCadenceRecord
+
+        assertPlatformRecord(platformStepsCadence) {
+            assertThat(samples)
+                .comparingElementsUsing(
+                    Correspondence.from<PlatformStepsCadenceSample, PlatformStepsCadenceSample>(
+                        { actual, expected ->
+                            actual!!.rate == expected!!.rate && actual.time == expected.time
+                        },
+                        "has same rate and same time as"
+                    )
+                )
+                .containsExactly(PlatformStepsCadenceSample(99.0, END_TIME))
+        }
+    }
+
+    @Test
+    fun totalCaloriesBurnedRecord_convertToPlatform() {
+        val platformTotalCaloriesBurned =
+            TotalCaloriesBurnedRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    energy = Energy.calories(100.0),
+                )
+                .toPlatformRecord() as PlatformTotalCaloriesBurnedRecord
+
+        assertPlatformRecord(platformTotalCaloriesBurned) {
+            assertThat(energy).isEqualTo(PlatformEnergy.fromCalories(100.0))
+        }
+    }
+
+    @Test
+    fun vo2MaxRecord_convertToPlatform() {
+        val platformVo2Max =
+            Vo2MaxRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    vo2MillilitersPerMinuteKilogram = 5.0,
+                    measurementMethod = Vo2MaxRecord.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST
+                )
+                .toPlatformRecord() as PlatformVo2MaxRecord
+
+        assertPlatformRecord(platformVo2Max) {
+            assertThat(vo2MillilitersPerMinuteKilogram).isEqualTo(5.0)
+            assertThat(measurementMethod)
+                .isEqualTo(
+                    PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST
+                )
+        }
+    }
+
+    @Test
+    fun weightRecord_convertToPlatform() {
+        val platformWeight =
+            WeightRecord(
+                    time = TIME,
+                    zoneOffset = ZONE_OFFSET,
+                    metadata = METADATA,
+                    weight = Mass.grams(100.0),
+                )
+                .toPlatformRecord() as PlatformWeightRecord
+
+        assertPlatformRecord(platformWeight) {
+            assertThat(weight).isEqualTo(PlatformMass.fromGrams(100.0))
+        }
+    }
+
+    @Test
+    fun wheelChairPushesRecord_convertToPlatform() {
+        val platformWheelchairPushes =
+            WheelchairPushesRecord(
+                    startTime = START_TIME,
+                    startZoneOffset = START_ZONE_OFFSET,
+                    endTime = END_TIME,
+                    endZoneOffset = END_ZONE_OFFSET,
+                    metadata = METADATA,
+                    count = 10,
+                )
+                .toPlatformRecord() as PlatformWheelchairPushesRecord
+
+        assertPlatformRecord(platformWheelchairPushes) { assertThat(count).isEqualTo(10) }
+    }
+
+    @Test
+    fun activeCaloriesBurnedRecord_convertToSdk() {
+        val sdkActiveCaloriesBurned =
+            PlatformActiveCaloriesBurnedRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformEnergy.fromCalories(300.0)
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as ActiveCaloriesBurnedRecord
+
+        assertSdkRecord(sdkActiveCaloriesBurned) {
+            assertThat(energy).isEqualTo(Energy.calories(300.0))
+        }
+    }
+
+    @Test
+    fun basalBodyTemperatureRecord_convertToSdk() {
+        val sdkBasalBodyTemperature =
+            PlatformBasalBodyTemperatureRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_RECTUM,
+                    PlatformTemperature.fromCelsius(37.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BasalBodyTemperatureRecord
+
+        assertSdkRecord(sdkBasalBodyTemperature) {
+            assertThat(measurementLocation)
+                .isEqualTo(BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_RECTUM)
+            assertThat(temperature).isEqualTo(Temperature.celsius(37.0))
+        }
+    }
+
+    @Test
+    fun basalMetabolicRateRecord_convertToSdk() {
+        val sdkBasalMetabolicRate =
+            PlatformBasalMetabolicRateRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformPower.fromWatts(100.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BasalMetabolicRateRecord
+
+        assertSdkRecord(sdkBasalMetabolicRate) {
+            assertThat(basalMetabolicRate).isEqualTo(Power.watts(100.0))
+        }
+    }
+
+    @Test
+    fun bloodGlucoseRecord_convertToSdk() {
+        val sdkBloodGlucose =
+            PlatformBloodGlucoseRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_TEARS,
+                    PlatformBloodGlucose.fromMillimolesPerLiter(10.2),
+                    PlatformBloodGlucoseRelationToMealType.RELATION_TO_MEAL_FASTING,
+                    PlatformMealType.MEAL_TYPE_SNACK
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BloodGlucoseRecord
+
+        assertSdkRecord(sdkBloodGlucose) {
+            assertThat(level).isEqualTo(BloodGlucose.millimolesPerLiter(10.2))
+            assertThat(specimenSource).isEqualTo(BloodGlucoseRecord.SPECIMEN_SOURCE_TEARS)
+            assertThat(mealType).isEqualTo(MealType.MEAL_TYPE_SNACK)
+            assertThat(relationToMeal).isEqualTo(BloodGlucoseRecord.RELATION_TO_MEAL_FASTING)
+        }
+    }
+
+    @Test
+    fun bloodPressureRecord_convertToSdk() {
+        val sdkBloodPressure =
+            PlatformBloodPressureRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformBloodPressureMeasurementLocation
+                        .BLOOD_PRESSURE_MEASUREMENT_LOCATION_LEFT_WRIST,
+                    PlatformPressure.fromMillimetersOfMercury(20.0),
+                    PlatformPressure.fromMillimetersOfMercury(15.0),
+                    PlatformBloodPressureBodyPosition.BODY_POSITION_STANDING_UP
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BloodPressureRecord
+
+        assertSdkRecord(sdkBloodPressure) {
+            assertThat(measurementLocation)
+                .isEqualTo(BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST)
+            assertThat(systolic).isEqualTo(Pressure.millimetersOfMercury(20.0))
+            assertThat(diastolic).isEqualTo(Pressure.millimetersOfMercury(15.0))
+            assertThat(bodyPosition).isEqualTo(BloodPressureRecord.BODY_POSITION_STANDING_UP)
+        }
+    }
+
+    @Test
+    fun bodyFatRecord_convertToSdk() {
+        val sdkBodyFat =
+            PlatformBodyFatRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformPercentage.fromValue(18.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BodyFatRecord
+
+        assertSdkRecord(sdkBodyFat) { assertThat(percentage).isEqualTo(Percentage(18.0)) }
+    }
+
+    @Test
+    fun bodyTemperatureRecord_convertToSdk() {
+        val sdkBodyTemperature =
+            PlatformBodyTemperatureRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_WRIST,
+                    PlatformTemperature.fromCelsius(27.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BodyTemperatureRecord
+
+        assertSdkRecord(sdkBodyTemperature) {
+            assertThat(measurementLocation)
+                .isEqualTo(BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_WRIST)
+            assertThat(temperature).isEqualTo(Temperature.celsius(27.0))
+        }
+    }
+
+    @Test
+    fun bodyWaterMassRecord_convertToSdk() {
+        val sdkBodyWaterMass =
+            PlatformBodyWaterMassRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformMass.fromGrams(12.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BodyWaterMassRecord
+
+        assertSdkRecord(sdkBodyWaterMass) { assertThat(mass).isEqualTo(Mass.grams(12.0)) }
+    }
+
+    @Test
+    fun boneMassRecord_convertToSdk() {
+        val sdkBoneMass =
+            PlatformBoneMassRecordBuilder(PLATFORM_METADATA, TIME, PlatformMass.fromGrams(73.0))
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as BoneMassRecord
+
+        assertSdkRecord(sdkBoneMass) { assertThat(mass).isEqualTo(Mass.grams(73.0)) }
+    }
+
+    @Test
+    fun cervicalMucusRecord_convertToSdk() {
+        val sdkCervicalMucus =
+            PlatformCervicalMucusRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformCervicalMucusSensation.SENSATION_HEAVY,
+                    PlatformCervicalMucusAppearance.APPEARANCE_DRY
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as CervicalMucusRecord
+
+        assertSdkRecord(sdkCervicalMucus) {
+            assertThat(sensation).isEqualTo(CervicalMucusRecord.SENSATION_HEAVY)
+            assertThat(appearance).isEqualTo(CervicalMucusRecord.APPEARANCE_DRY)
+        }
+    }
+
+    @Test
+    fun cyclingPedalingCadenceRecord_convertToSdk() {
+        val sdkCyclingPedalingCadence =
+            PlatformCyclingPedalingCadenceRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    listOf(PlatformCyclingPedalingCadenceSample(23.0, END_TIME))
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as CyclingPedalingCadenceRecord
+
+        assertSdkRecord(sdkCyclingPedalingCadence) {
+            assertThat(samples).containsExactly(CyclingPedalingCadenceRecord.Sample(END_TIME, 23.0))
+        }
+    }
+
+    @Test
+    fun distanceRecord_convertToSdk() {
+        val sdkDistance =
+            PlatformDistanceRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformLength.fromMeters(500.0)
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as DistanceRecord
+
+        assertSdkRecord(sdkDistance) { assertThat(distance).isEqualTo(Length.meters(500.0)) }
+    }
+
+    @Test
+    fun elevationGainedRecord_convertToSdk() {
+        val sdkElevationGained =
+            PlatformElevationGainedRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformLength.fromMeters(10.0)
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as ElevationGainedRecord
+
+        assertSdkRecord(sdkElevationGained) { assertThat(elevation).isEqualTo(Length.meters(10.0)) }
+    }
+
+    @Test
+    fun exerciseSessionRecord_convertToSdk() {
+        val sdkExerciseSession =
+            PlatformExerciseSessionRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformExerciseSessionType
+                        .EXERCISE_SESSION_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
+                )
+                .setTitle("Training")
+                .setNotes("Improve jump serve")
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .setLaps(
+                    listOf(
+                        PlatformExerciseLapBuilder(
+                                START_TIME.plusMillis(6),
+                                START_TIME.plusMillis(10)
+                            )
+                            .setLength(PlatformLength.fromMeters(1.0))
+                            .build(),
+                        PlatformExerciseLapBuilder(
+                                START_TIME.plusMillis(11),
+                                START_TIME.plusMillis(15)
+                            )
+                            .setLength(PlatformLength.fromMeters(1.5))
+                            .build()
+                    )
+                )
+                .setSegments(
+                    listOf(
+                        PlatformExerciseSegmentBuilder(
+                                START_TIME.plusMillis(1),
+                                START_TIME.plusMillis(10),
+                                PlatformExerciseSegmentType
+                                    .EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS
+                            )
+                            .setRepetitionsCount(10)
+                            .build()
+                    )
+                )
+                .setRoute(
+                    PlatformExerciseRoute(
+                        listOf(
+                            PlatformExerciseRouteLocationBuilder(START_TIME, 23.4, -23.4)
+                                .setAltitude(PlatformLength.fromMeters(10.0))
+                                .setHorizontalAccuracy(PlatformLength.fromMeters(2.0))
+                                .setVerticalAccuracy(PlatformLength.fromMeters(3.0))
+                                .build()
+                        )
+                    )
+                )
+                .build()
+                .toSdkRecord() as ExerciseSessionRecord
+
+        assertSdkRecord(sdkExerciseSession) {
+            assertThat(title).isEqualTo("Training")
+            assertThat(notes).isEqualTo("Improve jump serve")
+            assertThat(exerciseType)
+                .isEqualTo(ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING)
+            assertThat(laps)
+                .containsExactly(
+                    ExerciseLap(
+                        START_TIME.plusMillis(6),
+                        START_TIME.plusMillis(10),
+                        Length.meters(1.0)
+                    ),
+                    ExerciseLap(
+                        START_TIME.plusMillis(11),
+                        START_TIME.plusMillis(15),
+                        Length.meters(1.5)
+                    )
+                )
+            assertThat(segments)
+                .containsExactly(
+                    ExerciseSegment(
+                        START_TIME.plusMillis(1),
+                        START_TIME.plusMillis(10),
+                        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
+                        10
+                    )
+                )
+            assertThat(route)
+                .isEqualTo(
+                    ExerciseRoute(
+                        listOf(
+                            ExerciseRoute.Location(
+                                time = START_TIME,
+                                latitude = 23.4,
+                                longitude = -23.4,
+                                altitude = Length.meters(10.0),
+                                horizontalAccuracy = Length.meters(2.0),
+                                verticalAccuracy = Length.meters(3.0)
+                            )
+                        )
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun floorsClimbedRecord_convertToSdk() {
+        val sdkFloorsClimbed =
+            PlatformFloorsClimbedRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME, 10.0)
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as FloorsClimbedRecord
+
+        assertSdkRecord(sdkFloorsClimbed) { assertThat(floors).isEqualTo(10.0) }
+    }
+
+    @Test
+    fun heartRateRecord_convertToSdk() {
+        val sdkHeartRate =
+            PlatformHeartRateRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    listOf(PlatformHeartRateSample(83, START_TIME))
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as HeartRateRecord
+
+        assertSdkRecord(sdkHeartRate) {
+            assertThat(samples).containsExactly(HeartRateRecord.Sample(START_TIME, 83))
+        }
+    }
+
+    @Test
+    fun heartRateVariabilityRmssdRecord_convertToSdk() {
+        val sdkHeartRateVariabilityRmssd =
+            PlatformHeartRateVariabilityRmssdRecordBuilder(PLATFORM_METADATA, TIME, 1.6)
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as HeartRateVariabilityRmssdRecord
+
+        assertSdkRecord(sdkHeartRateVariabilityRmssd) {
+            assertThat(heartRateVariabilityMillis).isEqualTo(1.6)
+        }
+    }
+
+    @Test
+    fun heightRecord_convertToSdk() {
+        val sdkHeight =
+            PlatformHeightRecordBuilder(PLATFORM_METADATA, TIME, PlatformLength.fromMeters(1.7))
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as HeightRecord
+
+        assertSdkRecord(sdkHeight) { assertThat(height).isEqualTo(Length.meters(1.7)) }
+    }
+
+    @Test
+    fun hydrationRecord_convertToSdk() {
+        val sdkHydration =
+            PlatformHydrationRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformVolume.fromLiters(90.0)
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as HydrationRecord
+
+        assertSdkRecord(sdkHydration) { assertThat(volume).isEqualTo(Volume.liters(90.0)) }
+    }
+
+    @Test
+    fun intermenstrualBleedingRecord_convertToSdk() {
+        val sdkIntermenstrualBleeding =
+            PlatformIntermenstrualBleedingRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as IntermenstrualBleedingRecord
+
+        assertSdkRecord(sdkIntermenstrualBleeding)
+    }
+
+    @Test
+    fun leanBodyMassRecord_convertToSdk() {
+        val sdkLeanBodyMass =
+            PlatformLeanBodyMassRecordBuilder(PLATFORM_METADATA, TIME, PlatformMass.fromGrams(9.0))
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as LeanBodyMassRecord
+
+        assertSdkRecord(sdkLeanBodyMass) { assertThat(mass).isEqualTo(Mass.grams(9.0)) }
+    }
+
+    @Test
+    fun menstruationFlowRecord_convertToSdk() {
+        val sdkMenstruationFlow =
+            PlatformMenstruationFlowRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformMenstruationFlowType.FLOW_MEDIUM
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as MenstruationFlowRecord
+
+        assertSdkRecord(sdkMenstruationFlow) {
+            assertThat(flow).isEqualTo(MenstruationFlowRecord.FLOW_MEDIUM)
+        }
+    }
+
+    @Test
+    fun menstruationPeriodRecord_convertToSdk() {
+        val sdkMenstruationPeriod =
+            PlatformMenstruationPeriodRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME)
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as MenstruationPeriodRecord
+
+        assertSdkRecord(sdkMenstruationPeriod)
+    }
+
+    @Test
+    fun nutritionRecord_convertToSdk() {
+        val sdkNutrition =
+            PlatformNutritionRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME)
+                .setMealName("Cheat meal")
+                .setMealType(PlatformMealType.MEAL_TYPE_DINNER)
+                .setChromium(PlatformMass.fromGrams(0.01))
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as NutritionRecord
+
+        assertSdkRecord(sdkNutrition) {
+            assertThat(name).isEqualTo("Cheat meal")
+            assertThat(mealType).isEqualTo(MealType.MEAL_TYPE_DINNER)
+            assertThat(chromium).isEqualTo(Mass.grams(0.01))
+        }
+    }
+
+    @Test
+    fun ovulationTestRecord_convertToSdk() {
+        val sdkOvulationTest =
+            PlatformOvulationTestRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformOvulationTestResult.RESULT_NEGATIVE
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as OvulationTestRecord
+
+        assertSdkRecord(sdkOvulationTest) {
+            assertThat(result).isEqualTo(OvulationTestRecord.RESULT_NEGATIVE)
+        }
+    }
+
+    @Test
+    fun oxygenSaturationRecord_convertToSdk() {
+        val sdkOxygenSaturation =
+            PlatformOxygenSaturationRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformPercentage.fromValue(21.0)
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as OxygenSaturationRecord
+
+        assertSdkRecord(sdkOxygenSaturation) { assertThat(percentage).isEqualTo(Percentage(21.0)) }
+    }
+
+    @Test
+    fun powerRecord_convertToSdk() {
+        val sdkPower =
+            PlatformPowerRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    listOf(PlatformPowerRecordSample(PlatformPower.fromWatts(300.0), START_TIME))
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as PowerRecord
+
+        assertSdkRecord(sdkPower) {
+            assertThat(samples).containsExactly(PowerRecord.Sample(START_TIME, Power.watts(300.0)))
+        }
+    }
+
+    @Test
+    fun respiratoryRateRecord_convertToSdk() {
+        val sdkRespiratoryRate =
+            PlatformRespiratoryRateRecordBuilder(PLATFORM_METADATA, TIME, 12.0)
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as RespiratoryRateRecord
+
+        assertSdkRecord(sdkRespiratoryRate) { assertThat(rate).isEqualTo(12.0) }
+    }
+
+    @Test
+    fun restingHeartRateRecord_convertToSdk() {
+        val sdkRestingHeartRate =
+            PlatformRestingHeartRateRecordBuilder(PLATFORM_METADATA, TIME, 37)
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as RestingHeartRateRecord
+
+        assertSdkRecord(sdkRestingHeartRate) { assertThat(beatsPerMinute).isEqualTo(37) }
+    }
+
+    @Test
+    fun sexualActivityRecord_convertToSdk() {
+        val sdkSexualActivity =
+            PlatformSexualActivityRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformSexualActivityProtectionUsed.PROTECTION_USED_PROTECTED
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as SexualActivityRecord
+
+        assertSdkRecord(sdkSexualActivity) {
+            assertThat(protectionUsed).isEqualTo(SexualActivityRecord.PROTECTION_USED_PROTECTED)
+        }
+    }
+
+    @Test
+    fun sleepSessionRecord_convertToSdk() {
+        val sdkSleepSession =
+            PlatformSleepSessionRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME)
+                .setTitle("nap")
+                .setNotes("Afternoon reset")
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .setStages(
+                    listOf(
+                        PlatformSleepSessionStage(
+                            START_TIME,
+                            START_TIME.plusMillis(1),
+                            PlatformSleepStageType.STAGE_TYPE_AWAKE
+                        ),
+                        PlatformSleepSessionStage(
+                            END_TIME.minusMillis(1),
+                            END_TIME,
+                            PlatformSleepStageType.STAGE_TYPE_SLEEPING
+                        )
+                    )
+                )
+                .build()
+                .toSdkRecord() as SleepSessionRecord
+
+        assertSdkRecord(sdkSleepSession) {
+            assertThat(title).isEqualTo("nap")
+            assertThat(notes).isEqualTo("Afternoon reset")
+            assertThat(stages)
+                .containsExactly(
+                    SleepSessionRecord.Stage(
+                        START_TIME,
+                        START_TIME.plusMillis(1),
+                        SleepSessionRecord.STAGE_TYPE_AWAKE
+                    ),
+                    SleepSessionRecord.Stage(
+                        END_TIME.minusMillis(1),
+                        END_TIME,
+                        SleepSessionRecord.STAGE_TYPE_SLEEPING
+                    )
+                )
+        }
+    }
+
+    @Test
+    fun speedRecord_convertToSdk() {
+        val sdkSpeed =
+            PlatformSpeedRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    listOf(
+                        PlatformSpeedSample(PlatformVelocity.fromMetersPerSecond(99.0), END_TIME)
+                    )
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as SpeedRecord
+
+        assertSdkRecord(sdkSpeed) {
+            assertThat(samples)
+                .containsExactly(SpeedRecord.Sample(END_TIME, Velocity.metersPerSecond(99.0)))
+        }
+    }
+
+    @Test
+    fun stepsCadenceRecord_convertToSdk() {
+        val sdkStepsCadence =
+            PlatformStepsCadenceRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    listOf(PlatformStepsCadenceSample(10.0, END_TIME))
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as StepsCadenceRecord
+
+        assertSdkRecord(sdkStepsCadence) {
+            assertThat(samples).containsExactly(StepsCadenceRecord.Sample(END_TIME, 10.0))
+        }
+    }
+
+    @Test
+    fun stepsRecord_convertToSdk() {
+        val sdkSteps =
+            PlatformStepsRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME, 10)
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as StepsRecord
+
+        assertSdkRecord(sdkSteps) { assertThat(count).isEqualTo(10) }
+    }
+
+    @Test
+    fun totalCaloriesBurnedRecord_convertToSdk() {
+        val sdkTotalCaloriesBurned =
+            PlatformTotalCaloriesBurnedRecordBuilder(
+                    PLATFORM_METADATA,
+                    START_TIME,
+                    END_TIME,
+                    PlatformEnergy.fromCalories(333.0)
+                )
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as TotalCaloriesBurnedRecord
+
+        assertSdkRecord(sdkTotalCaloriesBurned) {
+            assertThat(energy).isEqualTo(Energy.calories(333.0))
+        }
+    }
+
+    @Test
+    fun vo2MaxRecord_convertToSdk() {
+        val sdkVo2Max =
+            PlatformVo2MaxRecordBuilder(
+                    PLATFORM_METADATA,
+                    TIME,
+                    PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST,
+                    13.0
+                )
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as Vo2MaxRecord
+
+        assertSdkRecord(sdkVo2Max) {
+            assertThat(measurementMethod)
+                .isEqualTo(Vo2MaxRecord.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST)
+            assertThat(vo2MillilitersPerMinuteKilogram).isEqualTo(13.0)
+        }
+    }
+
+    @Test
+    fun weightRecord_convertToSdk() {
+        val sdkWeight =
+            PlatformWeightRecordBuilder(PLATFORM_METADATA, TIME, PlatformMass.fromGrams(63.0))
+                .setZoneOffset(ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as WeightRecord
+
+        assertSdkRecord(sdkWeight) { assertThat(weight).isEqualTo(Mass.grams(63.0)) }
+    }
+
+    @Test
+    fun wheelChairPushesRecord_convertToSdk() {
+        val sdkWheelchairPushes =
+            PlatformWheelchairPushesRecordBuilder(PLATFORM_METADATA, START_TIME, END_TIME, 18)
+                .setStartZoneOffset(START_ZONE_OFFSET)
+                .setEndZoneOffset(END_ZONE_OFFSET)
+                .build()
+                .toSdkRecord() as WheelchairPushesRecord
+
+        assertSdkRecord(sdkWheelchairPushes) { assertThat(count).isEqualTo(18) }
+    }
+
+    private fun <T : PlatformIntervalRecord> assertPlatformRecord(platformRecord: T) {
+        assertPlatformRecord(platformRecord) {}
+    }
+
+    private fun <T : PlatformIntervalRecord> assertPlatformRecord(
+        platformRecord: T,
+        typeSpecificAssertions: T.() -> Unit
+    ) {
+        assertThat(platformRecord.startTime).isEqualTo(START_TIME)
+        assertThat(platformRecord.startZoneOffset).isEqualTo(START_ZONE_OFFSET)
+        assertThat(platformRecord.endTime).isEqualTo(END_TIME)
+        assertThat(platformRecord.endZoneOffset).isEqualTo(END_ZONE_OFFSET)
+        assertThat(platformRecord.metadata).isEqualTo(PLATFORM_METADATA)
+        platformRecord.typeSpecificAssertions()
+    }
+
+    private fun <T : PlatformInstantRecord> assertPlatformRecord(platformRecord: T) =
+        assertPlatformRecord(platformRecord) {}
+
+    private fun <T : PlatformInstantRecord> assertPlatformRecord(
+        platformRecord: T,
+        typeSpecificAssertions: T.() -> Unit
+    ) {
+        assertThat(platformRecord.time).isEqualTo(TIME)
+        assertThat(platformRecord.zoneOffset).isEqualTo(ZONE_OFFSET)
+        assertThat(platformRecord.metadata).isEqualTo(PLATFORM_METADATA)
+        platformRecord.typeSpecificAssertions()
+    }
+
+    private fun <T : IntervalRecord> assertSdkRecord(sdkRecord: T) = assertSdkRecord(sdkRecord) {}
+
+    private fun <T : IntervalRecord> assertSdkRecord(
+        sdkRecord: T,
+        typeSpecificAssertions: T.() -> Unit
+    ) {
+        assertThat(sdkRecord.startTime).isEqualTo(START_TIME)
+        assertThat(sdkRecord.startZoneOffset).isEqualTo(START_ZONE_OFFSET)
+        assertThat(sdkRecord.endTime).isEqualTo(END_TIME)
+        assertThat(sdkRecord.endZoneOffset).isEqualTo(END_ZONE_OFFSET)
+        assertThat(sdkRecord.metadata.id).isEqualTo(METADATA.id)
+        assertThat(sdkRecord.metadata.dataOrigin).isEqualTo(METADATA.dataOrigin)
+        sdkRecord.typeSpecificAssertions()
+    }
+
+    private fun <T : InstantaneousRecord> assertSdkRecord(sdkRecord: T) =
+        assertSdkRecord(sdkRecord) {}
+
+    private fun <T : InstantaneousRecord> assertSdkRecord(
+        sdkRecord: T,
+        typeSpecificAssertions: T.() -> Unit
+    ) {
+        assertThat(sdkRecord.time).isEqualTo(TIME)
+        assertThat(sdkRecord.zoneOffset).isEqualTo(ZONE_OFFSET)
+        assertThat(sdkRecord.metadata.id).isEqualTo(METADATA.id)
+        assertThat(sdkRecord.metadata.dataOrigin).isEqualTo(METADATA.dataOrigin)
+        sdkRecord.typeSpecificAssertions()
+    }
+
+    private companion object {
+        val TIME: Instant = Instant.ofEpochMilli(1235L)
+        val ZONE_OFFSET: ZoneOffset = ZoneOffset.UTC
+
+        val START_TIME: Instant = Instant.ofEpochMilli(1234L)
+        val END_TIME: Instant = Instant.ofEpochMilli(56780L)
+        val START_ZONE_OFFSET: ZoneOffset = ZoneOffset.UTC
+        val END_ZONE_OFFSET: ZoneOffset = ZoneOffset.ofHours(2)
+
+        val METADATA = Metadata(id = "someId", dataOrigin = DataOrigin("somePackage"))
+
+        val PLATFORM_METADATA =
+            PlatformMetadataBuilder()
+                .setId("someId")
+                .setDataOrigin(PlatformDataOriginBuilder().setPackageName("somePackage").build())
+                .build()
+    }
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RequestConvertersTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RequestConvertersTest.kt
new file mode 100644
index 0000000..4dcd780
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/RequestConvertersTest.kt
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.annotation.TargetApi
+import android.health.connect.LocalTimeRangeFilter
+import android.health.connect.TimeInstantRangeFilter
+import android.health.connect.datatypes.DataOrigin as PlatformDataOrigin
+import android.health.connect.datatypes.HeartRateRecord as PlatformHeartRateRecord
+import android.health.connect.datatypes.NutritionRecord as PlatformNutritionRecord
+import android.health.connect.datatypes.StepsRecord as PlatformStepsRecord
+import android.health.connect.datatypes.WheelchairPushesRecord as PlatformWheelchairPushesRecord
+import android.os.Build
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import androidx.health.connect.client.records.metadata.DataOrigin
+import androidx.health.connect.client.request.AggregateGroupByDurationRequest
+import androidx.health.connect.client.request.AggregateGroupByPeriodRequest
+import androidx.health.connect.client.request.AggregateRequest
+import androidx.health.connect.client.request.ChangesTokenRequest
+import androidx.health.connect.client.request.ReadRecordsRequest
+import androidx.health.connect.client.time.TimeRangeFilter
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.time.Duration
+import java.time.Instant
+import java.time.LocalDateTime
+import java.time.Month
+import java.time.Period
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@SmallTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class RequestConvertersTest {
+
+    @Test
+    fun readRecordsRequest_fromSdkToPlatform() {
+        val sdkRequest =
+            ReadRecordsRequest(
+                StepsRecord::class,
+                TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L)),
+                setOf(DataOrigin("package1"), DataOrigin("package2"))
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            assertThat(recordType).isAssignableTo(PlatformStepsRecord::class.java)
+            assertThat(isAscending).isTrue() // Default Order
+            assertThat(dataOrigins)
+                .containsExactly(
+                    PlatformDataOrigin.Builder().setPackageName("package1").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package2").build()
+                )
+        }
+    }
+
+    @Test
+    fun readRecordsRequest_fromSdkToPlatform_ascendingOrderIgnoredWhenPageTokenIsSet() {
+        val sdkRequest =
+            ReadRecordsRequest(
+                StepsRecord::class,
+                TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L)),
+                setOf(DataOrigin("package1"), DataOrigin("package2")),
+                ascendingOrder = false,
+                pageToken = "123"
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            assertThat(recordType).isAssignableTo(PlatformStepsRecord::class.java)
+            assertThat(pageToken).isEqualTo(123)
+            assertThat(dataOrigins)
+                .containsExactly(
+                    PlatformDataOrigin.Builder().setPackageName("package1").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package2").build()
+                )
+        }
+    }
+
+    @Test
+    fun timeRangeFilter_instant_fromSdkToPlatform() {
+        val sdkFilter =
+            TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L))
+
+        with(sdkFilter.toPlatformTimeRangeFilter() as TimeInstantRangeFilter) {
+            assertThat(endTime).isEqualTo(Instant.ofEpochMilli(456L))
+        }
+    }
+
+    @Test
+    fun timeRangeFilter_localDateTime_fromSdkToPlatform() {
+        val sdkFilter = TimeRangeFilter.before(LocalDateTime.of(2023, Month.MARCH, 10, 17, 30))
+
+        with(sdkFilter.toPlatformTimeRangeFilter() as LocalTimeRangeFilter) {
+            assertThat(endTime).isEqualTo(LocalDateTime.of(2023, Month.MARCH, 10, 17, 30))
+        }
+    }
+
+    @Test
+    fun timeRangeFilter_fromSdkToPlatform_none() {
+
+        val sdkFilter = TimeRangeFilter.none()
+
+        with(sdkFilter.toPlatformTimeRangeFilter() as TimeInstantRangeFilter) {
+            assertThat(startTime).isEqualTo(Instant.EPOCH)
+        }
+    }
+
+    @Test
+    fun changesTokenRequest_fromSdkToPlatform() {
+        val sdkRequest =
+            ChangesTokenRequest(
+                setOf(StepsRecord::class, HeartRateRecord::class),
+                setOf(DataOrigin("package1"), DataOrigin("package2"))
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            assertThat(recordTypes)
+                .containsExactly(
+                    PlatformStepsRecord::class.java,
+                    PlatformHeartRateRecord::class.java
+                )
+            assertThat(dataOriginFilters)
+                .containsExactly(
+                    PlatformDataOrigin.Builder().setPackageName("package1").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package2").build()
+                )
+        }
+    }
+
+    @Test
+    fun aggregateRequest_fromSdkToPlatform() {
+        val sdkRequest =
+            AggregateRequest(
+                setOf(StepsRecord.COUNT_TOTAL, NutritionRecord.CAFFEINE_TOTAL),
+                TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L)),
+                setOf(DataOrigin("package1"))
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            with(timeRangeFilter as TimeInstantRangeFilter) {
+                assertThat(startTime).isEqualTo(Instant.ofEpochMilli(123L))
+                assertThat(endTime).isEqualTo(Instant.ofEpochMilli(456L))
+            }
+            assertThat(aggregationTypes)
+                .containsExactly(
+                    PlatformStepsRecord.STEPS_COUNT_TOTAL,
+                    PlatformNutritionRecord.CAFFEINE_TOTAL
+                )
+            assertThat(dataOriginsFilters)
+                .containsExactly(PlatformDataOrigin.Builder().setPackageName("package1").build())
+        }
+    }
+
+    @Test
+    fun aggregateGroupByDurationRequest_fromSdkToPlatform() {
+        val sdkRequest =
+            AggregateGroupByDurationRequest(
+                setOf(NutritionRecord.ENERGY_TOTAL),
+                TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L)),
+                Duration.ofDays(1),
+                setOf(DataOrigin("package1"), DataOrigin("package2"))
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            with(timeRangeFilter as TimeInstantRangeFilter) {
+                assertThat(startTime).isEqualTo(Instant.ofEpochMilli(123L))
+                assertThat(endTime).isEqualTo(Instant.ofEpochMilli(456L))
+            }
+            assertThat(aggregationTypes).containsExactly(PlatformNutritionRecord.ENERGY_TOTAL)
+            assertThat(dataOriginsFilters)
+                .containsExactly(
+                    PlatformDataOrigin.Builder().setPackageName("package1").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package2").build()
+                )
+        }
+    }
+
+    @Test
+    fun aggregateGroupByPeriodRequest_fromSdkToPlatform() {
+        val sdkRequest =
+            AggregateGroupByPeriodRequest(
+                setOf(HeartRateRecord.BPM_MAX, HeartRateRecord.BPM_MIN, HeartRateRecord.BPM_AVG),
+                TimeRangeFilter.between(Instant.ofEpochMilli(123L), Instant.ofEpochMilli(456L)),
+                Period.ofDays(1),
+                setOf(DataOrigin("package1"), DataOrigin("package2"), DataOrigin("package3"))
+            )
+
+        with(sdkRequest.toPlatformRequest()) {
+            with(timeRangeFilter as TimeInstantRangeFilter) {
+                assertThat(startTime).isEqualTo(Instant.ofEpochMilli(123L))
+                assertThat(endTime).isEqualTo(Instant.ofEpochMilli(456L))
+            }
+            assertThat(aggregationTypes)
+                .containsExactly(
+                    PlatformHeartRateRecord.BPM_MAX,
+                    PlatformHeartRateRecord.BPM_MIN,
+                    PlatformHeartRateRecord.BPM_AVG
+                )
+            assertThat(dataOriginsFilters)
+                .containsExactly(
+                    PlatformDataOrigin.Builder().setPackageName("package1").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package2").build(),
+                    PlatformDataOrigin.Builder().setPackageName("package3").build()
+                )
+        }
+    }
+
+    @Test
+    fun toAggregationType_convertFromSdkToPlatform() {
+        assertThat(WheelchairPushesRecord.COUNT_TOTAL.toAggregationType())
+            .isEqualTo(PlatformWheelchairPushesRecord.WHEEL_CHAIR_PUSHES_COUNT_TOTAL)
+        assertThat(NutritionRecord.ENERGY_TOTAL.toAggregationType())
+            .isEqualTo(PlatformNutritionRecord.ENERGY_TOTAL)
+    }
+}
diff --git a/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt
new file mode 100644
index 0000000..fffd43a
--- /dev/null
+++ b/health/connect/connect-client/src/androidTest/java/androidx/health/connect/client/impl/platform/records/ResponseConvertersTest.kt
@@ -0,0 +1,263 @@
+/*
+ * 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.health.connect.client.impl.platform.records
+
+import android.annotation.TargetApi
+import android.health.connect.datatypes.units.Energy as PlatformEnergy
+import android.health.connect.datatypes.units.Length as PlatformLength
+import android.health.connect.datatypes.units.Mass as PlatformMass
+import android.health.connect.datatypes.units.Power as PlatformPower
+import android.health.connect.datatypes.units.Volume as PlatformVolume
+import android.os.Build
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.records.BasalMetabolicRateRecord
+import androidx.health.connect.client.records.DistanceRecord
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.FloorsClimbedRecord
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.metadata.DataOrigin
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Correspondence
+import com.google.common.truth.Truth.assertThat
+import java.time.Duration
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+@SmallTest
+@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+// Comment the SDK suppress to run on emulators lower than U.
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class ResponseConvertersTest {
+
+    private val tolerance = Correspondence.tolerance(1e-6)
+
+    @Test
+    fun buildAggregationResult() {
+        val aggregationResult =
+            buildAggregationResult(
+                metrics =
+                    setOf(HeartRateRecord.BPM_MIN, ExerciseSessionRecord.EXERCISE_DURATION_TOTAL),
+                aggregationValueGetter = { aggregationType ->
+                    when (aggregationType) {
+                        PlatformHeartRateRecord.BPM_MIN -> 53L
+                        PlatformExerciseSessionRecord.EXERCISE_DURATION_TOTAL -> 60_000L
+                        else -> null
+                    }
+                },
+                platformDataOriginsGetter = { aggregationType ->
+                    when (aggregationType) {
+                        PlatformHeartRateRecord.BPM_MIN ->
+                            setOf(
+                                PlatformDataOriginBuilder().setPackageName("HR App1").build(),
+                                PlatformDataOriginBuilder().setPackageName("HR App2").build()
+                            )
+                        PlatformExerciseSessionRecord.EXERCISE_DURATION_TOTAL ->
+                            setOf(PlatformDataOriginBuilder().setPackageName("Workout app").build())
+                        else -> emptySet()
+                    }
+                }
+            )
+
+        assertThat(aggregationResult[HeartRateRecord.BPM_MIN]).isEqualTo(53L)
+        assertThat(aggregationResult[ExerciseSessionRecord.EXERCISE_DURATION_TOTAL])
+            .isEqualTo(Duration.ofMinutes(1))
+        assertThat(aggregationResult.dataOrigins)
+            .containsExactly(
+                DataOrigin("HR App1"),
+                DataOrigin("HR App2"),
+                DataOrigin("Workout app")
+            )
+    }
+
+    @Test
+    fun getLongMetricValues_convertsValueAccurately() {
+        val metricValues =
+            getLongMetricValues(
+                mapOf(
+                    HeartRateRecord.BPM_MIN as AggregateMetric<Any> to 53L,
+                    ExerciseSessionRecord.EXERCISE_DURATION_TOTAL as AggregateMetric<Any> to 60_000L
+                )
+            )
+        assertThat(metricValues)
+            .containsExactly(
+                HeartRateRecord.BPM_MIN.metricKey,
+                53L,
+                ExerciseSessionRecord.EXERCISE_DURATION_TOTAL.metricKey,
+                60_000L
+            )
+    }
+
+    @Test
+    fun getLongMetricValues_ignoresNonLongMetricTypes() {
+        val metricValues =
+            getLongMetricValues(
+                mapOf(
+                    NutritionRecord.ENERGY_TOTAL as AggregateMetric<Any> to
+                        PlatformEnergy.fromCalories(418_400.0)
+                )
+            )
+        assertThat(metricValues).isEmpty()
+    }
+
+    @Test
+    fun getDoubleMetricValues_convertsEnergyToKilocalories() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    NutritionRecord.ENERGY_TOTAL as AggregateMetric<Any> to
+                        PlatformEnergy.fromCalories(418_400.0)
+                )
+            )
+        assertThat(metricValues)
+            .comparingValuesUsing(tolerance)
+            .containsExactly(NutritionRecord.ENERGY_TOTAL.metricKey, 418.4)
+    }
+
+    @Test
+    fun getDoubleMetricValues_convertsLengthToMeters() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    DistanceRecord.DISTANCE_TOTAL as AggregateMetric<Any> to
+                        PlatformLength.fromMeters(50.0)
+                )
+            )
+        assertThat(metricValues).containsExactly(DistanceRecord.DISTANCE_TOTAL.metricKey, 50.0)
+    }
+
+    @Test
+    fun getDoubleMetricValues_convertsMassToGrams() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    NutritionRecord.BIOTIN_TOTAL as AggregateMetric<Any> to
+                        PlatformMass.fromGrams(88.0)
+                )
+            )
+        assertThat(metricValues).containsExactly(NutritionRecord.BIOTIN_TOTAL.metricKey, 88.0)
+    }
+
+    @Test
+    fun getDoubleMetricValues_convertsPowerToWatts() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    PowerRecord.POWER_AVG as AggregateMetric<Any> to PlatformPower.fromWatts(366.0)
+                )
+            )
+        assertThat(metricValues).containsExactly(PowerRecord.POWER_AVG.metricKey, 366.0)
+    }
+
+    @Test
+    fun getDoubleMetricValues_convertsVolumeToLiters() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    HydrationRecord.VOLUME_TOTAL as AggregateMetric<Any> to
+                        PlatformVolume.fromLiters(1.5)
+                )
+            )
+        assertThat(metricValues).containsExactly(HydrationRecord.VOLUME_TOTAL.metricKey, 1.5)
+    }
+
+    @Test
+    fun getDoubleMetricValues_ignoresNonDoubleMetricTypes() {
+        val metricValues =
+            getDoubleMetricValues(mapOf(HeartRateRecord.BPM_MIN as AggregateMetric<Any> to 53L))
+        assertThat(metricValues).isEmpty()
+    }
+
+    @Test
+    fun getLongMetricValues_handlesMultipleMetrics() {
+        val metricValues =
+            getLongMetricValues(
+                mapOf(
+                    HeartRateRecord.BPM_MIN as AggregateMetric<Any> to 53L,
+                    ExerciseSessionRecord.EXERCISE_DURATION_TOTAL as AggregateMetric<Any> to
+                        60_000L,
+                    NutritionRecord.ENERGY_TOTAL as AggregateMetric<Any> to
+                        PlatformEnergy.fromCalories(418_400.0),
+                    DistanceRecord.DISTANCE_TOTAL as AggregateMetric<Any> to
+                        PlatformLength.fromMeters(50.0),
+                    NutritionRecord.BIOTIN_TOTAL as AggregateMetric<Any> to
+                        PlatformMass.fromGrams(88.0),
+                    PowerRecord.POWER_AVG as AggregateMetric<Any> to PlatformPower.fromWatts(366.0),
+                    HydrationRecord.VOLUME_TOTAL as AggregateMetric<Any> to
+                        PlatformVolume.fromLiters(1.5),
+                    FloorsClimbedRecord.FLOORS_CLIMBED_TOTAL as AggregateMetric<Any> to 10L,
+                    BasalMetabolicRateRecord.BASAL_CALORIES_TOTAL as AggregateMetric<Any> to
+                        PlatformPower.fromWatts(500.0),
+                )
+            )
+        assertThat(metricValues)
+            .containsExactly(
+                HeartRateRecord.BPM_MIN.metricKey,
+                53L,
+                ExerciseSessionRecord.EXERCISE_DURATION_TOTAL.metricKey,
+                60_000L
+            )
+    }
+
+    @Test
+    fun getDoubleMetricValues_handlesMultipleMetrics() {
+        val metricValues =
+            getDoubleMetricValues(
+                mapOf(
+                    HeartRateRecord.BPM_MIN as AggregateMetric<Any> to 53L,
+                    ExerciseSessionRecord.EXERCISE_DURATION_TOTAL as AggregateMetric<Any> to
+                        60_000L,
+                    NutritionRecord.ENERGY_TOTAL as AggregateMetric<Any> to
+                        PlatformEnergy.fromCalories(418_400.0),
+                    DistanceRecord.DISTANCE_TOTAL as AggregateMetric<Any> to
+                        PlatformLength.fromMeters(50.0),
+                    NutritionRecord.BIOTIN_TOTAL as AggregateMetric<Any> to
+                        PlatformMass.fromGrams(88.0),
+                    PowerRecord.POWER_AVG as AggregateMetric<Any> to PlatformPower.fromWatts(366.0),
+                    HydrationRecord.VOLUME_TOTAL as AggregateMetric<Any> to
+                        PlatformVolume.fromLiters(1.5),
+                    FloorsClimbedRecord.FLOORS_CLIMBED_TOTAL as AggregateMetric<Any> to 10.0,
+                    BasalMetabolicRateRecord.BASAL_CALORIES_TOTAL as AggregateMetric<Any> to
+                        PlatformEnergy.fromCalories(836_800.0),
+                )
+            )
+        assertThat(metricValues)
+            .comparingValuesUsing(tolerance)
+            .containsExactly(
+                NutritionRecord.ENERGY_TOTAL.metricKey,
+                418.4,
+                DistanceRecord.DISTANCE_TOTAL.metricKey,
+                50.0,
+                NutritionRecord.BIOTIN_TOTAL.metricKey,
+                88,
+                PowerRecord.POWER_AVG.metricKey,
+                366.0,
+                HydrationRecord.VOLUME_TOTAL.metricKey,
+                1.5,
+                FloorsClimbedRecord.FLOORS_CLIMBED_TOTAL.metricKey,
+                10.0,
+                BasalMetabolicRateRecord.BASAL_CALORIES_TOTAL.metricKey,
+                836.8
+            )
+    }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
index 96f9b86..d70451d 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/HealthConnectClient.kt
@@ -30,6 +30,7 @@
 import androidx.health.connect.client.aggregate.AggregationResultGroupedByDuration
 import androidx.health.connect.client.aggregate.AggregationResultGroupedByPeriod
 import androidx.health.connect.client.impl.HealthConnectClientImpl
+import androidx.health.connect.client.impl.HealthConnectClientUpsideDownImpl
 import androidx.health.connect.client.records.Record
 import androidx.health.connect.client.records.metadata.DataOrigin
 import androidx.health.connect.client.request.AggregateGroupByDurationRequest
@@ -312,7 +313,11 @@
         internal const val DEFAULT_PROVIDER_PACKAGE_NAME = "com.google.android.apps.healthdata"
 
         @RestrictTo(RestrictTo.Scope.LIBRARY)
-        internal const val DEFAULT_PROVIDER_MIN_VERSION_CODE = 35000
+        internal const val DEFAULT_PROVIDER_MIN_VERSION_CODE = 68623
+
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        const val ACTION_HEALTH_CONNECT_SETTINGS_LEGACY =
+            "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
 
         /**
          * Intent action to open Health Connect settings on this phone. Developers should use this
@@ -320,7 +325,10 @@
          */
         @get:JvmName("getHealthConnectSettingsAction")
         @JvmStatic
-        val ACTION_HEALTH_CONNECT_SETTINGS = "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
+        val ACTION_HEALTH_CONNECT_SETTINGS =
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+                "android.health.connect.action.HEALTH_HOME_SETTINGS"
+            else "androidx.health.ACTION_HEALTH_CONNECT_SETTINGS"
 
         /**
          * The Health Connect SDK is not unavailable on this device at the time. This can be due to
@@ -372,51 +380,32 @@
             context: Context,
             providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
         ): Int {
-            @Suppress("Deprecation")
-            if (!isApiSupported()) {
+            if (!isSdkVersionSufficient()) {
                 return SDK_UNAVAILABLE
             }
-            @Suppress("Deprecation")
             if (!isProviderAvailable(context, providerPackageName)) {
                 return SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED
             }
             return SDK_AVAILABLE
         }
 
-        /**
-         * Determines whether the current Health Connect SDK is supported on this device. If it is
-         * not supported, then installing any provider will not help - instead disable the
-         * integration.
-         *
-         * @return whether the api is supported on the device.
-         */
-        @JvmStatic
-        @Deprecated("use sdkStatus()", ReplaceWith("sdkStatus(context)"))
-        public fun isApiSupported(): Boolean {
-            return isSdkVersionSufficient()
-        }
-
-        /**
-         * Determines whether an implementation of [HealthConnectClient] is available on this device
-         * at the moment. If none is available, apps may choose to redirect to package installers to
-         * find suitable providers.
-         *
-         * @param context the context
-         * @param providerPackageName optional package provider to choose for backend implementation
-         * @return whether the api is available
-         */
         @JvmOverloads
         @JvmStatic
-        @Deprecated("use sdkStatus()", ReplaceWith("sdkStatus(context)"))
-        public fun isProviderAvailable(
+        @AvailabilityStatus
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        fun getSdkStatusLegacy(
             context: Context,
             providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
-        ): Boolean {
+        ): Int {
             @Suppress("Deprecation")
-            if (!isApiSupported()) {
-                return false
+            if (!isSdkVersionSufficient()) {
+                return SDK_UNAVAILABLE
             }
-            return isPackageInstalled(context.packageManager, providerPackageName)
+            @Suppress("Deprecation")
+            if (!isProviderAvailableLegacy(context, providerPackageName)) {
+                return SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED
+            }
+            return SDK_AVAILABLE
         }
 
         /**
@@ -437,12 +426,34 @@
             context: Context,
             providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
         ): HealthConnectClient {
-            @Suppress("Deprecation")
-            if (!isApiSupported()) {
+            val status = getSdkStatus(context, providerPackageName)
+            if (status == SDK_UNAVAILABLE) {
                 throw UnsupportedOperationException("SDK version too low")
             }
-            @Suppress("Deprecation")
-            if (!isProviderAvailable(context, providerPackageName)) {
+            if (status == SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
+                throw IllegalStateException("Service not available")
+            }
+
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                return HealthConnectClientUpsideDownImpl(context)
+            }
+            return HealthConnectClientImpl(
+                HealthDataService.getClient(context, providerPackageName)
+            )
+        }
+
+        @JvmOverloads
+        @JvmStatic
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        fun getOrCreateLegacy(
+            context: Context,
+            providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
+        ): HealthConnectClient {
+            val status = getSdkStatusLegacy(context, providerPackageName)
+            if (status == SDK_UNAVAILABLE) {
+                throw UnsupportedOperationException("SDK version too low")
+            }
+            if (status == SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
                 throw IllegalStateException("Service not available")
             }
             return HealthConnectClientImpl(
@@ -453,7 +464,28 @@
         @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.P)
         internal fun isSdkVersionSufficient() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P
 
-        internal fun isPackageInstalled(
+        /**
+         * Determines whether an implementation of [HealthConnectClient] is available on this device
+         * at the moment.
+         */
+        internal fun isProviderAvailable(
+            context: Context,
+            providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
+        ): Boolean {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                return true
+            }
+            return isPackageInstalled(context.packageManager, providerPackageName)
+        }
+
+        internal fun isProviderAvailableLegacy(
+            context: Context,
+            providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME,
+        ): Boolean {
+            return isPackageInstalled(context.packageManager, providerPackageName)
+        }
+
+        private fun isPackageInstalled(
             packageManager: PackageManager,
             packageName: String,
         ): Boolean {
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/PermissionController.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/PermissionController.kt
index 1be95806..18ebf35 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/PermissionController.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/PermissionController.kt
@@ -15,10 +15,13 @@
  */
 package androidx.health.connect.client
 
+import android.os.Build
 import androidx.activity.result.contract.ActivityResultContract
+import androidx.annotation.RestrictTo
 import androidx.health.connect.client.HealthConnectClient.Companion.DEFAULT_PROVIDER_PACKAGE_NAME
 import androidx.health.connect.client.permission.HealthDataRequestPermissionsInternal
 import androidx.health.connect.client.permission.HealthPermission
+import androidx.health.connect.client.permission.platform.HealthDataRequestPermissionsUpsideDownCake
 
 @JvmDefaultWithCompatibility
 /** Interface for operations related to permissions. */
@@ -45,6 +48,16 @@
     suspend fun revokeAllPermissions()
 
     companion object {
+
+        @JvmStatic
+        @JvmOverloads
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        fun createRequestPermissionResultContractLegacy(
+            providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME
+        ): ActivityResultContract<Set<String>, Set<String>> {
+            return HealthDataRequestPermissionsInternal(providerPackageName = providerPackageName)
+        }
+
         /**
          * Creates an [ActivityResultContract] to request Health permissions.
          *
@@ -58,6 +71,9 @@
         fun createRequestPermissionResultContract(
             providerPackageName: String = DEFAULT_PROVIDER_PACKAGE_NAME
         ): ActivityResultContract<Set<String>, Set<String>> {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                return HealthDataRequestPermissionsUpsideDownCake()
+            }
             return HealthDataRequestPermissionsInternal(providerPackageName = providerPackageName)
         }
     }
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImpl.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImpl.kt
new file mode 100644
index 0000000..8c2d24c
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/HealthConnectClientUpsideDownImpl.kt
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.health.connect.client.impl
+
+import android.content.Context
+import android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED
+import android.content.pm.PackageManager.GET_PERMISSIONS
+import android.content.pm.PackageManager.PackageInfoFlags
+import android.health.connect.HealthConnectException
+import android.health.connect.HealthConnectManager
+import android.health.connect.ReadRecordsRequestUsingIds
+import android.health.connect.RecordIdFilter
+import android.health.connect.changelog.ChangeLogsRequest
+import android.os.RemoteException
+import androidx.annotation.RequiresApi
+import androidx.annotation.VisibleForTesting
+import androidx.core.os.asOutcomeReceiver
+import androidx.health.connect.client.HealthConnectClient
+import androidx.health.connect.client.PermissionController
+import androidx.health.connect.client.aggregate.AggregationResult
+import androidx.health.connect.client.aggregate.AggregationResultGroupedByDuration
+import androidx.health.connect.client.aggregate.AggregationResultGroupedByPeriod
+import androidx.health.connect.client.changes.DeletionChange
+import androidx.health.connect.client.changes.UpsertionChange
+import androidx.health.connect.client.impl.platform.records.toPlatformRecord
+import androidx.health.connect.client.impl.platform.records.toPlatformRecordClass
+import androidx.health.connect.client.impl.platform.records.toPlatformRequest
+import androidx.health.connect.client.impl.platform.records.toPlatformTimeRangeFilter
+import androidx.health.connect.client.impl.platform.records.toSdkRecord
+import androidx.health.connect.client.impl.platform.records.toSdkResponse
+import androidx.health.connect.client.impl.platform.response.toKtResponse
+import androidx.health.connect.client.impl.platform.toKtException
+import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_PREFIX
+import androidx.health.connect.client.records.Record
+import androidx.health.connect.client.request.AggregateGroupByDurationRequest
+import androidx.health.connect.client.request.AggregateGroupByPeriodRequest
+import androidx.health.connect.client.request.AggregateRequest
+import androidx.health.connect.client.request.ChangesTokenRequest
+import androidx.health.connect.client.request.ReadRecordsRequest
+import androidx.health.connect.client.response.ChangesResponse
+import androidx.health.connect.client.response.InsertRecordsResponse
+import androidx.health.connect.client.response.ReadRecordResponse
+import androidx.health.connect.client.response.ReadRecordsResponse
+import androidx.health.connect.client.time.TimeRangeFilter
+import kotlin.reflect.KClass
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+/**
+ * Implements the [HealthConnectClient] with APIs in UpsideDownCake.
+ *
+ * @suppress
+ */
+@RequiresApi(api = 34)
+class HealthConnectClientUpsideDownImpl : HealthConnectClient, PermissionController {
+
+    private val executor = Dispatchers.Default.asExecutor()
+
+    private val context: Context
+    private val healthConnectManager: HealthConnectManager
+    private val revokePermissionsFunction: (Collection<String>) -> Unit
+
+    constructor(context: Context) : this(context, context::revokeSelfPermissionsOnKill)
+
+    @VisibleForTesting
+    internal constructor(
+        context: Context,
+        revokePermissionsFunction: (Collection<String>) -> Unit
+    ) {
+        this.context = context
+        this.healthConnectManager =
+            context.getSystemService(Context.HEALTHCONNECT_SERVICE) as HealthConnectManager
+        this.revokePermissionsFunction = revokePermissionsFunction
+    }
+
+    override val permissionController: PermissionController
+        get() = this
+
+    override suspend fun insertRecords(records: List<Record>): InsertRecordsResponse {
+        val response = wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.insertRecords(
+                    records.map { it.toPlatformRecord() },
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+        return response.toKtResponse()
+    }
+
+    override suspend fun updateRecords(records: List<Record>) {
+        wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.updateRecords(
+                    records.map { it.toPlatformRecord() },
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+    }
+
+    override suspend fun deleteRecords(
+        recordType: KClass<out Record>,
+        recordIdsList: List<String>,
+        clientRecordIdsList: List<String>
+    ) {
+        wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.deleteRecords(
+                    buildList {
+                        recordIdsList.forEach {
+                            add(RecordIdFilter.fromId(recordType.toPlatformRecordClass(), it))
+                        }
+                        clientRecordIdsList.forEach {
+                            add(
+                                RecordIdFilter.fromClientRecordId(
+                                    recordType.toPlatformRecordClass(),
+                                    it
+                                )
+                            )
+                        }
+                    },
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+    }
+
+    override suspend fun deleteRecords(
+        recordType: KClass<out Record>,
+        timeRangeFilter: TimeRangeFilter
+    ) {
+        wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.deleteRecords(
+                    recordType.toPlatformRecordClass(),
+                    timeRangeFilter.toPlatformTimeRangeFilter(),
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+    }
+
+    @Suppress("UNCHECKED_CAST") // Safe to cast as the type should match
+    override suspend fun <T : Record> readRecord(
+        recordType: KClass<T>,
+        recordId: String
+    ): ReadRecordResponse<T> {
+        val response = wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.readRecords(
+                    ReadRecordsRequestUsingIds.Builder(recordType.toPlatformRecordClass())
+                        .addId(recordId)
+                        .build(),
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+        if (response.records.isEmpty()) {
+            throw RemoteException("No records")
+        }
+        return ReadRecordResponse(response.records[0].toSdkRecord() as T)
+    }
+
+    @Suppress("UNCHECKED_CAST") // Safe to cast as the type should match
+    override suspend fun <T : Record> readRecords(
+        request: ReadRecordsRequest<T>
+    ): ReadRecordsResponse<T> {
+        val response = wrapPlatformException {
+            suspendCancellableCoroutine { continuation ->
+                healthConnectManager.readRecords(
+                    request.toPlatformRequest(),
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+        }
+        return ReadRecordsResponse(
+            response.records.map { it.toSdkRecord() as T },
+            pageToken = response.nextPageToken.takeUnless { it == -1L }?.toString()
+        )
+    }
+
+    override suspend fun aggregate(request: AggregateRequest): AggregationResult {
+        return wrapPlatformException {
+                suspendCancellableCoroutine { continuation ->
+                    healthConnectManager.aggregate(
+                        request.toPlatformRequest(),
+                        executor,
+                        continuation.asOutcomeReceiver()
+                    )
+                }
+            }
+            .toSdkResponse(request.metrics)
+    }
+
+    override suspend fun aggregateGroupByDuration(
+        request: AggregateGroupByDurationRequest
+    ): List<AggregationResultGroupedByDuration> {
+        return wrapPlatformException {
+                suspendCancellableCoroutine { continuation ->
+                    healthConnectManager.aggregateGroupByDuration(
+                        request.toPlatformRequest(),
+                        request.timeRangeSlicer,
+                        executor,
+                        continuation.asOutcomeReceiver()
+                    )
+                }
+            }
+            .map { it.toSdkResponse(request.metrics) }
+    }
+
+    override suspend fun aggregateGroupByPeriod(
+        request: AggregateGroupByPeriodRequest
+    ): List<AggregationResultGroupedByPeriod> {
+        return wrapPlatformException {
+                suspendCancellableCoroutine { continuation ->
+                    healthConnectManager.aggregateGroupByPeriod(
+                        request.toPlatformRequest(),
+                        request.timeRangeSlicer,
+                        executor,
+                        continuation.asOutcomeReceiver()
+                    )
+                }
+            }
+            .map { it.toSdkResponse(request.metrics) }
+    }
+
+    override suspend fun getChangesToken(request: ChangesTokenRequest): String {
+        return wrapPlatformException {
+                suspendCancellableCoroutine { continuation ->
+                    healthConnectManager.getChangeLogToken(
+                        request.toPlatformRequest(),
+                        executor,
+                        continuation.asOutcomeReceiver()
+                    )
+                }
+            }
+            .token
+    }
+
+    override suspend fun getChanges(changesToken: String): ChangesResponse {
+        try {
+            val response = suspendCancellableCoroutine { continuation ->
+                healthConnectManager.getChangeLogs(
+                    ChangeLogsRequest.Builder(changesToken).build(),
+                    executor,
+                    continuation.asOutcomeReceiver()
+                )
+            }
+            return ChangesResponse(
+                buildList {
+                    response.upsertedRecords.forEach { add(UpsertionChange(it.toSdkRecord())) }
+                    response.deletedLogs.forEach { add(DeletionChange(it.deletedRecordId)) }
+                },
+                response.nextChangesToken,
+                response.hasMorePages(),
+                changesTokenExpired = false
+            )
+        } catch (e: HealthConnectException) {
+            // Handle invalid token
+            if (e.errorCode == HealthConnectException.ERROR_INVALID_ARGUMENT) {
+                return ChangesResponse(
+                    changes = listOf(),
+                    nextChangesToken = "",
+                    hasMore = false,
+                    changesTokenExpired = true
+                )
+            }
+            throw e.toKtException()
+        }
+    }
+
+    override suspend fun getGrantedPermissions(): Set<String> {
+        context.packageManager
+            .getPackageInfo(context.packageName, PackageInfoFlags.of(GET_PERMISSIONS.toLong()))
+            .let {
+                return buildSet {
+                    for (i in it.requestedPermissions.indices) {
+                        if (
+                            it.requestedPermissions[i].startsWith(PERMISSION_PREFIX) &&
+                                it.requestedPermissionsFlags[i] and REQUESTED_PERMISSION_GRANTED > 0
+                        ) {
+                            add(it.requestedPermissions[i])
+                        }
+                    }
+                }
+            }
+    }
+
+    override suspend fun revokeAllPermissions() {
+        val allHealthPermissions =
+            context.packageManager
+                .getPackageInfo(context.packageName, PackageInfoFlags.of(GET_PERMISSIONS.toLong()))
+                .requestedPermissions
+                .filter { it.startsWith(PERMISSION_PREFIX) }
+        revokePermissionsFunction(allHealthPermissions)
+    }
+
+    private suspend fun <T> wrapPlatformException(function: suspend () -> T): T {
+        return try {
+            function()
+        } catch (e: HealthConnectException) {
+            throw e.toKtException()
+        }
+    }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/ExceptionConverter.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/ExceptionConverter.kt
new file mode 100644
index 0000000..be40e96
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/ExceptionConverter.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform
+
+import android.health.connect.HealthConnectException
+import android.os.RemoteException
+import androidx.annotation.RequiresApi
+import java.io.IOException
+import java.lang.IllegalArgumentException
+import java.lang.IllegalStateException
+
+/** Converts exception returned by the platform to one of standard exception class hierarchy. */
+internal fun HealthConnectException.toKtException(): Exception {
+    return when (errorCode) {
+        HealthConnectException.ERROR_IO -> IOException(message)
+        HealthConnectException.ERROR_REMOTE -> RemoteException(message)
+        HealthConnectException.ERROR_SECURITY -> SecurityException(message)
+        HealthConnectException.ERROR_INVALID_ARGUMENT -> IllegalArgumentException(message)
+        else -> IllegalStateException(message)
+    }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/package-info.java b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/package-info.java
new file mode 100644
index 0000000..664796d
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Helps with conversions to the platform record and API objects.
+ * @exportToFramework:hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+package androidx.health.connect.client.impl.platform;
+
+import androidx.annotation.RestrictTo;
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/AggregationMappings.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/AggregationMappings.kt
new file mode 100644
index 0000000..42d97d3
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/AggregationMappings.kt
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.health.connect.datatypes.ActiveCaloriesBurnedRecord as PlatformActiveCaloriesBurnedRecord
+import android.health.connect.datatypes.AggregationType as PlatformAggregateMetric
+import android.health.connect.datatypes.BasalMetabolicRateRecord as PlatformBasalMetabolicRateRecord
+import android.health.connect.datatypes.DistanceRecord as PlatformDistanceRecord
+import android.health.connect.datatypes.ElevationGainedRecord as PlatformElevationGainedRecord
+import android.health.connect.datatypes.FloorsClimbedRecord as PlatformFloorsClimbedRecord
+import android.health.connect.datatypes.HeartRateRecord as PlatformHeartRateRecord
+import android.health.connect.datatypes.HeightRecord as PlatformHeightRecord
+import android.health.connect.datatypes.HydrationRecord as PlatformHydrationRecord
+import android.health.connect.datatypes.NutritionRecord as PlatformNutritionRecord
+import android.health.connect.datatypes.PowerRecord as PlatformPowerRecord
+import android.health.connect.datatypes.StepsRecord as PlatformStepsRecord
+import android.health.connect.datatypes.TotalCaloriesBurnedRecord as PlatformTotalCaloriesBurnedRecord
+import android.health.connect.datatypes.WeightRecord as PlatformWeightRecord
+import android.health.connect.datatypes.WheelchairPushesRecord as PlatformWheelchairPushesRecord
+import android.health.connect.datatypes.units.Energy as PlatformEnergy
+import android.health.connect.datatypes.units.Length as PlatformLength
+import android.health.connect.datatypes.units.Mass as PlatformMass
+import android.health.connect.datatypes.units.Power as PlatformPower
+import android.health.connect.datatypes.units.Volume as PlatformVolume
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.records.ActiveCaloriesBurnedRecord
+import androidx.health.connect.client.records.BasalMetabolicRateRecord
+import androidx.health.connect.client.records.DistanceRecord
+import androidx.health.connect.client.records.ElevationGainedRecord
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.FloorsClimbedRecord
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.HeightRecord
+import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.RestingHeartRateRecord
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.TotalCaloriesBurnedRecord
+import androidx.health.connect.client.records.WeightRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import androidx.health.connect.client.units.Energy
+import androidx.health.connect.client.units.Length
+import androidx.health.connect.client.units.Mass
+import androidx.health.connect.client.units.Power
+import androidx.health.connect.client.units.Volume
+import java.time.Duration
+
+internal val DOUBLE_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Double>, PlatformAggregateMetric<Double>> =
+    mapOf(
+        FloorsClimbedRecord.FLOORS_CLIMBED_TOTAL to
+            PlatformFloorsClimbedRecord.FLOORS_CLIMBED_TOTAL,
+    )
+
+internal val DURATION_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Duration>, PlatformAggregateMetric<Long>> =
+    mapOf(
+        ExerciseSessionRecord.EXERCISE_DURATION_TOTAL to
+            PlatformExerciseSessionRecord.EXERCISE_DURATION_TOTAL,
+        SleepSessionRecord.SLEEP_DURATION_TOTAL to PlatformSleepSessionRecord.SLEEP_DURATION_TOTAL
+    )
+
+internal val ENERGY_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Energy>, PlatformAggregateMetric<PlatformEnergy>> =
+    mapOf(
+        ActiveCaloriesBurnedRecord.ACTIVE_CALORIES_TOTAL to
+            PlatformActiveCaloriesBurnedRecord.ACTIVE_CALORIES_TOTAL,
+        BasalMetabolicRateRecord.BASAL_CALORIES_TOTAL to
+            PlatformBasalMetabolicRateRecord.BASAL_CALORIES_TOTAL,
+        NutritionRecord.ENERGY_TOTAL to PlatformNutritionRecord.ENERGY_TOTAL,
+        NutritionRecord.ENERGY_FROM_FAT_TOTAL to PlatformNutritionRecord.ENERGY_FROM_FAT_TOTAL,
+        TotalCaloriesBurnedRecord.ENERGY_TOTAL to PlatformTotalCaloriesBurnedRecord.ENERGY_TOTAL,
+    )
+
+internal val LENGTH_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Length>, PlatformAggregateMetric<PlatformLength>> =
+    mapOf(
+        DistanceRecord.DISTANCE_TOTAL to PlatformDistanceRecord.DISTANCE_TOTAL,
+        ElevationGainedRecord.ELEVATION_GAINED_TOTAL to
+            PlatformElevationGainedRecord.ELEVATION_GAINED_TOTAL,
+        HeightRecord.HEIGHT_AVG to PlatformHeightRecord.HEIGHT_AVG,
+        HeightRecord.HEIGHT_MIN to PlatformHeightRecord.HEIGHT_MIN,
+        HeightRecord.HEIGHT_MAX to PlatformHeightRecord.HEIGHT_MAX,
+    )
+
+internal val LONG_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Long>, PlatformAggregateMetric<Long>> =
+    mapOf(
+        HeartRateRecord.BPM_AVG to PlatformHeartRateRecord.BPM_AVG,
+        HeartRateRecord.BPM_MIN to PlatformHeartRateRecord.BPM_MIN,
+        HeartRateRecord.BPM_MAX to PlatformHeartRateRecord.BPM_MAX,
+        HeartRateRecord.MEASUREMENTS_COUNT to PlatformHeartRateRecord.HEART_MEASUREMENTS_COUNT,
+        RestingHeartRateRecord.BPM_AVG to PlatformRestingHeartRateRecord.BPM_AVG,
+        RestingHeartRateRecord.BPM_MIN to PlatformRestingHeartRateRecord.BPM_MIN,
+        RestingHeartRateRecord.BPM_MAX to PlatformRestingHeartRateRecord.BPM_MAX,
+        StepsRecord.COUNT_TOTAL to PlatformStepsRecord.STEPS_COUNT_TOTAL,
+        WheelchairPushesRecord.COUNT_TOTAL to
+            PlatformWheelchairPushesRecord.WHEEL_CHAIR_PUSHES_COUNT_TOTAL,
+    )
+
+internal val GRAMS_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Mass>, PlatformAggregateMetric<PlatformMass>> =
+    mapOf(
+        NutritionRecord.BIOTIN_TOTAL to PlatformNutritionRecord.BIOTIN_TOTAL,
+        NutritionRecord.CAFFEINE_TOTAL to PlatformNutritionRecord.CAFFEINE_TOTAL,
+        NutritionRecord.CALCIUM_TOTAL to PlatformNutritionRecord.CALCIUM_TOTAL,
+        NutritionRecord.CHLORIDE_TOTAL to PlatformNutritionRecord.CHLORIDE_TOTAL,
+        NutritionRecord.CHOLESTEROL_TOTAL to PlatformNutritionRecord.CHOLESTEROL_TOTAL,
+        NutritionRecord.CHROMIUM_TOTAL to PlatformNutritionRecord.CHROMIUM_TOTAL,
+        NutritionRecord.COPPER_TOTAL to PlatformNutritionRecord.COPPER_TOTAL,
+        NutritionRecord.DIETARY_FIBER_TOTAL to PlatformNutritionRecord.DIETARY_FIBER_TOTAL,
+        NutritionRecord.FOLATE_TOTAL to PlatformNutritionRecord.FOLATE_TOTAL,
+        NutritionRecord.FOLIC_ACID_TOTAL to PlatformNutritionRecord.FOLIC_ACID_TOTAL,
+        NutritionRecord.IODINE_TOTAL to PlatformNutritionRecord.IODINE_TOTAL,
+        NutritionRecord.IRON_TOTAL to PlatformNutritionRecord.IRON_TOTAL,
+        NutritionRecord.MAGNESIUM_TOTAL to PlatformNutritionRecord.MAGNESIUM_TOTAL,
+        NutritionRecord.MANGANESE_TOTAL to PlatformNutritionRecord.MANGANESE_TOTAL,
+        NutritionRecord.MOLYBDENUM_TOTAL to PlatformNutritionRecord.MOLYBDENUM_TOTAL,
+        NutritionRecord.MONOUNSATURATED_FAT_TOTAL to
+            PlatformNutritionRecord.MONOUNSATURATED_FAT_TOTAL,
+        NutritionRecord.NIACIN_TOTAL to PlatformNutritionRecord.NIACIN_TOTAL,
+        NutritionRecord.PANTOTHENIC_ACID_TOTAL to PlatformNutritionRecord.PANTOTHENIC_ACID_TOTAL,
+        NutritionRecord.PHOSPHORUS_TOTAL to PlatformNutritionRecord.PHOSPHORUS_TOTAL,
+        NutritionRecord.POLYUNSATURATED_FAT_TOTAL to
+            PlatformNutritionRecord.POLYUNSATURATED_FAT_TOTAL,
+        NutritionRecord.POTASSIUM_TOTAL to PlatformNutritionRecord.POTASSIUM_TOTAL,
+        NutritionRecord.PROTEIN_TOTAL to PlatformNutritionRecord.PROTEIN_TOTAL,
+        NutritionRecord.RIBOFLAVIN_TOTAL to PlatformNutritionRecord.RIBOFLAVIN_TOTAL,
+        NutritionRecord.SATURATED_FAT_TOTAL to PlatformNutritionRecord.SATURATED_FAT_TOTAL,
+        NutritionRecord.SELENIUM_TOTAL to PlatformNutritionRecord.SELENIUM_TOTAL,
+        NutritionRecord.SODIUM_TOTAL to PlatformNutritionRecord.SODIUM_TOTAL,
+        NutritionRecord.SUGAR_TOTAL to PlatformNutritionRecord.SUGAR_TOTAL,
+        NutritionRecord.THIAMIN_TOTAL to PlatformNutritionRecord.THIAMIN_TOTAL,
+        NutritionRecord.TOTAL_CARBOHYDRATE_TOTAL to
+            PlatformNutritionRecord.TOTAL_CARBOHYDRATE_TOTAL,
+        NutritionRecord.TOTAL_FAT_TOTAL to PlatformNutritionRecord.TOTAL_FAT_TOTAL,
+        NutritionRecord.UNSATURATED_FAT_TOTAL to PlatformNutritionRecord.UNSATURATED_FAT_TOTAL,
+        NutritionRecord.VITAMIN_A_TOTAL to PlatformNutritionRecord.VITAMIN_A_TOTAL,
+        NutritionRecord.VITAMIN_B12_TOTAL to PlatformNutritionRecord.VITAMIN_B12_TOTAL,
+        NutritionRecord.VITAMIN_B6_TOTAL to PlatformNutritionRecord.VITAMIN_B6_TOTAL,
+        NutritionRecord.VITAMIN_C_TOTAL to PlatformNutritionRecord.VITAMIN_C_TOTAL,
+        NutritionRecord.VITAMIN_D_TOTAL to PlatformNutritionRecord.VITAMIN_D_TOTAL,
+        NutritionRecord.VITAMIN_E_TOTAL to PlatformNutritionRecord.VITAMIN_E_TOTAL,
+        NutritionRecord.VITAMIN_K_TOTAL to PlatformNutritionRecord.VITAMIN_K_TOTAL,
+        NutritionRecord.ZINC_TOTAL to PlatformNutritionRecord.ZINC_TOTAL
+    )
+
+internal val KILOGRAMS_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Mass>, PlatformAggregateMetric<PlatformMass>> =
+    mapOf(
+        WeightRecord.WEIGHT_AVG to PlatformWeightRecord.WEIGHT_AVG,
+        WeightRecord.WEIGHT_MIN to PlatformWeightRecord.WEIGHT_MIN,
+        WeightRecord.WEIGHT_MAX to PlatformWeightRecord.WEIGHT_MAX,
+    )
+
+internal val POWER_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Power>, PlatformAggregateMetric<PlatformPower>> =
+    mapOf(
+        PowerRecord.POWER_AVG to PlatformPowerRecord.POWER_AVG,
+        PowerRecord.POWER_MAX to PlatformPowerRecord.POWER_MAX,
+        PowerRecord.POWER_MIN to PlatformPowerRecord.POWER_MIN,
+    )
+
+internal val VOLUME_AGGREGATION_METRIC_TYPE_MAP:
+    Map<AggregateMetric<Volume>, PlatformAggregateMetric<PlatformVolume>> =
+    mapOf(
+        HydrationRecord.VOLUME_TOTAL to PlatformHydrationRecord.VOLUME_TOTAL,
+    )
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/IntDefMappings.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/IntDefMappings.kt
new file mode 100644
index 0000000..0ad31b2
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/IntDefMappings.kt
@@ -0,0 +1,662 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.records.BloodGlucoseRecord
+import androidx.health.connect.client.records.BloodPressureRecord
+import androidx.health.connect.client.records.BodyTemperatureMeasurementLocation
+import androidx.health.connect.client.records.CervicalMucusRecord
+import androidx.health.connect.client.records.ExerciseSegment
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.MealType
+import androidx.health.connect.client.records.MenstruationFlowRecord
+import androidx.health.connect.client.records.OvulationTestRecord
+import androidx.health.connect.client.records.SexualActivityRecord
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.Vo2MaxRecord
+import androidx.health.connect.client.records.metadata.Metadata
+
+internal val SDK_TO_PLATFORM_CERVICAL_MUCUS_APPEARANCE: Map<Int, Int> =
+    mapOf(
+        CervicalMucusRecord.APPEARANCE_EGG_WHITE to
+            PlatformCervicalMucusAppearance.APPEARANCE_EGG_WHITE,
+        CervicalMucusRecord.APPEARANCE_DRY to PlatformCervicalMucusAppearance.APPEARANCE_DRY,
+        CervicalMucusRecord.APPEARANCE_STICKY to PlatformCervicalMucusAppearance.APPEARANCE_STICKY,
+        CervicalMucusRecord.APPEARANCE_CREAMY to PlatformCervicalMucusAppearance.APPEARANCE_CREAMY,
+        CervicalMucusRecord.APPEARANCE_WATERY to PlatformCervicalMucusAppearance.APPEARANCE_WATERY,
+        CervicalMucusRecord.APPEARANCE_UNUSUAL to
+            PlatformCervicalMucusAppearance.APPEARANCE_UNUSUAL,
+    )
+
+internal val PLATFORM_TO_SDK_CERVICAL_MUCUS_APPEARANCE =
+    SDK_TO_PLATFORM_CERVICAL_MUCUS_APPEARANCE.reversed()
+
+internal val SDK_TO_PLATFORM_BLOOD_PRESSURE_BODY_POSITION: Map<Int, Int> =
+    mapOf(
+        BloodPressureRecord.BODY_POSITION_STANDING_UP to
+            PlatformBloodPressureBodyPosition.BODY_POSITION_STANDING_UP,
+        BloodPressureRecord.BODY_POSITION_SITTING_DOWN to
+            PlatformBloodPressureBodyPosition.BODY_POSITION_SITTING_DOWN,
+        BloodPressureRecord.BODY_POSITION_LYING_DOWN to
+            PlatformBloodPressureBodyPosition.BODY_POSITION_LYING_DOWN,
+        BloodPressureRecord.BODY_POSITION_RECLINING to
+            PlatformBloodPressureBodyPosition.BODY_POSITION_RECLINING,
+    )
+
+internal val PLATFORM_TO_SDK_BLOOD_PRESSURE_BODY_POSITION =
+    SDK_TO_PLATFORM_BLOOD_PRESSURE_BODY_POSITION.reversed()
+
+internal val SDK_TO_PLATFORM_EXERCISE_SESSION_TYPE: Map<Int, Int> =
+    mapOf(
+        ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_OTHER_WORKOUT,
+        ExerciseSessionRecord.EXERCISE_TYPE_BADMINTON to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BADMINTON,
+        ExerciseSessionRecord.EXERCISE_TYPE_BASEBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BASEBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_BASKETBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BASKETBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_BIKING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BIKING,
+        ExerciseSessionRecord.EXERCISE_TYPE_BIKING_STATIONARY to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BIKING_STATIONARY,
+        ExerciseSessionRecord.EXERCISE_TYPE_BOOT_CAMP to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BOOT_CAMP,
+        ExerciseSessionRecord.EXERCISE_TYPE_BOXING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_BOXING,
+        ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_CALISTHENICS,
+        ExerciseSessionRecord.EXERCISE_TYPE_CRICKET to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_CRICKET,
+        ExerciseSessionRecord.EXERCISE_TYPE_DANCING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_DANCING,
+        ExerciseSessionRecord.EXERCISE_TYPE_ELLIPTICAL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ELLIPTICAL,
+        ExerciseSessionRecord.EXERCISE_TYPE_EXERCISE_CLASS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_EXERCISE_CLASS,
+        ExerciseSessionRecord.EXERCISE_TYPE_FENCING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_FENCING,
+        ExerciseSessionRecord.EXERCISE_TYPE_FOOTBALL_AMERICAN to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_FOOTBALL_AMERICAN,
+        ExerciseSessionRecord.EXERCISE_TYPE_FOOTBALL_AUSTRALIAN to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_FOOTBALL_AUSTRALIAN,
+        ExerciseSessionRecord.EXERCISE_TYPE_FRISBEE_DISC to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_FRISBEE_DISC,
+        ExerciseSessionRecord.EXERCISE_TYPE_GOLF to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_GOLF,
+        ExerciseSessionRecord.EXERCISE_TYPE_GUIDED_BREATHING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_GUIDED_BREATHING,
+        ExerciseSessionRecord.EXERCISE_TYPE_GYMNASTICS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_GYMNASTICS,
+        ExerciseSessionRecord.EXERCISE_TYPE_HANDBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_HANDBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+        ExerciseSessionRecord.EXERCISE_TYPE_HIKING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_HIKING,
+        ExerciseSessionRecord.EXERCISE_TYPE_ICE_HOCKEY to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ICE_HOCKEY,
+        ExerciseSessionRecord.EXERCISE_TYPE_ICE_SKATING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ICE_SKATING,
+        ExerciseSessionRecord.EXERCISE_TYPE_MARTIAL_ARTS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_MARTIAL_ARTS,
+        ExerciseSessionRecord.EXERCISE_TYPE_PADDLING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_PADDLING,
+        ExerciseSessionRecord.EXERCISE_TYPE_PARAGLIDING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_PARAGLIDING,
+        ExerciseSessionRecord.EXERCISE_TYPE_PILATES to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_PILATES,
+        ExerciseSessionRecord.EXERCISE_TYPE_RACQUETBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_RACQUETBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_ROCK_CLIMBING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ROCK_CLIMBING,
+        ExerciseSessionRecord.EXERCISE_TYPE_ROLLER_HOCKEY to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ROLLER_HOCKEY,
+        ExerciseSessionRecord.EXERCISE_TYPE_ROWING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ROWING,
+        ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_ROWING_MACHINE,
+        ExerciseSessionRecord.EXERCISE_TYPE_RUGBY to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_RUGBY,
+        ExerciseSessionRecord.EXERCISE_TYPE_RUNNING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_RUNNING,
+        ExerciseSessionRecord.EXERCISE_TYPE_RUNNING_TREADMILL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_RUNNING_TREADMILL,
+        ExerciseSessionRecord.EXERCISE_TYPE_SAILING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SAILING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SCUBA_DIVING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SCUBA_DIVING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SKATING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SKATING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SKIING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SKIING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SNOWBOARDING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SNOWBOARDING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SNOWSHOEING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SNOWSHOEING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SOCCER to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SOCCER,
+        ExerciseSessionRecord.EXERCISE_TYPE_SOFTBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SOFTBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_SQUASH to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SQUASH,
+        ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_STAIR_CLIMBING,
+        ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING_MACHINE to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_STAIR_CLIMBING_MACHINE,
+        ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_STRENGTH_TRAINING,
+        ExerciseSessionRecord.EXERCISE_TYPE_STRETCHING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_STRETCHING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SURFING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SURFING,
+        ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SWIMMING_OPEN_WATER,
+        ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_SWIMMING_POOL,
+        ExerciseSessionRecord.EXERCISE_TYPE_TABLE_TENNIS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_TABLE_TENNIS,
+        ExerciseSessionRecord.EXERCISE_TYPE_TENNIS to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_TENNIS,
+        ExerciseSessionRecord.EXERCISE_TYPE_VOLLEYBALL to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_VOLLEYBALL,
+        ExerciseSessionRecord.EXERCISE_TYPE_WALKING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_WALKING,
+        ExerciseSessionRecord.EXERCISE_TYPE_WATER_POLO to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_WATER_POLO,
+        ExerciseSessionRecord.EXERCISE_TYPE_WEIGHTLIFTING to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_WEIGHTLIFTING,
+        ExerciseSessionRecord.EXERCISE_TYPE_WHEELCHAIR to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_WHEELCHAIR,
+        ExerciseSessionRecord.EXERCISE_TYPE_YOGA to
+            PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_YOGA,
+    )
+
+internal val PLATFORM_TO_SDK_EXERCISE_SESSION_TYPE =
+    SDK_TO_PLATFORM_EXERCISE_SESSION_TYPE.reversed()
+
+internal val SDK_TO_PLATFORM_MEAL_TYPE: Map<Int, Int> =
+    mapOf(
+        MealType.MEAL_TYPE_BREAKFAST to PlatformMealType.MEAL_TYPE_BREAKFAST,
+        MealType.MEAL_TYPE_LUNCH to PlatformMealType.MEAL_TYPE_LUNCH,
+        MealType.MEAL_TYPE_DINNER to PlatformMealType.MEAL_TYPE_DINNER,
+        MealType.MEAL_TYPE_SNACK to PlatformMealType.MEAL_TYPE_SNACK,
+    )
+
+internal val PLATFORM_TO_SDK_MEAL_TYPE = SDK_TO_PLATFORM_MEAL_TYPE.reversed()
+
+internal val SDK_TO_PLATFORM_VO2_MAX_MEASUREMENT_METHOD: Map<Int, Int> =
+    mapOf(
+        Vo2MaxRecord.MEASUREMENT_METHOD_METABOLIC_CART to
+            PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_METABOLIC_CART,
+        Vo2MaxRecord.MEASUREMENT_METHOD_HEART_RATE_RATIO to
+            PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_HEART_RATE_RATIO,
+        Vo2MaxRecord.MEASUREMENT_METHOD_COOPER_TEST to
+            PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_COOPER_TEST,
+        Vo2MaxRecord.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST to
+            PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_MULTISTAGE_FITNESS_TEST,
+        Vo2MaxRecord.MEASUREMENT_METHOD_ROCKPORT_FITNESS_TEST to
+            PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_ROCKPORT_FITNESS_TEST,
+    )
+
+internal val PLATFORM_TO_SDK_VO2_MAX_MEASUREMENT_METHOD =
+    SDK_TO_PLATFORM_VO2_MAX_MEASUREMENT_METHOD.reversed()
+
+internal val SDK_TO_PLATFORM_MENSTRUATION_FLOW_TYPE: Map<Int, Int> =
+    mapOf(
+        MenstruationFlowRecord.FLOW_LIGHT to PlatformMenstruationFlowType.FLOW_LIGHT,
+        MenstruationFlowRecord.FLOW_MEDIUM to PlatformMenstruationFlowType.FLOW_MEDIUM,
+        MenstruationFlowRecord.FLOW_HEAVY to PlatformMenstruationFlowType.FLOW_HEAVY,
+    )
+
+internal val PLATFORM_TO_SDK_MENSTRUATION_FLOW_TYPE =
+    SDK_TO_PLATFORM_MENSTRUATION_FLOW_TYPE.reversed()
+
+internal val SDK_TO_PLATFORM_BODY_TEMPERATURE_MEASUREMENT_LOCATION: Map<Int, Int> =
+    mapOf(
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_ARMPIT to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_ARMPIT,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FINGER to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FINGER,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FOREHEAD to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_FOREHEAD,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_MOUTH to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_MOUTH,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_RECTUM to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_RECTUM,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_TEMPORAL_ARTERY to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_TEMPORAL_ARTERY,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_TOE to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_TOE,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_EAR to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_EAR,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_WRIST to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_WRIST,
+        BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_VAGINA to
+            PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_VAGINA,
+    )
+
+internal val PLATFORM_TO_SDK_BODY_TEMPERATURE_MEASUREMENT_LOCATION =
+    SDK_TO_PLATFORM_BODY_TEMPERATURE_MEASUREMENT_LOCATION.reversed()
+
+internal val SDK_TO_PLATFORM_BLOOD_PRESSURE_MEASUREMENT_LOCATION: Map<Int, Int> =
+    mapOf(
+        BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_WRIST to
+            PlatformBloodPressureMeasurementLocation.BLOOD_PRESSURE_MEASUREMENT_LOCATION_LEFT_WRIST,
+        BloodPressureRecord.MEASUREMENT_LOCATION_RIGHT_WRIST to
+            PlatformBloodPressureMeasurementLocation
+                .BLOOD_PRESSURE_MEASUREMENT_LOCATION_RIGHT_WRIST,
+        BloodPressureRecord.MEASUREMENT_LOCATION_LEFT_UPPER_ARM to
+            PlatformBloodPressureMeasurementLocation
+                .BLOOD_PRESSURE_MEASUREMENT_LOCATION_LEFT_UPPER_ARM,
+        BloodPressureRecord.MEASUREMENT_LOCATION_RIGHT_UPPER_ARM to
+            PlatformBloodPressureMeasurementLocation
+                .BLOOD_PRESSURE_MEASUREMENT_LOCATION_RIGHT_UPPER_ARM,
+    )
+
+internal val PLATFORM_TO_SDK_BLOOD_PRESSURE_MEASUREMENT_LOCATION =
+    SDK_TO_PLATFORM_BLOOD_PRESSURE_MEASUREMENT_LOCATION.reversed()
+
+internal val SDK_TO_PLATFORM_OVULATION_TEST_RESULT: Map<Int, Int> =
+    mapOf(
+        OvulationTestRecord.RESULT_POSITIVE to PlatformOvulationTestResult.RESULT_POSITIVE,
+        OvulationTestRecord.RESULT_HIGH to PlatformOvulationTestResult.RESULT_HIGH,
+        OvulationTestRecord.RESULT_NEGATIVE to PlatformOvulationTestResult.RESULT_NEGATIVE,
+        OvulationTestRecord.RESULT_INCONCLUSIVE to PlatformOvulationTestResult.RESULT_INCONCLUSIVE,
+    )
+
+internal val PLATFORM_TO_SDK_OVULATION_TEST_RESULT =
+    SDK_TO_PLATFORM_OVULATION_TEST_RESULT.reversed()
+
+internal val SDK_TO_PLATFORM_CERVICAL_MUCUS_SENSATION: Map<Int, Int> =
+    mapOf(
+        CervicalMucusRecord.SENSATION_LIGHT to PlatformCervicalMucusSensation.SENSATION_LIGHT,
+        CervicalMucusRecord.SENSATION_MEDIUM to PlatformCervicalMucusSensation.SENSATION_MEDIUM,
+        CervicalMucusRecord.SENSATION_HEAVY to PlatformCervicalMucusSensation.SENSATION_HEAVY,
+    )
+
+internal val PLATFORM_TO_SDK_CERVICAL_MUCUS_SENSATION =
+    SDK_TO_PLATFORM_CERVICAL_MUCUS_SENSATION.reversed()
+
+internal val SDK_TO_PLATFORM_SEXUAL_ACTIVITY_PROTECTION_USED: Map<Int, Int> =
+    mapOf(
+        SexualActivityRecord.PROTECTION_USED_PROTECTED to
+            PlatformSexualActivityProtectionUsed.PROTECTION_USED_PROTECTED,
+        SexualActivityRecord.PROTECTION_USED_UNPROTECTED to
+            PlatformSexualActivityProtectionUsed.PROTECTION_USED_UNPROTECTED,
+    )
+
+internal val PLATFORM_TO_SDK_SEXUAL_ACTIVITY_PROTECTION_USED =
+    SDK_TO_PLATFORM_SEXUAL_ACTIVITY_PROTECTION_USED.reversed()
+
+internal val SDK_TO_PLATFORM_BLOOD_GLUCOSE_SPECIMEN_SOURCE: Map<Int, Int> =
+    mapOf(
+        BloodGlucoseRecord.SPECIMEN_SOURCE_INTERSTITIAL_FLUID to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_INTERSTITIAL_FLUID,
+        BloodGlucoseRecord.SPECIMEN_SOURCE_CAPILLARY_BLOOD to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_CAPILLARY_BLOOD,
+        BloodGlucoseRecord.SPECIMEN_SOURCE_PLASMA to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_PLASMA,
+        BloodGlucoseRecord.SPECIMEN_SOURCE_SERUM to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_SERUM,
+        BloodGlucoseRecord.SPECIMEN_SOURCE_TEARS to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_TEARS,
+        BloodGlucoseRecord.SPECIMEN_SOURCE_WHOLE_BLOOD to
+            PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_WHOLE_BLOOD,
+    )
+
+internal val PLATFORM_TO_SDK_GLUCOSE_SPECIMEN_SOURCE =
+    SDK_TO_PLATFORM_BLOOD_GLUCOSE_SPECIMEN_SOURCE.reversed()
+
+internal val SDK_TO_PLATFORM_BLOOD_GLUCOSE_RELATION_TO_MEAL: Map<Int, Int> =
+    mapOf(
+        BloodGlucoseRecord.RELATION_TO_MEAL_GENERAL to
+            PlatformBloodGlucoseRelationToMeal.RELATION_TO_MEAL_GENERAL,
+        BloodGlucoseRecord.RELATION_TO_MEAL_FASTING to
+            PlatformBloodGlucoseRelationToMeal.RELATION_TO_MEAL_FASTING,
+        BloodGlucoseRecord.RELATION_TO_MEAL_BEFORE_MEAL to
+            PlatformBloodGlucoseRelationToMeal.RELATION_TO_MEAL_BEFORE_MEAL,
+        BloodGlucoseRecord.RELATION_TO_MEAL_AFTER_MEAL to
+            PlatformBloodGlucoseRelationToMeal.RELATION_TO_MEAL_AFTER_MEAL,
+    )
+
+internal val PLATFORM_TO_SDK_BLOOD_GLUCOSE_RELATION_TO_MEAL =
+    SDK_TO_PLATFORM_BLOOD_GLUCOSE_RELATION_TO_MEAL.reversed()
+
+internal val SDK_TO_PLATFORM_SLEEP_STAGE_TYPE: Map<Int, Int> =
+    mapOf(
+        SleepSessionRecord.STAGE_TYPE_AWAKE to PlatformSleepStageType.STAGE_TYPE_AWAKE,
+        SleepSessionRecord.STAGE_TYPE_SLEEPING to PlatformSleepStageType.STAGE_TYPE_SLEEPING,
+        SleepSessionRecord.STAGE_TYPE_OUT_OF_BED to
+            PlatformSleepStageType.STAGE_TYPE_AWAKE_OUT_OF_BED,
+        SleepSessionRecord.STAGE_TYPE_LIGHT to PlatformSleepStageType.STAGE_TYPE_SLEEPING_LIGHT,
+        SleepSessionRecord.STAGE_TYPE_DEEP to PlatformSleepStageType.STAGE_TYPE_SLEEPING_DEEP,
+        SleepSessionRecord.STAGE_TYPE_REM to PlatformSleepStageType.STAGE_TYPE_SLEEPING_REM,
+        SleepSessionRecord.STAGE_TYPE_AWAKE_IN_BED to PlatformSleepStageType.STAGE_TYPE_AWAKE_IN_BED
+    )
+
+internal val PLATFORM_TO_SDK_SLEEP_STAGE_TYPE = SDK_TO_PLATFORM_SLEEP_STAGE_TYPE.reversed()
+
+internal val SDK_TO_PLATFORM_EXERCISE_SEGMENT_TYPE: Map<Int, Int> =
+    mapOf(
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_ARM_CURL to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_ARM_CURL,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BACK_EXTENSION to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BALL_SLAM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BALL_SLAM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BENCH_PRESS to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BIKING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BIKING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_BURPEE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_BURPEE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_CRUNCH to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_CRUNCH,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DEADLIFT to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DEADLIFT,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_ELLIPTICAL to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_ELLIPTICAL,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_FORWARD_TWIST to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_FRONT_RAISE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_HIP_THRUST to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_HIP_THRUST,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_HULA_HOOP to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_HULA_HOOP,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_JUMPING_JACK to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_JUMP_ROPE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LATERAL_RAISE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LEG_CURL to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LEG_CURL,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LEG_EXTENSION to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LEG_EXTENSION,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LEG_PRESS to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LEG_PRESS,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LEG_RAISE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LEG_RAISE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_LUNGE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_LUNGE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_PAUSE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_PAUSE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_PILATES to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_PILATES,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_PLANK to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_PLANK,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_PULL_UP to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_PULL_UP,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_PUNCH to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_PUNCH,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_REST to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_REST,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_ROWING_MACHINE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_ROWING_MACHINE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_RUNNING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SIT_UP to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SIT_UP,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SQUAT to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SQUAT,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_STRETCHING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_STRETCHING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_SWIMMING_POOL to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_SWIMMING_POOL,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_UPPER_TWIST to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_WALKING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_WALKING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_WHEELCHAIR to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_WHEELCHAIR,
+        ExerciseSegment.EXERCISE_SEGMENT_TYPE_YOGA to
+            PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_YOGA,
+    )
+
+internal val PLATFORM_TO_SDK_EXERCISE_SEGMENT_TYPE =
+    SDK_TO_PLATFORM_EXERCISE_SEGMENT_TYPE.reversed()
+
+internal val SDK_TO_PLATFORM_RECORDING_METHOD: Map<Int, Int> =
+    mapOf(
+        Metadata.RECORDING_METHOD_ACTIVELY_RECORDED to
+            PlatformMetadata.RECORDING_METHOD_ACTIVELY_RECORDED,
+        Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED to
+            PlatformMetadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED,
+        Metadata.RECORDING_METHOD_MANUAL_ENTRY to PlatformMetadata.RECORDING_METHOD_MANUAL_ENTRY
+    )
+
+internal val PLATFORM_TO_SDK_RECORDING_METHOD: Map<Int, Int> =
+    SDK_TO_PLATFORM_RECORDING_METHOD.reversed()
+
+internal fun Int.toPlatformCervicalMucusAppearance(): Int {
+    return SDK_TO_PLATFORM_CERVICAL_MUCUS_APPEARANCE[this]
+        ?: PlatformCervicalMucusAppearance.APPEARANCE_UNKNOWN
+}
+
+internal fun Int.toPlatformBloodPressureBodyPosition(): Int {
+    return SDK_TO_PLATFORM_BLOOD_PRESSURE_BODY_POSITION[this]
+        ?: PlatformBloodPressureBodyPosition.BODY_POSITION_UNKNOWN
+}
+
+internal fun Int.toPlatformExerciseSessionType(): Int {
+    return SDK_TO_PLATFORM_EXERCISE_SESSION_TYPE[this]
+        ?: PlatformExerciseSessionType.EXERCISE_SESSION_TYPE_UNKNOWN
+}
+
+internal fun Int.toPlatformExerciseSegmentType(): Int {
+    return SDK_TO_PLATFORM_EXERCISE_SEGMENT_TYPE[this]
+        ?: PlatformExerciseSegmentType.EXERCISE_SEGMENT_TYPE_UNKNOWN
+}
+
+internal fun Int.toPlatformMealType(): Int {
+    return SDK_TO_PLATFORM_MEAL_TYPE[this] ?: PlatformMealType.MEAL_TYPE_UNKNOWN
+}
+
+internal fun Int.toPlatformVo2MaxMeasurementMethod(): Int {
+    return SDK_TO_PLATFORM_VO2_MAX_MEASUREMENT_METHOD[this]
+        ?: PlatformVo2MaxMeasurementMethod.MEASUREMENT_METHOD_OTHER
+}
+
+internal fun Int.toPlatformMenstruationFlow(): Int {
+    return SDK_TO_PLATFORM_MENSTRUATION_FLOW_TYPE[this] ?: PlatformMenstruationFlowType.FLOW_UNKNOWN
+}
+
+internal fun Int.toPlatformBodyTemperatureMeasurementLocation(): Int {
+    return SDK_TO_PLATFORM_BODY_TEMPERATURE_MEASUREMENT_LOCATION[this]
+        ?: PlatformBodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_UNKNOWN
+}
+
+internal fun Int.toPlatformBloodPressureMeasurementLocation(): Int {
+    return SDK_TO_PLATFORM_BLOOD_PRESSURE_MEASUREMENT_LOCATION[this]
+        ?: PlatformBloodPressureMeasurementLocation.BLOOD_PRESSURE_MEASUREMENT_LOCATION_UNKNOWN
+}
+
+internal fun Int.toPlatformOvulationTestResult(): Int {
+    return SDK_TO_PLATFORM_OVULATION_TEST_RESULT[this]
+        ?: PlatformOvulationTestResult.RESULT_INCONCLUSIVE
+}
+
+internal fun Int.toPlatformCervicalMucusSensation(): Int {
+    return SDK_TO_PLATFORM_CERVICAL_MUCUS_SENSATION[this]
+        ?: PlatformCervicalMucusSensation.SENSATION_UNKNOWN
+}
+
+internal fun Int.toPlatformSexualActivityProtectionUsed(): Int {
+    return SDK_TO_PLATFORM_SEXUAL_ACTIVITY_PROTECTION_USED[this]
+        ?: PlatformSexualActivityProtectionUsed.PROTECTION_USED_UNKNOWN
+}
+
+internal fun Int.toPlatformBloodGlucoseSpecimenSource(): Int {
+    return SDK_TO_PLATFORM_BLOOD_GLUCOSE_SPECIMEN_SOURCE[this]
+        ?: PlatformBloodGlucoseSpecimenSource.SPECIMEN_SOURCE_UNKNOWN
+}
+
+internal fun Int.toPlatformBloodGlucoseRelationToMeal(): Int {
+    return SDK_TO_PLATFORM_BLOOD_GLUCOSE_RELATION_TO_MEAL[this]
+        ?: PlatformBloodGlucoseRelationToMeal.RELATION_TO_MEAL_UNKNOWN
+}
+
+internal fun Int.toPlatformSleepStageType(): Int {
+    return SDK_TO_PLATFORM_SLEEP_STAGE_TYPE[this] ?: PlatformSleepStageType.STAGE_TYPE_UNKNOWN
+}
+
+internal fun Int.toPlatformRecordingMethod(): Int {
+    return SDK_TO_PLATFORM_RECORDING_METHOD[this] ?: PlatformMetadata.RECORDING_METHOD_UNKNOWN
+}
+
+internal fun Int.toSdkBloodPressureBodyPosition(): Int {
+    return PLATFORM_TO_SDK_BLOOD_PRESSURE_BODY_POSITION[this]
+        ?: BloodPressureRecord.BODY_POSITION_UNKNOWN
+}
+
+internal fun Int.toSdkBloodPressureMeasurementLocation(): Int {
+    return PLATFORM_TO_SDK_BLOOD_PRESSURE_MEASUREMENT_LOCATION[this]
+        ?: BloodPressureRecord.MEASUREMENT_LOCATION_UNKNOWN
+}
+
+internal fun Int.toSdkExerciseSessionType(): Int {
+    return PLATFORM_TO_SDK_EXERCISE_SESSION_TYPE[this]
+        ?: ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT
+}
+
+internal fun Int.toSdkExerciseSegmentType(): Int {
+    return PLATFORM_TO_SDK_EXERCISE_SEGMENT_TYPE[this]
+        ?: ExerciseSegment.EXERCISE_SEGMENT_TYPE_UNKNOWN
+}
+
+internal fun Int.toSdkVo2MaxMeasurementMethod(): Int {
+    return PLATFORM_TO_SDK_VO2_MAX_MEASUREMENT_METHOD[this] ?: Vo2MaxRecord.MEASUREMENT_METHOD_OTHER
+}
+
+internal fun Int.toSdkMenstruationFlow(): Int {
+    return PLATFORM_TO_SDK_MENSTRUATION_FLOW_TYPE[this] ?: MenstruationFlowRecord.FLOW_UNKNOWN
+}
+
+internal fun Int.toSdkProtectionUsed(): Int {
+    return PLATFORM_TO_SDK_SEXUAL_ACTIVITY_PROTECTION_USED[this]
+        ?: SexualActivityRecord.PROTECTION_USED_UNKNOWN
+}
+
+internal fun Int.toSdkCervicalMucusSensation(): Int {
+    return PLATFORM_TO_SDK_CERVICAL_MUCUS_SENSATION[this] ?: CervicalMucusRecord.SENSATION_UNKNOWN
+}
+
+internal fun Int.toSdkBloodGlucoseSpecimenSource(): Int {
+    return PLATFORM_TO_SDK_GLUCOSE_SPECIMEN_SOURCE[this]
+        ?: BloodGlucoseRecord.SPECIMEN_SOURCE_UNKNOWN
+}
+
+internal fun Int.toSdkMealType(): Int {
+    return PLATFORM_TO_SDK_MEAL_TYPE[this] ?: MealType.MEAL_TYPE_UNKNOWN
+}
+
+internal fun Int.toSdkOvulationTestResult(): Int {
+    return PLATFORM_TO_SDK_OVULATION_TEST_RESULT[this] ?: OvulationTestRecord.RESULT_INCONCLUSIVE
+}
+
+internal fun Int.toSdkRelationToMeal(): Int {
+    return PLATFORM_TO_SDK_BLOOD_GLUCOSE_RELATION_TO_MEAL[this]
+        ?: BloodGlucoseRecord.RELATION_TO_MEAL_UNKNOWN
+}
+
+internal fun Int.toSdkBodyTemperatureMeasurementLocation(): Int {
+    return PLATFORM_TO_SDK_BODY_TEMPERATURE_MEASUREMENT_LOCATION[this]
+        ?: BodyTemperatureMeasurementLocation.MEASUREMENT_LOCATION_UNKNOWN
+}
+
+internal fun Int.toSdkCervicalMucusAppearance(): Int {
+    return PLATFORM_TO_SDK_CERVICAL_MUCUS_APPEARANCE[this] ?: CervicalMucusRecord.APPEARANCE_UNKNOWN
+}
+
+internal fun Int.toSdkSleepStageType(): Int {
+    return PLATFORM_TO_SDK_SLEEP_STAGE_TYPE[this] ?: SleepSessionRecord.STAGE_TYPE_UNKNOWN
+}
+
+internal fun Int.toSdkRecordingMethod(): Int {
+    return PLATFORM_TO_SDK_RECORDING_METHOD[this] ?: Metadata.RECORDING_METHOD_UNKNOWN
+}
+
+private fun Map<Int, Int>.reversed(): Map<Int, Int> {
+    return entries.associate { (k, v) -> v to k }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/MetadataConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/MetadataConverters.kt
new file mode 100644
index 0000000..f4f74d1
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/MetadataConverters.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.records.metadata.DataOrigin
+import androidx.health.connect.client.records.metadata.Device
+import androidx.health.connect.client.records.metadata.Metadata
+
+internal fun PlatformMetadata.toSdkMetadata(): Metadata {
+    return Metadata(
+        id = id,
+        dataOrigin = dataOrigin.toSdkDataOrigin(),
+        lastModifiedTime = lastModifiedTime,
+        clientRecordId = clientRecordId,
+        clientRecordVersion = clientRecordVersion,
+        recordingMethod = recordingMethod.toSdkRecordingMethod(),
+        device = device.toSdkDevice()
+    )
+}
+
+internal fun PlatformDevice.toSdkDevice(): Device {
+    @Suppress("WrongConstant") // Platform intdef and jetpack intdef match in value.
+    return Device(manufacturer = manufacturer, model = model, type = type)
+}
+
+internal fun PlatformDataOrigin.toSdkDataOrigin(): DataOrigin {
+    return DataOrigin(packageName)
+}
+
+internal fun Metadata.toPlatformMetadata(): PlatformMetadata {
+    return PlatformMetadataBuilder()
+        .apply {
+            device?.toPlatformDevice()?.let { setDevice(it) }
+            setLastModifiedTime(lastModifiedTime)
+            setId(id)
+            setDataOrigin(dataOrigin.toPlatformDataOrigin())
+            setClientRecordId(clientRecordId)
+            setClientRecordVersion(clientRecordVersion)
+            setRecordingMethod(recordingMethod.toPlatformRecordingMethod())
+        }
+        .build()
+}
+
+internal fun DataOrigin.toPlatformDataOrigin(): PlatformDataOrigin {
+    return PlatformDataOriginBuilder().apply { setPackageName(packageName) }.build()
+}
+
+internal fun Device.toPlatformDevice(): PlatformDevice {
+    @Suppress("WrongConstant") // Platform intdef and jetpack intdef match in value.
+    return PlatformDeviceBuilder()
+        .apply {
+            setType(type)
+            manufacturer?.let { setManufacturer(it) }
+            model?.let { setModel(it) }
+        }
+        .build()
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/PlatformRecordAliases.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/PlatformRecordAliases.kt
new file mode 100644
index 0000000..b1653a2
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/PlatformRecordAliases.kt
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+
+internal typealias PlatformInstantRecord = android.health.connect.datatypes.InstantRecord
+
+internal typealias PlatformIntervalRecord = android.health.connect.datatypes.IntervalRecord
+
+internal typealias PlatformRecord = android.health.connect.datatypes.Record
+
+internal typealias PlatformActiveCaloriesBurnedRecord =
+    android.health.connect.datatypes.ActiveCaloriesBurnedRecord
+
+internal typealias PlatformActiveCaloriesBurnedRecordBuilder =
+    android.health.connect.datatypes.ActiveCaloriesBurnedRecord.Builder
+
+internal typealias PlatformBasalBodyTemperatureRecord =
+    android.health.connect.datatypes.BasalBodyTemperatureRecord
+
+internal typealias PlatformBasalBodyTemperatureRecordBuilder =
+    android.health.connect.datatypes.BasalBodyTemperatureRecord.Builder
+
+internal typealias PlatformBodyTemperatureMeasurementLocation =
+    android.health.connect.datatypes.BodyTemperatureMeasurementLocation
+
+internal typealias PlatformBasalMetabolicRateRecord =
+    android.health.connect.datatypes.BasalMetabolicRateRecord
+
+internal typealias PlatformBasalMetabolicRateRecordBuilder =
+    android.health.connect.datatypes.BasalMetabolicRateRecord.Builder
+
+internal typealias PlatformBloodGlucoseRecord = android.health.connect.datatypes.BloodGlucoseRecord
+
+internal typealias PlatformBloodGlucoseRecordBuilder =
+    android.health.connect.datatypes.BloodGlucoseRecord.Builder
+
+internal typealias PlatformBloodGlucoseSpecimenSource =
+    android.health.connect.datatypes.BloodGlucoseRecord.SpecimenSource
+
+internal typealias PlatformBloodGlucoseRelationToMealType =
+    android.health.connect.datatypes.BloodGlucoseRecord.RelationToMealType
+
+internal typealias PlatformBloodPressureRecord =
+    android.health.connect.datatypes.BloodPressureRecord
+
+internal typealias PlatformBloodPressureRecordBuilder =
+    android.health.connect.datatypes.BloodPressureRecord.Builder
+
+internal typealias PlatformBloodGlucoseRelationToMeal =
+    android.health.connect.datatypes.BloodGlucoseRecord.RelationToMealType
+
+internal typealias PlatformBloodPressureBodyPosition =
+    android.health.connect.datatypes.BloodPressureRecord.BodyPosition
+
+internal typealias PlatformBloodPressureMeasurementLocation =
+    android.health.connect.datatypes.BloodPressureRecord.BloodPressureMeasurementLocation
+
+internal typealias PlatformBodyFatRecord = android.health.connect.datatypes.BodyFatRecord
+
+internal typealias PlatformBodyFatRecordBuilder =
+    android.health.connect.datatypes.BodyFatRecord.Builder
+
+internal typealias PlatformBodyTemperatureRecord =
+    android.health.connect.datatypes.BodyTemperatureRecord
+
+internal typealias PlatformBodyTemperatureRecordBuilder =
+    android.health.connect.datatypes.BodyTemperatureRecord.Builder
+
+internal typealias PlatformBodyWaterMassRecord =
+    android.health.connect.datatypes.BodyWaterMassRecord
+
+internal typealias PlatformBodyWaterMassRecordBuilder =
+    android.health.connect.datatypes.BodyWaterMassRecord.Builder
+
+internal typealias PlatformBoneMassRecord = android.health.connect.datatypes.BoneMassRecord
+
+internal typealias PlatformBoneMassRecordBuilder =
+    android.health.connect.datatypes.BoneMassRecord.Builder
+
+internal typealias PlatformCervicalMucusRecord =
+    android.health.connect.datatypes.CervicalMucusRecord
+
+internal typealias PlatformCervicalMucusRecordBuilder =
+    android.health.connect.datatypes.CervicalMucusRecord.Builder
+
+internal typealias PlatformCervicalMucusAppearance =
+    android.health.connect.datatypes.CervicalMucusRecord.CervicalMucusAppearance
+
+internal typealias PlatformCervicalMucusSensation =
+    android.health.connect.datatypes.CervicalMucusRecord.CervicalMucusSensation
+
+internal typealias PlatformCyclingPedalingCadenceRecord =
+    android.health.connect.datatypes.CyclingPedalingCadenceRecord
+
+internal typealias PlatformCyclingPedalingCadenceRecordBuilder =
+    android.health.connect.datatypes.CyclingPedalingCadenceRecord.Builder
+
+internal typealias PlatformCyclingPedalingCadenceSample =
+    android.health.connect.datatypes.CyclingPedalingCadenceRecord.CyclingPedalingCadenceRecordSample
+
+internal typealias PlatformDistanceRecord = android.health.connect.datatypes.DistanceRecord
+
+internal typealias PlatformDistanceRecordBuilder =
+    android.health.connect.datatypes.DistanceRecord.Builder
+
+internal typealias PlatformElevationGainedRecord =
+    android.health.connect.datatypes.ElevationGainedRecord
+
+internal typealias PlatformElevationGainedRecordBuilder =
+    android.health.connect.datatypes.ElevationGainedRecord.Builder
+
+internal typealias PlatformExerciseLap = android.health.connect.datatypes.ExerciseLap
+
+internal typealias PlatformExerciseLapBuilder = android.health.connect.datatypes.ExerciseLap.Builder
+
+internal typealias PlatformExerciseSegment = android.health.connect.datatypes.ExerciseSegment
+
+internal typealias PlatformExerciseSegmentBuilder =
+    android.health.connect.datatypes.ExerciseSegment.Builder
+
+internal typealias PlatformExerciseSegmentType =
+    android.health.connect.datatypes.ExerciseSegmentType
+
+internal typealias PlatformExerciseSessionRecord =
+    android.health.connect.datatypes.ExerciseSessionRecord
+
+internal typealias PlatformExerciseSessionRecordBuilder =
+    android.health.connect.datatypes.ExerciseSessionRecord.Builder
+
+internal typealias PlatformExerciseSessionType =
+    android.health.connect.datatypes.ExerciseSessionType
+
+internal typealias PlatformExerciseRoute = android.health.connect.datatypes.ExerciseRoute
+
+internal typealias PlatformExerciseRouteLocation =
+    android.health.connect.datatypes.ExerciseRoute.Location
+
+internal typealias PlatformExerciseRouteLocationBuilder =
+    android.health.connect.datatypes.ExerciseRoute.Location.Builder
+
+internal typealias PlatformFloorsClimbedRecord =
+    android.health.connect.datatypes.FloorsClimbedRecord
+
+internal typealias PlatformFloorsClimbedRecordBuilder =
+    android.health.connect.datatypes.FloorsClimbedRecord.Builder
+
+internal typealias PlatformHeartRateRecord = android.health.connect.datatypes.HeartRateRecord
+
+internal typealias PlatformHeartRateRecordBuilder =
+    android.health.connect.datatypes.HeartRateRecord.Builder
+
+internal typealias PlatformHeartRateSample =
+    android.health.connect.datatypes.HeartRateRecord.HeartRateSample
+
+internal typealias PlatformHeartRateVariabilityRmssdRecord =
+    android.health.connect.datatypes.HeartRateVariabilityRmssdRecord
+
+internal typealias PlatformHeartRateVariabilityRmssdRecordBuilder =
+    android.health.connect.datatypes.HeartRateVariabilityRmssdRecord.Builder
+
+internal typealias PlatformHeightRecord = android.health.connect.datatypes.HeightRecord
+
+internal typealias PlatformHeightRecordBuilder =
+    android.health.connect.datatypes.HeightRecord.Builder
+
+internal typealias PlatformHydrationRecord = android.health.connect.datatypes.HydrationRecord
+
+internal typealias PlatformHydrationRecordBuilder =
+    android.health.connect.datatypes.HydrationRecord.Builder
+
+internal typealias PlatformIntermenstrualBleedingRecord =
+    android.health.connect.datatypes.IntermenstrualBleedingRecord
+
+internal typealias PlatformIntermenstrualBleedingRecordBuilder =
+    android.health.connect.datatypes.IntermenstrualBleedingRecord.Builder
+
+internal typealias PlatformLeanBodyMassRecord = android.health.connect.datatypes.LeanBodyMassRecord
+
+internal typealias PlatformLeanBodyMassRecordBuilder =
+    android.health.connect.datatypes.LeanBodyMassRecord.Builder
+
+internal typealias PlatformMenstruationFlowRecord =
+    android.health.connect.datatypes.MenstruationFlowRecord
+
+internal typealias PlatformMenstruationFlowRecordBuilder =
+    android.health.connect.datatypes.MenstruationFlowRecord.Builder
+
+internal typealias PlatformMenstruationFlowType =
+    android.health.connect.datatypes.MenstruationFlowRecord.MenstruationFlowType
+
+internal typealias PlatformMealType = android.health.connect.datatypes.MealType
+
+internal typealias PlatformMenstruationPeriodRecord =
+    android.health.connect.datatypes.MenstruationPeriodRecord
+
+internal typealias PlatformMenstruationPeriodRecordBuilder =
+    android.health.connect.datatypes.MenstruationPeriodRecord.Builder
+
+internal typealias PlatformNutritionRecord = android.health.connect.datatypes.NutritionRecord
+
+internal typealias PlatformNutritionRecordBuilder =
+    android.health.connect.datatypes.NutritionRecord.Builder
+
+internal typealias PlatformOvulationTestRecord =
+    android.health.connect.datatypes.OvulationTestRecord
+
+internal typealias PlatformOvulationTestRecordBuilder =
+    android.health.connect.datatypes.OvulationTestRecord.Builder
+
+internal typealias PlatformOvulationTestResult =
+    android.health.connect.datatypes.OvulationTestRecord.OvulationTestResult
+
+internal typealias PlatformOxygenSaturationRecord =
+    android.health.connect.datatypes.OxygenSaturationRecord
+
+internal typealias PlatformOxygenSaturationRecordBuilder =
+    android.health.connect.datatypes.OxygenSaturationRecord.Builder
+
+internal typealias PlatformPowerRecord = android.health.connect.datatypes.PowerRecord
+
+internal typealias PlatformPowerRecordBuilder = android.health.connect.datatypes.PowerRecord.Builder
+
+internal typealias PlatformPowerRecordSample =
+    android.health.connect.datatypes.PowerRecord.PowerRecordSample
+
+internal typealias PlatformRespiratoryRateRecord =
+    android.health.connect.datatypes.RespiratoryRateRecord
+
+internal typealias PlatformRespiratoryRateRecordBuilder =
+    android.health.connect.datatypes.RespiratoryRateRecord.Builder
+
+internal typealias PlatformRestingHeartRateRecord =
+    android.health.connect.datatypes.RestingHeartRateRecord
+
+internal typealias PlatformRestingHeartRateRecordBuilder =
+    android.health.connect.datatypes.RestingHeartRateRecord.Builder
+
+internal typealias PlatformSexualActivityRecord =
+    android.health.connect.datatypes.SexualActivityRecord
+
+internal typealias PlatformSexualActivityRecordBuilder =
+    android.health.connect.datatypes.SexualActivityRecord.Builder
+
+internal typealias PlatformSexualActivityProtectionUsed =
+    android.health.connect.datatypes.SexualActivityRecord.SexualActivityProtectionUsed
+
+internal typealias PlatformSleepSessionRecord = android.health.connect.datatypes.SleepSessionRecord
+
+internal typealias PlatformSleepSessionRecordBuilder =
+    android.health.connect.datatypes.SleepSessionRecord.Builder
+
+internal typealias PlatformSleepSessionStage =
+    android.health.connect.datatypes.SleepSessionRecord.Stage
+
+internal typealias PlatformSleepStageType =
+    android.health.connect.datatypes.SleepSessionRecord.StageType
+
+internal typealias PlatformSpeedRecord = android.health.connect.datatypes.SpeedRecord
+
+internal typealias PlatformSpeedRecordBuilder = android.health.connect.datatypes.SpeedRecord.Builder
+
+internal typealias PlatformSpeedSample =
+    android.health.connect.datatypes.SpeedRecord.SpeedRecordSample
+
+internal typealias PlatformStepsCadenceRecord = android.health.connect.datatypes.StepsCadenceRecord
+
+internal typealias PlatformStepsCadenceRecordBuilder =
+    android.health.connect.datatypes.StepsCadenceRecord.Builder
+
+internal typealias PlatformStepsCadenceSample =
+    android.health.connect.datatypes.StepsCadenceRecord.StepsCadenceRecordSample
+
+internal typealias PlatformStepsRecord = android.health.connect.datatypes.StepsRecord
+
+internal typealias PlatformStepsRecordBuilder = android.health.connect.datatypes.StepsRecord.Builder
+
+internal typealias PlatformTotalCaloriesBurnedRecord =
+    android.health.connect.datatypes.TotalCaloriesBurnedRecord
+
+internal typealias PlatformTotalCaloriesBurnedRecordBuilder =
+    android.health.connect.datatypes.TotalCaloriesBurnedRecord.Builder
+
+internal typealias PlatformVo2MaxRecord = android.health.connect.datatypes.Vo2MaxRecord
+
+internal typealias PlatformVo2MaxRecordBuilder =
+    android.health.connect.datatypes.Vo2MaxRecord.Builder
+
+internal typealias PlatformVo2MaxMeasurementMethod =
+    android.health.connect.datatypes.Vo2MaxRecord.Vo2MaxMeasurementMethod
+
+internal typealias PlatformWeightRecord = android.health.connect.datatypes.WeightRecord
+
+internal typealias PlatformWeightRecordBuilder =
+    android.health.connect.datatypes.WeightRecord.Builder
+
+internal typealias PlatformWheelchairPushesRecord =
+    android.health.connect.datatypes.WheelchairPushesRecord
+
+internal typealias PlatformWheelchairPushesRecordBuilder =
+    android.health.connect.datatypes.WheelchairPushesRecord.Builder
+
+internal typealias PlatformDataOrigin = android.health.connect.datatypes.DataOrigin
+
+internal typealias PlatformDataOriginBuilder = android.health.connect.datatypes.DataOrigin.Builder
+
+internal typealias PlatformDevice = android.health.connect.datatypes.Device
+
+internal typealias PlatformDeviceBuilder = android.health.connect.datatypes.Device.Builder
+
+internal typealias PlatformMetadata = android.health.connect.datatypes.Metadata
+
+internal typealias PlatformMetadataBuilder = android.health.connect.datatypes.Metadata.Builder
+
+internal typealias PlatformBloodGlucose = android.health.connect.datatypes.units.BloodGlucose
+
+internal typealias PlatformEnergy = android.health.connect.datatypes.units.Energy
+
+internal typealias PlatformLength = android.health.connect.datatypes.units.Length
+
+internal typealias PlatformMass = android.health.connect.datatypes.units.Mass
+
+internal typealias PlatformPercentage = android.health.connect.datatypes.units.Percentage
+
+internal typealias PlatformPower = android.health.connect.datatypes.units.Power
+
+internal typealias PlatformPressure = android.health.connect.datatypes.units.Pressure
+
+internal typealias PlatformTemperature = android.health.connect.datatypes.units.Temperature
+
+internal typealias PlatformVelocity = android.health.connect.datatypes.units.Velocity
+
+internal typealias PlatformVolume = android.health.connect.datatypes.units.Volume
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordConverters.kt
new file mode 100644
index 0000000..e82005f
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordConverters.kt
@@ -0,0 +1,1052 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.records.ActiveCaloriesBurnedRecord
+import androidx.health.connect.client.records.BasalBodyTemperatureRecord
+import androidx.health.connect.client.records.BasalMetabolicRateRecord
+import androidx.health.connect.client.records.BloodGlucoseRecord
+import androidx.health.connect.client.records.BloodPressureRecord
+import androidx.health.connect.client.records.BodyFatRecord
+import androidx.health.connect.client.records.BodyTemperatureRecord
+import androidx.health.connect.client.records.BodyWaterMassRecord
+import androidx.health.connect.client.records.BoneMassRecord
+import androidx.health.connect.client.records.CervicalMucusRecord
+import androidx.health.connect.client.records.CyclingPedalingCadenceRecord
+import androidx.health.connect.client.records.DistanceRecord
+import androidx.health.connect.client.records.ElevationGainedRecord
+import androidx.health.connect.client.records.ExerciseLap
+import androidx.health.connect.client.records.ExerciseRoute
+import androidx.health.connect.client.records.ExerciseSegment
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.FloorsClimbedRecord
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.HeartRateVariabilityRmssdRecord
+import androidx.health.connect.client.records.HeightRecord
+import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
+import androidx.health.connect.client.records.LeanBodyMassRecord
+import androidx.health.connect.client.records.MenstruationFlowRecord
+import androidx.health.connect.client.records.MenstruationPeriodRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.OvulationTestRecord
+import androidx.health.connect.client.records.OxygenSaturationRecord
+import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.Record
+import androidx.health.connect.client.records.RespiratoryRateRecord
+import androidx.health.connect.client.records.RestingHeartRateRecord
+import androidx.health.connect.client.records.SexualActivityRecord
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.SpeedRecord
+import androidx.health.connect.client.records.StepsCadenceRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.TotalCaloriesBurnedRecord
+import androidx.health.connect.client.records.Vo2MaxRecord
+import androidx.health.connect.client.records.WeightRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import kotlin.reflect.KClass
+
+// TODO(b/270559291): Validate that all class fields are being converted.
+
+fun KClass<out Record>.toPlatformRecordClass(): Class<out PlatformRecord> {
+    return SDK_TO_PLATFORM_RECORD_CLASS[this]
+        ?: throw IllegalArgumentException("Unsupported record type $this")
+}
+
+fun Record.toPlatformRecord(): PlatformRecord {
+    return when (this) {
+        is ActiveCaloriesBurnedRecord -> toPlatformActiveCaloriesBurnedRecord()
+        is BasalBodyTemperatureRecord -> toPlatformBasalBodyTemperatureRecord()
+        is BasalMetabolicRateRecord -> toPlatformBasalMetabolicRateRecord()
+        is BloodGlucoseRecord -> toPlatformBloodGlucoseRecord()
+        is BloodPressureRecord -> toPlatformBloodPressureRecord()
+        is BodyFatRecord -> toPlatformBodyFatRecord()
+        is BodyTemperatureRecord -> toPlatformBodyTemperatureRecord()
+        is BodyWaterMassRecord -> toPlatformBodyWaterMassRecord()
+        is BoneMassRecord -> toPlatformBoneMassRecord()
+        is CervicalMucusRecord -> toPlatformCervicalMucusRecord()
+        is CyclingPedalingCadenceRecord -> toPlatformCyclingPedalingCadenceRecord()
+        is DistanceRecord -> toPlatformDistanceRecord()
+        is ElevationGainedRecord -> toPlatformElevationGainedRecord()
+        is ExerciseSessionRecord -> toPlatformExerciseSessionRecord()
+        is FloorsClimbedRecord -> toPlatformFloorsClimbedRecord()
+        is HeartRateRecord -> toPlatformHeartRateRecord()
+        is HeartRateVariabilityRmssdRecord -> toPlatformHeartRateVariabilityRmssdRecord()
+        is HeightRecord -> toPlatformHeightRecord()
+        is HydrationRecord -> toPlatformHydrationRecord()
+        is IntermenstrualBleedingRecord -> toPlatformIntermenstrualBleedingRecord()
+        is LeanBodyMassRecord -> toPlatformLeanBodyMassRecord()
+        is MenstruationFlowRecord -> toPlatformMenstruationFlowRecord()
+        is MenstruationPeriodRecord -> toPlatformMenstruationPeriodRecord()
+        is NutritionRecord -> toPlatformNutritionRecord()
+        is OvulationTestRecord -> toPlatformOvulationTestRecord()
+        is OxygenSaturationRecord -> toPlatformOxygenSaturationRecord()
+        is PowerRecord -> toPlatformPowerRecord()
+        is RespiratoryRateRecord -> toPlatformRespiratoryRateRecord()
+        is RestingHeartRateRecord -> toPlatformRestingHeartRateRecord()
+        is SexualActivityRecord -> toPlatformSexualActivityRecord()
+        is SleepSessionRecord -> toPlatformSleepSessionRecord()
+        is SpeedRecord -> toPlatformSpeedRecord()
+        is StepsCadenceRecord -> toPlatformStepsCadenceRecord()
+        is StepsRecord -> toPlatformStepsRecord()
+        is TotalCaloriesBurnedRecord -> toPlatformTotalCaloriesBurnedRecord()
+        is Vo2MaxRecord -> toPlatformVo2MaxRecord()
+        is WeightRecord -> toPlatformWeightRecord()
+        is WheelchairPushesRecord -> toPlatformWheelchairPushesRecord()
+        else -> throw IllegalArgumentException("Unsupported record $this")
+    }
+}
+
+fun PlatformRecord.toSdkRecord(): Record {
+    return when (this) {
+        is PlatformActiveCaloriesBurnedRecord -> toSdkActiveCaloriesBurnedRecord()
+        is PlatformBasalBodyTemperatureRecord -> toSdkBasalBodyTemperatureRecord()
+        is PlatformBasalMetabolicRateRecord -> toSdkBasalMetabolicRateRecord()
+        is PlatformBloodGlucoseRecord -> toSdkBloodGlucoseRecord()
+        is PlatformBloodPressureRecord -> toSdkBloodPressureRecord()
+        is PlatformBodyFatRecord -> toSdkBodyFatRecord()
+        is PlatformBodyTemperatureRecord -> toSdkBodyTemperatureRecord()
+        is PlatformBodyWaterMassRecord -> toSdkBodyWaterMassRecord()
+        is PlatformBoneMassRecord -> toSdkBoneMassRecord()
+        is PlatformCervicalMucusRecord -> toSdkCervicalMucusRecord()
+        is PlatformCyclingPedalingCadenceRecord -> toSdkCyclingPedalingCadenceRecord()
+        is PlatformDistanceRecord -> toSdkDistanceRecord()
+        is PlatformElevationGainedRecord -> toSdkElevationGainedRecord()
+        is PlatformExerciseSessionRecord -> toSdkExerciseSessionRecord()
+        is PlatformFloorsClimbedRecord -> toSdkFloorsClimbedRecord()
+        is PlatformHeartRateRecord -> toSdkHeartRateRecord()
+        is PlatformHeartRateVariabilityRmssdRecord -> toSdkHeartRateVariabilityRmssdRecord()
+        is PlatformHeightRecord -> toSdkHeightRecord()
+        is PlatformHydrationRecord -> toSdkHydrationRecord()
+        is PlatformIntermenstrualBleedingRecord -> toSdkIntermenstrualBleedingRecord()
+        is PlatformLeanBodyMassRecord -> toSdkLeanBodyMassRecord()
+        is PlatformMenstruationFlowRecord -> toSdkMenstruationFlowRecord()
+        is PlatformMenstruationPeriodRecord -> toSdkMenstruationPeriodRecord()
+        is PlatformNutritionRecord -> toSdkNutritionRecord()
+        is PlatformOvulationTestRecord -> toSdkOvulationTestRecord()
+        is PlatformOxygenSaturationRecord -> toSdkOxygenSaturationRecord()
+        is PlatformPowerRecord -> toSdkPowerRecord()
+        is PlatformRespiratoryRateRecord -> toSdkRespiratoryRateRecord()
+        is PlatformRestingHeartRateRecord -> toSdkRestingHeartRateRecord()
+        is PlatformSexualActivityRecord -> toSdkSexualActivityRecord()
+        is PlatformSleepSessionRecord -> toSdkSleepSessionRecord()
+        is PlatformSpeedRecord -> toSdkSpeedRecord()
+        is PlatformStepsCadenceRecord -> toSdkStepsCadenceRecord()
+        is PlatformStepsRecord -> toSdkStepsRecord()
+        is PlatformTotalCaloriesBurnedRecord -> toSdkTotalCaloriesBurnedRecord()
+        is PlatformVo2MaxRecord -> toSdkVo2MaxRecord()
+        is PlatformWeightRecord -> toSdkWeightRecord()
+        is PlatformWheelchairPushesRecord -> toWheelchairPushesRecord()
+        else -> throw IllegalArgumentException("Unsupported record $this")
+    }
+}
+
+private fun PlatformActiveCaloriesBurnedRecord.toSdkActiveCaloriesBurnedRecord() =
+    ActiveCaloriesBurnedRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        energy = energy.toSdkEnergy(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBasalBodyTemperatureRecord.toSdkBasalBodyTemperatureRecord() =
+    BasalBodyTemperatureRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        temperature = temperature.toSdkTemperature(),
+        measurementLocation = measurementLocation,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBasalMetabolicRateRecord.toSdkBasalMetabolicRateRecord() =
+    BasalMetabolicRateRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        basalMetabolicRate = basalMetabolicRate.toSdkPower(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBloodGlucoseRecord.toSdkBloodGlucoseRecord() =
+    BloodGlucoseRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        level = level.toSdkBloodGlucose(),
+        specimenSource = specimenSource.toSdkBloodGlucoseSpecimenSource(),
+        mealType = mealType.toSdkMealType(),
+        relationToMeal = relationToMeal.toSdkRelationToMeal(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBloodPressureRecord.toSdkBloodPressureRecord() =
+    BloodPressureRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        systolic = systolic.toSdkPressure(),
+        diastolic = diastolic.toSdkPressure(),
+        bodyPosition = bodyPosition.toSdkBloodPressureBodyPosition(),
+        measurementLocation = measurementLocation.toSdkBloodPressureMeasurementLocation(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBodyFatRecord.toSdkBodyFatRecord() =
+    BodyFatRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        percentage = percentage.toSdkPercentage(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBodyTemperatureRecord.toSdkBodyTemperatureRecord() =
+    BodyTemperatureRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        temperature = temperature.toSdkTemperature(),
+        measurementLocation = measurementLocation.toSdkBodyTemperatureMeasurementLocation(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBodyWaterMassRecord.toSdkBodyWaterMassRecord() =
+    BodyWaterMassRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        mass = bodyWaterMass.toSdkMass(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformBoneMassRecord.toSdkBoneMassRecord() =
+    BoneMassRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        mass = mass.toSdkMass(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformCervicalMucusRecord.toSdkCervicalMucusRecord() =
+    CervicalMucusRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        appearance = appearance.toSdkCervicalMucusAppearance(),
+        sensation = sensation.toSdkCervicalMucusSensation(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformCyclingPedalingCadenceRecord.toSdkCyclingPedalingCadenceRecord() =
+    CyclingPedalingCadenceRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        samples = samples.map { it.toSdkCyclingPedalingCadenceSample() }.sortedBy { it.time },
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformDistanceRecord.toSdkDistanceRecord() =
+    DistanceRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        distance = distance.toSdkLength(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformElevationGainedRecord.toSdkElevationGainedRecord() =
+    ElevationGainedRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        elevation = elevation.toSdkLength(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformExerciseSessionRecord.toSdkExerciseSessionRecord() =
+    ExerciseSessionRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        exerciseType = exerciseType.toSdkExerciseSessionType(),
+        title = title?.toString(),
+        notes = notes?.toString(),
+        route = route?.toSdkExerciseRoute(),
+        laps = laps.map { it.toSdkExerciseLap() }.sortedBy { it.startTime },
+        segments = segments.map { it.toSdkExerciseSegment() }.sortedBy { it.startTime },
+        hasRoute = hasRoute(),
+        metadata = metadata.toSdkMetadata(),
+    )
+
+private fun PlatformFloorsClimbedRecord.toSdkFloorsClimbedRecord() =
+    FloorsClimbedRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        floors = floors,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformHeartRateRecord.toSdkHeartRateRecord() =
+    HeartRateRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        samples = samples.map { it.toSdkHeartRateSample() }.sortedBy { it.time },
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformHeartRateVariabilityRmssdRecord.toSdkHeartRateVariabilityRmssdRecord() =
+    HeartRateVariabilityRmssdRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        heartRateVariabilityMillis = heartRateVariabilityMillis,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformHeightRecord.toSdkHeightRecord() =
+    HeightRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        height = height.toSdkLength(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformHydrationRecord.toSdkHydrationRecord() =
+    HydrationRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        volume = volume.toSdkVolume(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformIntermenstrualBleedingRecord.toSdkIntermenstrualBleedingRecord() =
+    IntermenstrualBleedingRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformLeanBodyMassRecord.toSdkLeanBodyMassRecord() =
+    LeanBodyMassRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        mass = mass.toSdkMass(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformMenstruationFlowRecord.toSdkMenstruationFlowRecord() =
+    MenstruationFlowRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        flow = flow.toSdkMenstruationFlow(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformMenstruationPeriodRecord.toSdkMenstruationPeriodRecord() =
+    MenstruationPeriodRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformNutritionRecord.toSdkNutritionRecord() =
+    NutritionRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        name = mealName,
+        mealType = mealType.toSdkMealType(),
+        metadata = metadata.toSdkMetadata(),
+        biotin = biotin?.toSdkMass(),
+        caffeine = caffeine?.toSdkMass(),
+        calcium = calcium?.toSdkMass(),
+        energy = energy?.toSdkEnergy(),
+        energyFromFat = energyFromFat?.toSdkEnergy(),
+        chloride = chloride?.toSdkMass(),
+        cholesterol = cholesterol?.toSdkMass(),
+        chromium = chromium?.toSdkMass(),
+        copper = copper?.toSdkMass(),
+        dietaryFiber = dietaryFiber?.toSdkMass(),
+        folate = folate?.toSdkMass(),
+        folicAcid = folicAcid?.toSdkMass(),
+        iodine = iodine?.toSdkMass(),
+        iron = iron?.toSdkMass(),
+        magnesium = magnesium?.toSdkMass(),
+        manganese = manganese?.toSdkMass(),
+        molybdenum = molybdenum?.toSdkMass(),
+        monounsaturatedFat = monounsaturatedFat?.toSdkMass(),
+        niacin = niacin?.toSdkMass(),
+        pantothenicAcid = pantothenicAcid?.toSdkMass(),
+        phosphorus = phosphorus?.toSdkMass(),
+        polyunsaturatedFat = polyunsaturatedFat?.toSdkMass(),
+        potassium = potassium?.toSdkMass(),
+        protein = protein?.toSdkMass(),
+        riboflavin = riboflavin?.toSdkMass(),
+        saturatedFat = saturatedFat?.toSdkMass(),
+        selenium = selenium?.toSdkMass(),
+        sodium = sodium?.toSdkMass(),
+        sugar = sugar?.toSdkMass(),
+        thiamin = thiamin?.toSdkMass(),
+        totalCarbohydrate = totalCarbohydrate?.toSdkMass(),
+        totalFat = totalFat?.toSdkMass(),
+        transFat = transFat?.toSdkMass(),
+        unsaturatedFat = unsaturatedFat?.toSdkMass(),
+        vitaminA = vitaminA?.toSdkMass(),
+        vitaminB12 = vitaminB12?.toSdkMass(),
+        vitaminB6 = vitaminB6?.toSdkMass(),
+        vitaminC = vitaminC?.toSdkMass(),
+        vitaminD = vitaminD?.toSdkMass(),
+        vitaminE = vitaminE?.toSdkMass(),
+        vitaminK = vitaminK?.toSdkMass(),
+        zinc = zinc?.toSdkMass()
+    )
+
+private fun PlatformOvulationTestRecord.toSdkOvulationTestRecord() =
+    OvulationTestRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        result = result.toSdkOvulationTestResult(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformOxygenSaturationRecord.toSdkOxygenSaturationRecord() =
+    OxygenSaturationRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        percentage = percentage.toSdkPercentage(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformPowerRecord.toSdkPowerRecord() =
+    PowerRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        samples = samples.map { it.toSdkPowerRecordSample() }.sortedBy { it.time },
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformRespiratoryRateRecord.toSdkRespiratoryRateRecord() =
+    RespiratoryRateRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        rate = rate,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformRestingHeartRateRecord.toSdkRestingHeartRateRecord() =
+    RestingHeartRateRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        beatsPerMinute = beatsPerMinute,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformSexualActivityRecord.toSdkSexualActivityRecord() =
+    SexualActivityRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        protectionUsed = protectionUsed.toSdkProtectionUsed(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformSleepSessionRecord.toSdkSleepSessionRecord() =
+    SleepSessionRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        metadata = metadata.toSdkMetadata(),
+        title = title?.toString(),
+        notes = notes?.toString(),
+        stages = stages.map { it.toSdkSleepSessionStage() }.sortedBy { it.startTime },
+    )
+
+private fun PlatformSpeedRecord.toSdkSpeedRecord() =
+    SpeedRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        samples = samples.map { it.toSdkSpeedSample() }.sortedBy { it.time },
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformStepsCadenceRecord.toSdkStepsCadenceRecord() =
+    StepsCadenceRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        samples = samples.map { it.toSdkStepsCadenceSample() }.sortedBy { it.time },
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformStepsRecord.toSdkStepsRecord() =
+    StepsRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        count = count,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformTotalCaloriesBurnedRecord.toSdkTotalCaloriesBurnedRecord() =
+    TotalCaloriesBurnedRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        energy = energy.toSdkEnergy(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformVo2MaxRecord.toSdkVo2MaxRecord() =
+    Vo2MaxRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        vo2MillilitersPerMinuteKilogram = vo2MillilitersPerMinuteKilogram,
+        measurementMethod = measurementMethod.toSdkVo2MaxMeasurementMethod(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformWeightRecord.toSdkWeightRecord() =
+    WeightRecord(
+        time = time,
+        zoneOffset = zoneOffset,
+        weight = weight.toSdkMass(),
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun PlatformWheelchairPushesRecord.toWheelchairPushesRecord() =
+    WheelchairPushesRecord(
+        startTime = startTime,
+        startZoneOffset = startZoneOffset,
+        endTime = endTime,
+        endZoneOffset = endZoneOffset,
+        count = count,
+        metadata = metadata.toSdkMetadata()
+    )
+
+private fun ActiveCaloriesBurnedRecord.toPlatformActiveCaloriesBurnedRecord() =
+    PlatformActiveCaloriesBurnedRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            energy.toPlatformEnergy(),
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun BasalBodyTemperatureRecord.toPlatformBasalBodyTemperatureRecord() =
+    PlatformBasalBodyTemperatureRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            measurementLocation.toPlatformBodyTemperatureMeasurementLocation(),
+            temperature.toPlatformTemperature()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BasalMetabolicRateRecord.toPlatformBasalMetabolicRateRecord() =
+    PlatformBasalMetabolicRateRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            basalMetabolicRate.toPlatformPower()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BloodGlucoseRecord.toPlatformBloodGlucoseRecord() =
+    PlatformBloodGlucoseRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            specimenSource.toPlatformBloodGlucoseSpecimenSource(),
+            level.toPlatformBloodGlucose(),
+            relationToMeal.toPlatformBloodGlucoseRelationToMeal(),
+            mealType.toPlatformMealType()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BloodPressureRecord.toPlatformBloodPressureRecord() =
+    PlatformBloodPressureRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            measurementLocation.toPlatformBloodPressureMeasurementLocation(),
+            systolic.toPlatformPressure(),
+            diastolic.toPlatformPressure(),
+            bodyPosition.toPlatformBloodPressureBodyPosition()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BodyFatRecord.toPlatformBodyFatRecord() =
+    PlatformBodyFatRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            percentage.toPlatformPercentage()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BodyTemperatureRecord.toPlatformBodyTemperatureRecord() =
+    PlatformBodyTemperatureRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            measurementLocation.toPlatformBodyTemperatureMeasurementLocation(),
+            temperature.toPlatformTemperature()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BodyWaterMassRecord.toPlatformBodyWaterMassRecord() =
+    PlatformBodyWaterMassRecordBuilder(metadata.toPlatformMetadata(), time, mass.toPlatformMass())
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun BoneMassRecord.toPlatformBoneMassRecord() =
+    PlatformBoneMassRecordBuilder(metadata.toPlatformMetadata(), time, mass.toPlatformMass())
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun CervicalMucusRecord.toPlatformCervicalMucusRecord() =
+    PlatformCervicalMucusRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            sensation.toPlatformCervicalMucusSensation(),
+            appearance.toPlatformCervicalMucusAppearance(),
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun CyclingPedalingCadenceRecord.toPlatformCyclingPedalingCadenceRecord() =
+    PlatformCyclingPedalingCadenceRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            samples.map { it.toPlatformCyclingPedalingCadenceSample() }
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun CyclingPedalingCadenceRecord.Sample.toPlatformCyclingPedalingCadenceSample() =
+    PlatformCyclingPedalingCadenceSample(revolutionsPerMinute, time)
+
+private fun DistanceRecord.toPlatformDistanceRecord() =
+    PlatformDistanceRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            distance.toPlatformLength()
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun ElevationGainedRecord.toPlatformElevationGainedRecord() =
+    PlatformElevationGainedRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            elevation.toPlatformLength()
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun ExerciseSessionRecord.toPlatformExerciseSessionRecord() =
+    PlatformExerciseSessionRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            exerciseType.toPlatformExerciseSessionType()
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+            notes?.let { setNotes(it) }
+            title?.let { setTitle(it) }
+            route?.let { setRoute(it.toPlatformExerciseRoute()) }
+            setLaps(laps.map { it.toPlatformExerciseLap() })
+            setSegments(segments.map { it.toPlatformExerciseSegment() })
+        }
+        .build()
+
+private fun ExerciseLap.toPlatformExerciseLap() =
+    PlatformExerciseLapBuilder(startTime, endTime)
+        .apply { length?.let { setLength(it.toPlatformLength()) } }
+        .build()
+
+private fun ExerciseRoute.toPlatformExerciseRoute() =
+    PlatformExerciseRoute(
+        route.map { location ->
+            PlatformExerciseRouteLocationBuilder(
+                    location.time,
+                    location.latitude,
+                    location.longitude
+                )
+                .apply {
+                    location.horizontalAccuracy?.let {
+                        setHorizontalAccuracy(it.toPlatformLength())
+                    }
+                    location.verticalAccuracy?.let { setVerticalAccuracy(it.toPlatformLength()) }
+                    location.altitude?.let { setAltitude(it.toPlatformLength()) }
+                }
+                .build()
+        }
+    )
+
+private fun ExerciseSegment.toPlatformExerciseSegment() =
+    PlatformExerciseSegmentBuilder(startTime, endTime, segmentType.toPlatformExerciseSegmentType())
+        .setRepetitionsCount(repetitions)
+        .build()
+
+private fun FloorsClimbedRecord.toPlatformFloorsClimbedRecord() =
+    PlatformFloorsClimbedRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime, floors)
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun HeartRateRecord.toPlatformHeartRateRecord() =
+    PlatformHeartRateRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            samples.map { it.toPlatformHeartRateSample() }
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun HeartRateRecord.Sample.toPlatformHeartRateSample() =
+    PlatformHeartRateSample(beatsPerMinute, time)
+
+private fun HeartRateVariabilityRmssdRecord.toPlatformHeartRateVariabilityRmssdRecord() =
+    PlatformHeartRateVariabilityRmssdRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            heartRateVariabilityMillis
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun HeightRecord.toPlatformHeightRecord() =
+    PlatformHeightRecordBuilder(metadata.toPlatformMetadata(), time, height.toPlatformLength())
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun HydrationRecord.toPlatformHydrationRecord() =
+    PlatformHydrationRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            volume.toPlatformVolume()
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun IntermenstrualBleedingRecord.toPlatformIntermenstrualBleedingRecord() =
+    PlatformIntermenstrualBleedingRecordBuilder(metadata.toPlatformMetadata(), time)
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun LeanBodyMassRecord.toPlatformLeanBodyMassRecord() =
+    PlatformLeanBodyMassRecordBuilder(metadata.toPlatformMetadata(), time, mass.toPlatformMass())
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun MenstruationFlowRecord.toPlatformMenstruationFlowRecord() =
+    PlatformMenstruationFlowRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            flow.toPlatformMenstruationFlow()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun MenstruationPeriodRecord.toPlatformMenstruationPeriodRecord() =
+    PlatformMenstruationPeriodRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime)
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun NutritionRecord.toPlatformNutritionRecord() =
+    PlatformNutritionRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime)
+        .setMealType(mealType.toPlatformMealType())
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+            biotin?.let { setBiotin(it.toPlatformMass()) }
+            caffeine?.let { setCaffeine(it.toPlatformMass()) }
+            calcium?.let { setCalcium(it.toPlatformMass()) }
+            chloride?.let { setChloride(it.toPlatformMass()) }
+            cholesterol?.let { setCholesterol(it.toPlatformMass()) }
+            chromium?.let { setChromium(it.toPlatformMass()) }
+            copper?.let { setCopper(it.toPlatformMass()) }
+            dietaryFiber?.let { setDietaryFiber(it.toPlatformMass()) }
+            energy?.let { setEnergy(it.toPlatformEnergy()) }
+            energyFromFat?.let { setEnergyFromFat(it.toPlatformEnergy()) }
+            folate?.let { setFolate(it.toPlatformMass()) }
+            folicAcid?.let { setFolicAcid(it.toPlatformMass()) }
+            iodine?.let { setIodine(it.toPlatformMass()) }
+            iron?.let { setIron(it.toPlatformMass()) }
+            magnesium?.let { setMagnesium(it.toPlatformMass()) }
+            manganese?.let { setManganese(it.toPlatformMass()) }
+            molybdenum?.let { setMolybdenum(it.toPlatformMass()) }
+            monounsaturatedFat?.let { setMonounsaturatedFat(it.toPlatformMass()) }
+            name?.let { setMealName(it) }
+            niacin?.let { setNiacin(it.toPlatformMass()) }
+            pantothenicAcid?.let { setPantothenicAcid(it.toPlatformMass()) }
+            phosphorus?.let { setPhosphorus(it.toPlatformMass()) }
+            polyunsaturatedFat?.let { setPolyunsaturatedFat(it.toPlatformMass()) }
+            potassium?.let { setPotassium(it.toPlatformMass()) }
+            protein?.let { setProtein(it.toPlatformMass()) }
+            riboflavin?.let { setRiboflavin(it.toPlatformMass()) }
+            saturatedFat?.let { setSaturatedFat(it.toPlatformMass()) }
+            selenium?.let { setSelenium(it.toPlatformMass()) }
+            sodium?.let { setSodium(it.toPlatformMass()) }
+            sugar?.let { setSugar(it.toPlatformMass()) }
+            thiamin?.let { setThiamin(it.toPlatformMass()) }
+            totalCarbohydrate?.let { setTotalCarbohydrate(it.toPlatformMass()) }
+            totalFat?.let { setTotalFat(it.toPlatformMass()) }
+            transFat?.let { setTransFat(it.toPlatformMass()) }
+            unsaturatedFat?.let { setUnsaturatedFat(it.toPlatformMass()) }
+            vitaminA?.let { setVitaminA(it.toPlatformMass()) }
+            vitaminB6?.let { setVitaminB6(it.toPlatformMass()) }
+            vitaminB12?.let { setVitaminB12(it.toPlatformMass()) }
+            vitaminC?.let { setVitaminC(it.toPlatformMass()) }
+            vitaminD?.let { setVitaminD(it.toPlatformMass()) }
+            vitaminE?.let { setVitaminE(it.toPlatformMass()) }
+            vitaminK?.let { setVitaminK(it.toPlatformMass()) }
+            zinc?.let { setZinc(it.toPlatformMass()) }
+        }
+        .build()
+
+private fun OvulationTestRecord.toPlatformOvulationTestRecord() =
+    PlatformOvulationTestRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            result.toPlatformOvulationTestResult()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun OxygenSaturationRecord.toPlatformOxygenSaturationRecord() =
+    PlatformOxygenSaturationRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            percentage.toPlatformPercentage()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun PowerRecord.toPlatformPowerRecord() =
+    PlatformPowerRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            samples.map { it.toPlatformPowerRecordSample() }
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun PowerRecord.Sample.toPlatformPowerRecordSample() =
+    PlatformPowerRecordSample(power.toPlatformPower(), time)
+
+private fun RespiratoryRateRecord.toPlatformRespiratoryRateRecord() =
+    PlatformRespiratoryRateRecordBuilder(metadata.toPlatformMetadata(), time, rate)
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun RestingHeartRateRecord.toPlatformRestingHeartRateRecord() =
+    PlatformRestingHeartRateRecordBuilder(metadata.toPlatformMetadata(), time, beatsPerMinute)
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun SexualActivityRecord.toPlatformSexualActivityRecord() =
+    PlatformSexualActivityRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            protectionUsed.toPlatformSexualActivityProtectionUsed()
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun SleepSessionRecord.toPlatformSleepSessionRecord() =
+    PlatformSleepSessionRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime)
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+            notes?.let { setNotes(it) }
+            title?.let { setTitle(it) }
+            setStages(stages.map { it.toPlatformSleepSessionStage() })
+        }
+        .build()
+
+private fun SleepSessionRecord.Stage.toPlatformSleepSessionStage() =
+    PlatformSleepSessionStage(startTime, endTime, stage.toPlatformSleepStageType())
+
+private fun SpeedRecord.toPlatformSpeedRecord() =
+    PlatformSpeedRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            samples.map { it.toPlatformSpeedRecordSample() }
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun SpeedRecord.Sample.toPlatformSpeedRecordSample() =
+    PlatformSpeedSample(speed.toPlatformVelocity(), time)
+
+private fun StepsRecord.toPlatformStepsRecord() =
+    PlatformStepsRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime, count)
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun StepsCadenceRecord.toPlatformStepsCadenceRecord() =
+    PlatformStepsCadenceRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            samples.map { it.toPlatformStepsCadenceSample() }
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun StepsCadenceRecord.Sample.toPlatformStepsCadenceSample() =
+    PlatformStepsCadenceSample(rate, time)
+
+private fun TotalCaloriesBurnedRecord.toPlatformTotalCaloriesBurnedRecord() =
+    PlatformTotalCaloriesBurnedRecordBuilder(
+            metadata.toPlatformMetadata(),
+            startTime,
+            endTime,
+            energy.toPlatformEnergy()
+        )
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun Vo2MaxRecord.toPlatformVo2MaxRecord() =
+    PlatformVo2MaxRecordBuilder(
+            metadata.toPlatformMetadata(),
+            time,
+            measurementMethod.toPlatformVo2MaxMeasurementMethod(),
+            vo2MillilitersPerMinuteKilogram
+        )
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun WeightRecord.toPlatformWeightRecord() =
+    PlatformWeightRecordBuilder(metadata.toPlatformMetadata(), time, weight.toPlatformMass())
+        .apply { zoneOffset?.let { setZoneOffset(it) } }
+        .build()
+
+private fun WheelchairPushesRecord.toPlatformWheelchairPushesRecord() =
+    PlatformWheelchairPushesRecordBuilder(metadata.toPlatformMetadata(), startTime, endTime, count)
+        .apply {
+            startZoneOffset?.let { setStartZoneOffset(it) }
+            endZoneOffset?.let { setEndZoneOffset(it) }
+        }
+        .build()
+
+private fun PlatformCyclingPedalingCadenceSample.toSdkCyclingPedalingCadenceSample() =
+    CyclingPedalingCadenceRecord.Sample(time, revolutionsPerMinute)
+
+private fun PlatformHeartRateSample.toSdkHeartRateSample() =
+    HeartRateRecord.Sample(time, beatsPerMinute)
+
+private fun PlatformPowerRecordSample.toSdkPowerRecordSample() =
+    PowerRecord.Sample(time, power.toSdkPower())
+
+private fun PlatformSpeedSample.toSdkSpeedSample() = SpeedRecord.Sample(time, speed.toSdkVelocity())
+
+private fun PlatformStepsCadenceSample.toSdkStepsCadenceSample() =
+    StepsCadenceRecord.Sample(time, rate)
+
+private fun PlatformSleepSessionStage.toSdkSleepSessionStage() =
+    SleepSessionRecord.Stage(startTime, endTime, type.toSdkSleepStageType())
+
+internal fun PlatformExerciseRoute.toSdkExerciseRoute() =
+    ExerciseRoute(
+        routeLocations.map { value ->
+            ExerciseRoute.Location(
+                time = value.time,
+                latitude = value.latitude,
+                longitude = value.longitude,
+                horizontalAccuracy = value.horizontalAccuracy?.toSdkLength(),
+                verticalAccuracy = value.verticalAccuracy?.toSdkLength(),
+                altitude = value.altitude?.toSdkLength()
+            )
+        }
+    )
+
+internal fun PlatformExerciseLap.toSdkExerciseLap() =
+    ExerciseLap(startTime, endTime, length?.toSdkLength())
+
+internal fun PlatformExerciseSegment.toSdkExerciseSegment() =
+    ExerciseSegment(startTime, endTime, segmentType.toSdkExerciseSegmentType(), repetitionsCount)
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordMappings.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordMappings.kt
new file mode 100644
index 0000000..46d32a4
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RecordMappings.kt
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.records.ActiveCaloriesBurnedRecord
+import androidx.health.connect.client.records.BasalBodyTemperatureRecord
+import androidx.health.connect.client.records.BasalMetabolicRateRecord
+import androidx.health.connect.client.records.BloodGlucoseRecord
+import androidx.health.connect.client.records.BloodPressureRecord
+import androidx.health.connect.client.records.BodyFatRecord
+import androidx.health.connect.client.records.BodyTemperatureRecord
+import androidx.health.connect.client.records.BodyWaterMassRecord
+import androidx.health.connect.client.records.BoneMassRecord
+import androidx.health.connect.client.records.CervicalMucusRecord
+import androidx.health.connect.client.records.CyclingPedalingCadenceRecord
+import androidx.health.connect.client.records.DistanceRecord
+import androidx.health.connect.client.records.ElevationGainedRecord
+import androidx.health.connect.client.records.ExerciseSessionRecord
+import androidx.health.connect.client.records.FloorsClimbedRecord
+import androidx.health.connect.client.records.HeartRateRecord
+import androidx.health.connect.client.records.HeartRateVariabilityRmssdRecord
+import androidx.health.connect.client.records.HeightRecord
+import androidx.health.connect.client.records.HydrationRecord
+import androidx.health.connect.client.records.IntermenstrualBleedingRecord
+import androidx.health.connect.client.records.LeanBodyMassRecord
+import androidx.health.connect.client.records.MenstruationFlowRecord
+import androidx.health.connect.client.records.MenstruationPeriodRecord
+import androidx.health.connect.client.records.NutritionRecord
+import androidx.health.connect.client.records.OvulationTestRecord
+import androidx.health.connect.client.records.OxygenSaturationRecord
+import androidx.health.connect.client.records.PowerRecord
+import androidx.health.connect.client.records.Record
+import androidx.health.connect.client.records.RespiratoryRateRecord
+import androidx.health.connect.client.records.RestingHeartRateRecord
+import androidx.health.connect.client.records.SexualActivityRecord
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.SpeedRecord
+import androidx.health.connect.client.records.StepsCadenceRecord
+import androidx.health.connect.client.records.StepsRecord
+import androidx.health.connect.client.records.TotalCaloriesBurnedRecord
+import androidx.health.connect.client.records.Vo2MaxRecord
+import androidx.health.connect.client.records.WeightRecord
+import androidx.health.connect.client.records.WheelchairPushesRecord
+import kotlin.reflect.KClass
+
+internal val SDK_TO_PLATFORM_RECORD_CLASS: Map<KClass<out Record>, Class<out PlatformRecord>> =
+    mapOf(
+        ActiveCaloriesBurnedRecord::class to PlatformActiveCaloriesBurnedRecord::class.java,
+        BasalBodyTemperatureRecord::class to PlatformBasalBodyTemperatureRecord::class.java,
+        BasalMetabolicRateRecord::class to PlatformBasalMetabolicRateRecord::class.java,
+        BloodGlucoseRecord::class to PlatformBloodGlucoseRecord::class.java,
+        BloodPressureRecord::class to PlatformBloodPressureRecord::class.java,
+        BodyFatRecord::class to PlatformBodyFatRecord::class.java,
+        BodyTemperatureRecord::class to PlatformBodyTemperatureRecord::class.java,
+        BodyWaterMassRecord::class to PlatformBodyWaterMassRecord::class.java,
+        BoneMassRecord::class to PlatformBoneMassRecord::class.java,
+        CervicalMucusRecord::class to PlatformCervicalMucusRecord::class.java,
+        CyclingPedalingCadenceRecord::class to PlatformCyclingPedalingCadenceRecord::class.java,
+        DistanceRecord::class to PlatformDistanceRecord::class.java,
+        ElevationGainedRecord::class to PlatformElevationGainedRecord::class.java,
+        ExerciseSessionRecord::class to PlatformExerciseSessionRecord::class.java,
+        FloorsClimbedRecord::class to PlatformFloorsClimbedRecord::class.java,
+        HeartRateRecord::class to PlatformHeartRateRecord::class.java,
+        HeartRateVariabilityRmssdRecord::class to
+            PlatformHeartRateVariabilityRmssdRecord::class.java,
+        HeightRecord::class to PlatformHeightRecord::class.java,
+        HydrationRecord::class to PlatformHydrationRecord::class.java,
+        IntermenstrualBleedingRecord::class to PlatformIntermenstrualBleedingRecord::class.java,
+        LeanBodyMassRecord::class to PlatformLeanBodyMassRecord::class.java,
+        MenstruationFlowRecord::class to PlatformMenstruationFlowRecord::class.java,
+        MenstruationPeriodRecord::class to PlatformMenstruationPeriodRecord::class.java,
+        NutritionRecord::class to PlatformNutritionRecord::class.java,
+        OvulationTestRecord::class to PlatformOvulationTestRecord::class.java,
+        OxygenSaturationRecord::class to PlatformOxygenSaturationRecord::class.java,
+        PowerRecord::class to PlatformPowerRecord::class.java,
+        RespiratoryRateRecord::class to PlatformRespiratoryRateRecord::class.java,
+        RestingHeartRateRecord::class to PlatformRestingHeartRateRecord::class.java,
+        SexualActivityRecord::class to PlatformSexualActivityRecord::class.java,
+        SleepSessionRecord::class to PlatformSleepSessionRecord::class.java,
+        SpeedRecord::class to PlatformSpeedRecord::class.java,
+        StepsCadenceRecord::class to PlatformStepsCadenceRecord::class.java,
+        StepsRecord::class to PlatformStepsRecord::class.java,
+        TotalCaloriesBurnedRecord::class to PlatformTotalCaloriesBurnedRecord::class.java,
+        Vo2MaxRecord::class to PlatformVo2MaxRecord::class.java,
+        WeightRecord::class to PlatformWeightRecord::class.java,
+        WheelchairPushesRecord::class to PlatformWheelchairPushesRecord::class.java,
+    )
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RequestConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RequestConverters.kt
new file mode 100644
index 0000000..cce4e13
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/RequestConverters.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.health.connect.AggregateRecordsRequest
+import android.health.connect.LocalTimeRangeFilter
+import android.health.connect.ReadRecordsRequestUsingFilters
+import android.health.connect.TimeInstantRangeFilter
+import android.health.connect.TimeRangeFilter as PlatformTimeRangeFilter
+import android.health.connect.changelog.ChangeLogTokenRequest
+import android.health.connect.datatypes.AggregationType
+import android.health.connect.datatypes.Record as PlatformRecord
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.records.Record
+import androidx.health.connect.client.request.AggregateGroupByDurationRequest
+import androidx.health.connect.client.request.AggregateGroupByPeriodRequest
+import androidx.health.connect.client.request.AggregateRequest
+import androidx.health.connect.client.request.ChangesTokenRequest
+import androidx.health.connect.client.request.ReadRecordsRequest
+import androidx.health.connect.client.time.TimeRangeFilter
+import java.time.Instant
+
+fun ReadRecordsRequest<out Record>.toPlatformRequest():
+    ReadRecordsRequestUsingFilters<out PlatformRecord> {
+    return ReadRecordsRequestUsingFilters.Builder(recordType.toPlatformRecordClass())
+        .setTimeRangeFilter(timeRangeFilter.toPlatformTimeRangeFilter())
+        .setPageSize(pageSize)
+        .apply {
+            dataOriginFilter.forEach { addDataOrigins(it.toPlatformDataOrigin()) }
+            pageToken?.let { setPageToken(it.toLong()) }
+            // Platform doesn't allow setting both pageToken and ascendingOrder together.
+            if (pageToken == null) {
+                setAscending(ascendingOrder)
+            }
+        }
+        .build()
+}
+
+fun TimeRangeFilter.toPlatformTimeRangeFilter(): PlatformTimeRangeFilter {
+    return if (startTime != null || endTime != null) {
+        TimeInstantRangeFilter.Builder().setStartTime(startTime).setEndTime(endTime).build()
+    } else if (localStartTime != null || localEndTime != null) {
+        LocalTimeRangeFilter.Builder().setStartTime(localStartTime).setEndTime(localEndTime).build()
+    } else {
+        // Platform doesn't allow both startTime and endTime to be null
+        TimeInstantRangeFilter.Builder().setStartTime(Instant.EPOCH).build()
+    }
+}
+
+fun ChangesTokenRequest.toPlatformRequest(): ChangeLogTokenRequest {
+    return ChangeLogTokenRequest.Builder()
+        .apply {
+            dataOriginFilters.forEach { addDataOriginFilter(it.toPlatformDataOrigin()) }
+            recordTypes.forEach { addRecordType(it.toPlatformRecordClass()) }
+        }
+        .build()
+}
+
+fun AggregateRequest.toPlatformRequest(): AggregateRecordsRequest<Any> {
+    return AggregateRecordsRequest.Builder<Any>(timeRangeFilter.toPlatformTimeRangeFilter())
+        .apply {
+            dataOriginFilter.forEach { addDataOriginsFilter(it.toPlatformDataOrigin()) }
+            metrics.forEach { addAggregationType(it.toAggregationType()) }
+        }
+        .build()
+}
+
+fun AggregateGroupByDurationRequest.toPlatformRequest(): AggregateRecordsRequest<Any> {
+    return AggregateRecordsRequest.Builder<Any>(timeRangeFilter.toPlatformTimeRangeFilter())
+        .apply {
+            dataOriginFilter.forEach { addDataOriginsFilter(it.toPlatformDataOrigin()) }
+            metrics.forEach { addAggregationType(it.toAggregationType()) }
+        }
+        .build()
+}
+
+fun AggregateGroupByPeriodRequest.toPlatformRequest(): AggregateRecordsRequest<Any> {
+    return AggregateRecordsRequest.Builder<Any>(timeRangeFilter.toPlatformTimeRangeFilter())
+        .apply {
+            dataOriginFilter.forEach { addDataOriginsFilter(it.toPlatformDataOrigin()) }
+            metrics.forEach { addAggregationType(it.toAggregationType()) }
+        }
+        .build()
+}
+
+@Suppress("UNCHECKED_CAST")
+fun AggregateMetric<Any>.toAggregationType(): AggregationType<Any> {
+    return DOUBLE_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+        ?: DURATION_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: ENERGY_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: LENGTH_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: LONG_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: GRAMS_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: KILOGRAMS_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: POWER_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: VOLUME_AGGREGATION_METRIC_TYPE_MAP[this] as AggregationType<Any>?
+            ?: throw IllegalArgumentException("Unsupported aggregation type $metricKey")
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/ResponseConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/ResponseConverters.kt
new file mode 100644
index 0000000..d07820f
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/ResponseConverters.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.health.connect.AggregateRecordsGroupedByDurationResponse
+import android.health.connect.AggregateRecordsGroupedByPeriodResponse
+import android.health.connect.AggregateRecordsResponse
+import android.health.connect.datatypes.AggregationType
+import android.health.connect.datatypes.units.Energy as PlatformEnergy
+import android.health.connect.datatypes.units.Volume as PlatformVolume
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.health.connect.client.aggregate.AggregateMetric
+import androidx.health.connect.client.aggregate.AggregationResult
+import androidx.health.connect.client.aggregate.AggregationResultGroupedByDuration
+import androidx.health.connect.client.aggregate.AggregationResultGroupedByPeriod
+import androidx.health.connect.client.units.Energy
+import androidx.health.connect.client.units.Mass
+import java.time.ZoneOffset
+
+fun AggregateRecordsResponse<Any>.toSdkResponse(metrics: Set<AggregateMetric<Any>>) =
+    buildAggregationResult(
+        metrics,
+        ::get,
+        ::getDataOrigins,
+    )
+
+fun AggregateRecordsGroupedByDurationResponse<Any>.toSdkResponse(
+    metrics: Set<AggregateMetric<Any>>
+) =
+    AggregationResultGroupedByDuration(
+        buildAggregationResult(metrics, ::get),
+        startTime,
+        endTime,
+        getZoneOffset(metrics.first().toAggregationType())
+            ?: ZoneOffset.systemDefault().rules.getOffset(startTime)
+    )
+
+fun AggregateRecordsGroupedByPeriodResponse<Any>.toSdkResponse(metrics: Set<AggregateMetric<Any>>) =
+    AggregationResultGroupedByPeriod(buildAggregationResult(metrics, ::get), startTime, endTime)
+
+@VisibleForTesting
+internal fun buildAggregationResult(
+    metrics: Set<AggregateMetric<Any>>,
+    aggregationValueGetter: (AggregationType<Any>) -> Any?,
+    platformDataOriginsGetter: (AggregationType<Any>) -> Set<PlatformDataOrigin> = { _ ->
+        emptySet()
+    }
+): AggregationResult {
+    val metricValueMap = buildMap {
+        metrics.forEach { metric ->
+            aggregationValueGetter(metric.toAggregationType())?.also { this[metric] = it }
+        }
+    }
+    return AggregationResult(
+        getLongMetricValues(metricValueMap),
+        getDoubleMetricValues(metricValueMap),
+        metrics.flatMapTo(hashSetOf()) { metric ->
+            platformDataOriginsGetter(metric.toAggregationType()).map { it.toSdkDataOrigin() }
+        }
+    )
+}
+
+@VisibleForTesting
+internal fun getLongMetricValues(
+    metricValueMap: Map<AggregateMetric<Any>, Any>
+): Map<String, Long> {
+    return buildMap {
+        metricValueMap.forEach { (key, value) ->
+            if (
+                key in DURATION_AGGREGATION_METRIC_TYPE_MAP ||
+                    key in LONG_AGGREGATION_METRIC_TYPE_MAP
+            ) {
+                this[key.metricKey] = value as Long
+            }
+        }
+    }
+}
+
+@VisibleForTesting
+internal fun getDoubleMetricValues(
+    metricValueMap: Map<AggregateMetric<Any>, Any>
+): Map<String, Double> {
+    return buildMap {
+        metricValueMap.forEach { (key, value) ->
+            when (key) {
+                in DOUBLE_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = value as Double
+                }
+                in ENERGY_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] =
+                        Energy.calories((value as PlatformEnergy).inCalories).inKilocalories
+                }
+                in LENGTH_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = (value as PlatformLength).inMeters
+                }
+                in GRAMS_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = (value as PlatformMass).inGrams
+                }
+                in KILOGRAMS_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = Mass.grams((value as PlatformMass).inGrams).inKilograms
+                }
+                in POWER_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = (value as PlatformPower).inWatts
+                }
+                in VOLUME_AGGREGATION_METRIC_TYPE_MAP -> {
+                    this[key.metricKey] = (value as PlatformVolume).inLiters
+                }
+            }
+        }
+    }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/UnitConverters.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/UnitConverters.kt
new file mode 100644
index 0000000..c9a23f9
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/UnitConverters.kt
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+@file:RestrictTo(RestrictTo.Scope.LIBRARY)
+@file:RequiresApi(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+
+package androidx.health.connect.client.impl.platform.records
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.units.BloodGlucose
+import androidx.health.connect.client.units.Energy
+import androidx.health.connect.client.units.Length
+import androidx.health.connect.client.units.Mass
+import androidx.health.connect.client.units.Percentage
+import androidx.health.connect.client.units.Power
+import androidx.health.connect.client.units.Pressure
+import androidx.health.connect.client.units.Temperature
+import androidx.health.connect.client.units.Velocity
+import androidx.health.connect.client.units.Volume
+
+internal fun BloodGlucose.toPlatformBloodGlucose(): PlatformBloodGlucose {
+    return PlatformBloodGlucose.fromMillimolesPerLiter(inMillimolesPerLiter)
+}
+
+internal fun Energy.toPlatformEnergy(): PlatformEnergy {
+    return PlatformEnergy.fromCalories(inCalories)
+}
+
+internal fun Length.toPlatformLength(): PlatformLength {
+    return PlatformLength.fromMeters(inMeters)
+}
+
+internal fun Mass.toPlatformMass(): PlatformMass {
+    return PlatformMass.fromGrams(inGrams)
+}
+
+internal fun Percentage.toPlatformPercentage(): PlatformPercentage {
+    return PlatformPercentage.fromValue(value)
+}
+
+internal fun Power.toPlatformPower(): PlatformPower {
+    return PlatformPower.fromWatts(inWatts)
+}
+
+internal fun Pressure.toPlatformPressure(): PlatformPressure {
+    return PlatformPressure.fromMillimetersOfMercury(inMillimetersOfMercury)
+}
+
+internal fun Temperature.toPlatformTemperature(): PlatformTemperature {
+    return PlatformTemperature.fromCelsius(inCelsius)
+}
+
+internal fun Velocity.toPlatformVelocity(): PlatformVelocity {
+    return PlatformVelocity.fromMetersPerSecond(inMetersPerSecond)
+}
+
+internal fun Volume.toPlatformVolume(): PlatformVolume {
+    return PlatformVolume.fromLiters(inLiters)
+}
+
+internal fun PlatformBloodGlucose.toSdkBloodGlucose(): BloodGlucose {
+    return BloodGlucose.millimolesPerLiter(inMillimolesPerLiter)
+}
+
+internal fun PlatformEnergy.toSdkEnergy(): Energy {
+    return Energy.calories(inCalories)
+}
+
+internal fun PlatformLength.toSdkLength(): Length {
+    return Length.meters(inMeters)
+}
+
+internal fun PlatformMass.toSdkMass(): Mass {
+    return Mass.grams(inGrams)
+}
+
+internal fun PlatformPercentage.toSdkPercentage(): Percentage {
+    return Percentage(value)
+}
+
+internal fun PlatformPower.toSdkPower(): Power {
+    return Power.watts(inWatts)
+}
+
+internal fun PlatformPressure.toSdkPressure(): Pressure {
+    return Pressure.millimetersOfMercury(inMillimetersOfMercury)
+}
+
+internal fun PlatformTemperature.toSdkTemperature(): Temperature {
+    return Temperature.celsius(inCelsius)
+}
+
+internal fun PlatformVelocity.toSdkVelocity(): Velocity {
+    return Velocity.metersPerSecond(inMetersPerSecond)
+}
+
+internal fun PlatformVolume.toSdkVolume(): Volume {
+    return Volume.liters(inLiters)
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/package-info.java b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/package-info.java
new file mode 100644
index 0000000..c5b8a8e
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/records/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Helps with conversions to the platform record and API objects.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+package androidx.health.connect.client.impl.platform.records;
+
+import androidx.annotation.RestrictTo;
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/InsertRecordsResponseConverter.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/InsertRecordsResponseConverter.kt
new file mode 100644
index 0000000..10903a2
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/InsertRecordsResponseConverter.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:RequiresApi(api = 34)
+
+package androidx.health.connect.client.impl.platform.response
+
+import android.health.connect.InsertRecordsResponse
+import androidx.annotation.RequiresApi
+
+internal fun InsertRecordsResponse.toKtResponse():
+    androidx.health.connect.client.response.InsertRecordsResponse {
+    return androidx.health.connect.client.response.InsertRecordsResponse(
+        recordIdsList = records.map { record -> record.metadata.id }
+    )
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/package-info.java b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/package-info.java
new file mode 100644
index 0000000..f8b9cb7
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/platform/response/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Helps with conversions to the platform record and API objects.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+package androidx.health.connect.client.impl.platform.response;
+
+import androidx.annotation.RestrictTo;
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
index 5103509..d09bd4e 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/HealthPermission.kt
@@ -129,138 +129,128 @@
             return WRITE_PERMISSION_PREFIX + RECORD_TYPE_TO_PERMISSION.getOrDefault(recordType, "")
         }
 
+        internal const val PERMISSION_PREFIX = "android.permission.health."
+
         // Read permissions for ACTIVITY.
         internal const val READ_ACTIVE_CALORIES_BURNED =
-            "android.permission.health.READ_ACTIVE_CALORIES_BURNED"
-        internal const val READ_DISTANCE = "android.permission.health.READ_DISTANCE"
-        internal const val READ_ELEVATION_GAINED = "android.permission.health.READ_ELEVATION_GAINED"
-        internal const val READ_EXERCISE = "android.permission.health.READ_EXERCISE"
-        internal const val READ_FLOORS_CLIMBED = "android.permission.health.READ_FLOORS_CLIMBED"
-        internal const val READ_STEPS = "android.permission.health.READ_STEPS"
+            PERMISSION_PREFIX + "READ_ACTIVE_CALORIES_BURNED"
+        internal const val READ_DISTANCE = PERMISSION_PREFIX + "READ_DISTANCE"
+        internal const val READ_ELEVATION_GAINED = PERMISSION_PREFIX + "READ_ELEVATION_GAINED"
+        internal const val READ_EXERCISE = PERMISSION_PREFIX + "READ_EXERCISE"
+        internal const val READ_FLOORS_CLIMBED = PERMISSION_PREFIX + "READ_FLOORS_CLIMBED"
+        internal const val READ_STEPS = PERMISSION_PREFIX + "READ_STEPS"
         internal const val READ_TOTAL_CALORIES_BURNED =
-            "android.permission.health.READ_TOTAL_CALORIES_BURNED"
-        internal const val READ_VO2_MAX = "android.permission.health.READ_VO2_MAX"
-        internal const val READ_WHEELCHAIR_PUSHES =
-            "android.permission.health.READ_WHEELCHAIR_PUSHES"
-        internal const val READ_POWER = "android.permission.health.READ_POWER"
-        internal const val READ_SPEED = "android.permission.health.READ_SPEED"
+            PERMISSION_PREFIX + "READ_TOTAL_CALORIES_BURNED"
+        internal const val READ_VO2_MAX = PERMISSION_PREFIX + "READ_VO2_MAX"
+        internal const val READ_WHEELCHAIR_PUSHES = PERMISSION_PREFIX + "READ_WHEELCHAIR_PUSHES"
+        internal const val READ_POWER = PERMISSION_PREFIX + "READ_POWER"
+        internal const val READ_SPEED = PERMISSION_PREFIX + "READ_SPEED"
 
         // Read permissions for BODY_MEASUREMENTS.
         internal const val READ_BASAL_METABOLIC_RATE =
-            "android.permission.health.READ_BASAL_METABOLIC_RATE"
-        internal const val READ_BODY_FAT = "android.permission.health.READ_BODY_FAT"
-        internal const val READ_BODY_WATER_MASS = "android.permission.health.READ_BODY_WATER_MASS"
-        internal const val READ_BONE_MASS = "android.permission.health.READ_BONE_MASS"
-        internal const val READ_HEIGHT = "android.permission.health.READ_HEIGHT"
+            PERMISSION_PREFIX + "READ_BASAL_METABOLIC_RATE"
+        internal const val READ_BODY_FAT = PERMISSION_PREFIX + "READ_BODY_FAT"
+        internal const val READ_BODY_WATER_MASS = PERMISSION_PREFIX + "READ_BODY_WATER_MASS"
+        internal const val READ_BONE_MASS = PERMISSION_PREFIX + "READ_BONE_MASS"
+        internal const val READ_HEIGHT = PERMISSION_PREFIX + "READ_HEIGHT"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
-        internal const val READ_HIP_CIRCUMFERENCE =
-            "android.permission.health.READ_HIP_CIRCUMFERENCE"
-        internal const val READ_LEAN_BODY_MASS = "android.permission.health.READ_LEAN_BODY_MASS"
+        internal const val READ_HIP_CIRCUMFERENCE = PERMISSION_PREFIX + "READ_HIP_CIRCUMFERENCE"
+        internal const val READ_LEAN_BODY_MASS = PERMISSION_PREFIX + "READ_LEAN_BODY_MASS"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
-        internal const val READ_WAIST_CIRCUMFERENCE =
-            "android.permission.health.READ_WAIST_CIRCUMFERENCE"
-        internal const val READ_WEIGHT = "android.permission.health.READ_WEIGHT"
+        internal const val READ_WAIST_CIRCUMFERENCE = PERMISSION_PREFIX + "READ_WAIST_CIRCUMFERENCE"
+        internal const val READ_WEIGHT = PERMISSION_PREFIX + "READ_WEIGHT"
 
         // Read permissions for CYCLE_TRACKING.
-        internal const val READ_CERVICAL_MUCUS = "android.permission.health.READ_CERVICAL_MUCUS"
+        internal const val READ_CERVICAL_MUCUS = PERMISSION_PREFIX + "READ_CERVICAL_MUCUS"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
         internal const val READ_INTERMENSTRUAL_BLEEDING =
-            "android.permission.health.READ_INTERMENSTRUAL_BLEEDING"
-        internal const val READ_MENSTRUATION = "android.permission.health.READ_MENSTRUATION"
-        internal const val READ_OVULATION_TEST = "android.permission.health.READ_OVULATION_TEST"
-        internal const val READ_SEXUAL_ACTIVITY = "android.permission.health.READ_SEXUAL_ACTIVITY"
+            PERMISSION_PREFIX + "READ_INTERMENSTRUAL_BLEEDING"
+        internal const val READ_MENSTRUATION = PERMISSION_PREFIX + "READ_MENSTRUATION"
+        internal const val READ_OVULATION_TEST = PERMISSION_PREFIX + "READ_OVULATION_TEST"
+        internal const val READ_SEXUAL_ACTIVITY = PERMISSION_PREFIX + "READ_SEXUAL_ACTIVITY"
 
         // Read permissions for NUTRITION.
-        internal const val READ_HYDRATION = "android.permission.health.READ_HYDRATION"
-        internal const val READ_NUTRITION = "android.permission.health.READ_NUTRITION"
+        internal const val READ_HYDRATION = PERMISSION_PREFIX + "READ_HYDRATION"
+        internal const val READ_NUTRITION = PERMISSION_PREFIX + "READ_NUTRITION"
 
         // Read permissions for SLEEP.
-        internal const val READ_SLEEP = "android.permission.health.READ_SLEEP"
+        internal const val READ_SLEEP = PERMISSION_PREFIX + "READ_SLEEP"
 
         // Read permissions for VITALS.
         internal const val READ_BASAL_BODY_TEMPERATURE =
-            "android.permission.health.READ_BASAL_BODY_TEMPERATURE"
-        internal const val READ_BLOOD_GLUCOSE = "android.permission.health.READ_BLOOD_GLUCOSE"
-        internal const val READ_BLOOD_PRESSURE = "android.permission.health.READ_BLOOD_PRESSURE"
-        internal const val READ_BODY_TEMPERATURE = "android.permission.health.READ_BODY_TEMPERATURE"
-        internal const val READ_HEART_RATE = "android.permission.health.READ_HEART_RATE"
+            PERMISSION_PREFIX + "READ_BASAL_BODY_TEMPERATURE"
+        internal const val READ_BLOOD_GLUCOSE = PERMISSION_PREFIX + "READ_BLOOD_GLUCOSE"
+        internal const val READ_BLOOD_PRESSURE = PERMISSION_PREFIX + "READ_BLOOD_PRESSURE"
+        internal const val READ_BODY_TEMPERATURE = PERMISSION_PREFIX + "READ_BODY_TEMPERATURE"
+        internal const val READ_HEART_RATE = PERMISSION_PREFIX + "READ_HEART_RATE"
         internal const val READ_HEART_RATE_VARIABILITY =
-            "android.permission.health.READ_HEART_RATE_VARIABILITY"
-        internal const val READ_OXYGEN_SATURATION =
-            "android.permission.health.READ_OXYGEN_SATURATION"
-        internal const val READ_RESPIRATORY_RATE = "android.permission.health.READ_RESPIRATORY_RATE"
-        internal const val READ_RESTING_HEART_RATE =
-            "android.permission.health.READ_RESTING_HEART_RATE"
+            PERMISSION_PREFIX + "READ_HEART_RATE_VARIABILITY"
+        internal const val READ_OXYGEN_SATURATION = PERMISSION_PREFIX + "READ_OXYGEN_SATURATION"
+        internal const val READ_RESPIRATORY_RATE = PERMISSION_PREFIX + "READ_RESPIRATORY_RATE"
+        internal const val READ_RESTING_HEART_RATE = PERMISSION_PREFIX + "READ_RESTING_HEART_RATE"
 
         // Write permissions for ACTIVITY.
         internal const val WRITE_ACTIVE_CALORIES_BURNED =
-            "android.permission.health.WRITE_ACTIVE_CALORIES_BURNED"
-        internal const val WRITE_DISTANCE = "android.permission.health.WRITE_DISTANCE"
-        internal const val WRITE_ELEVATION_GAINED =
-            "android.permission.health.WRITE_ELEVATION_GAINED"
-        internal const val WRITE_EXERCISE = "android.permission.health.WRITE_EXERCISE"
-        internal const val WRITE_EXERCISE_ROUTE = "android.permission.health.WRITE_EXERCISE_ROUTE"
-        internal const val WRITE_FLOORS_CLIMBED = "android.permission.health.WRITE_FLOORS_CLIMBED"
-        internal const val WRITE_STEPS = "android.permission.health.WRITE_STEPS"
+            PERMISSION_PREFIX + "WRITE_ACTIVE_CALORIES_BURNED"
+        internal const val WRITE_DISTANCE = PERMISSION_PREFIX + "WRITE_DISTANCE"
+        internal const val WRITE_ELEVATION_GAINED = PERMISSION_PREFIX + "WRITE_ELEVATION_GAINED"
+        internal const val WRITE_EXERCISE = PERMISSION_PREFIX + "WRITE_EXERCISE"
+        internal const val WRITE_EXERCISE_ROUTE = PERMISSION_PREFIX + "WRITE_EXERCISE_ROUTE"
+        internal const val WRITE_FLOORS_CLIMBED = PERMISSION_PREFIX + "WRITE_FLOORS_CLIMBED"
+        internal const val WRITE_STEPS = PERMISSION_PREFIX + "WRITE_STEPS"
         internal const val WRITE_TOTAL_CALORIES_BURNED =
-            "android.permission.health.WRITE_TOTAL_CALORIES_BURNED"
-        internal const val WRITE_VO2_MAX = "android.permission.health.WRITE_VO2_MAX"
-        internal const val WRITE_WHEELCHAIR_PUSHES =
-            "android.permission.health.WRITE_WHEELCHAIR_PUSHES"
-        internal const val WRITE_POWER = "android.permission.health.WRITE_POWER"
-        internal const val WRITE_SPEED = "android.permission.health.WRITE_SPEED"
+            PERMISSION_PREFIX + "WRITE_TOTAL_CALORIES_BURNED"
+        internal const val WRITE_VO2_MAX = PERMISSION_PREFIX + "WRITE_VO2_MAX"
+        internal const val WRITE_WHEELCHAIR_PUSHES = PERMISSION_PREFIX + "WRITE_WHEELCHAIR_PUSHES"
+        internal const val WRITE_POWER = PERMISSION_PREFIX + "WRITE_POWER"
+        internal const val WRITE_SPEED = PERMISSION_PREFIX + "WRITE_SPEED"
 
         // Write permissions for BODY_MEASUREMENTS.
         internal const val WRITE_BASAL_METABOLIC_RATE =
-            "android.permission.health.WRITE_BASAL_METABOLIC_RATE"
-        internal const val WRITE_BODY_FAT = "android.permission.health.WRITE_BODY_FAT"
-        internal const val WRITE_BODY_WATER_MASS = "android.permission.health.WRITE_BODY_WATER_MASS"
-        internal const val WRITE_BONE_MASS = "android.permission.health.WRITE_BONE_MASS"
-        internal const val WRITE_HEIGHT = "android.permission.health.WRITE_HEIGHT"
+            PERMISSION_PREFIX + "WRITE_BASAL_METABOLIC_RATE"
+        internal const val WRITE_BODY_FAT = PERMISSION_PREFIX + "WRITE_BODY_FAT"
+        internal const val WRITE_BODY_WATER_MASS = PERMISSION_PREFIX + "WRITE_BODY_WATER_MASS"
+        internal const val WRITE_BONE_MASS = PERMISSION_PREFIX + "WRITE_BONE_MASS"
+        internal const val WRITE_HEIGHT = PERMISSION_PREFIX + "WRITE_HEIGHT"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
-        internal const val WRITE_HIP_CIRCUMFERENCE =
-            "android.permission.health.WRITE_HIP_CIRCUMFERENCE"
-        internal const val WRITE_LEAN_BODY_MASS = "android.permission.health.WRITE_LEAN_BODY_MASS"
+        internal const val WRITE_HIP_CIRCUMFERENCE = PERMISSION_PREFIX + "WRITE_HIP_CIRCUMFERENCE"
+        internal const val WRITE_LEAN_BODY_MASS = PERMISSION_PREFIX + "WRITE_LEAN_BODY_MASS"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
         internal const val WRITE_WAIST_CIRCUMFERENCE =
-            "android.permission.health.WRITE_WAIST_CIRCUMFERENCE"
-        internal const val WRITE_WEIGHT = "android.permission.health.WRITE_WEIGHT"
+            PERMISSION_PREFIX + "WRITE_WAIST_CIRCUMFERENCE"
+        internal const val WRITE_WEIGHT = PERMISSION_PREFIX + "WRITE_WEIGHT"
 
         // Write permissions for CYCLE_TRACKING.
-        internal const val WRITE_CERVICAL_MUCUS = "android.permission.health.WRITE_CERVICAL_MUCUS"
+        internal const val WRITE_CERVICAL_MUCUS = PERMISSION_PREFIX + "WRITE_CERVICAL_MUCUS"
         @RestrictTo(RestrictTo.Scope.LIBRARY)
         internal const val WRITE_INTERMENSTRUAL_BLEEDING =
-            "android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING"
-        internal const val WRITE_MENSTRUATION = "android.permission.health.WRITE_MENSTRUATION"
-        internal const val WRITE_OVULATION_TEST = "android.permission.health.WRITE_OVULATION_TEST"
-        internal const val WRITE_SEXUAL_ACTIVITY = "android.permission.health.WRITE_SEXUAL_ACTIVITY"
+            PERMISSION_PREFIX + "WRITE_INTERMENSTRUAL_BLEEDING"
+        internal const val WRITE_MENSTRUATION = PERMISSION_PREFIX + "WRITE_MENSTRUATION"
+        internal const val WRITE_OVULATION_TEST = PERMISSION_PREFIX + "WRITE_OVULATION_TEST"
+        internal const val WRITE_SEXUAL_ACTIVITY = PERMISSION_PREFIX + "WRITE_SEXUAL_ACTIVITY"
 
         // Write permissions for NUTRITION.
-        internal const val WRITE_HYDRATION = "android.permission.health.WRITE_HYDRATION"
-        internal const val WRITE_NUTRITION = "android.permission.health.WRITE_NUTRITION"
+        internal const val WRITE_HYDRATION = PERMISSION_PREFIX + "WRITE_HYDRATION"
+        internal const val WRITE_NUTRITION = PERMISSION_PREFIX + "WRITE_NUTRITION"
 
         // Write permissions for SLEEP.
-        internal const val WRITE_SLEEP = "android.permission.health.WRITE_SLEEP"
+        internal const val WRITE_SLEEP = PERMISSION_PREFIX + "WRITE_SLEEP"
 
         // Write permissions for VITALS.
         internal const val WRITE_BASAL_BODY_TEMPERATURE =
-            "android.permission.health.WRITE_BASAL_BODY_TEMPERATURE"
-        internal const val WRITE_BLOOD_GLUCOSE = "android.permission.health.WRITE_BLOOD_GLUCOSE"
-        internal const val WRITE_BLOOD_PRESSURE = "android.permission.health.WRITE_BLOOD_PRESSURE"
-        internal const val WRITE_BODY_TEMPERATURE =
-            "android.permission.health.WRITE_BODY_TEMPERATURE"
-        internal const val WRITE_HEART_RATE = "android.permission.health.WRITE_HEART_RATE"
+            PERMISSION_PREFIX + "WRITE_BASAL_BODY_TEMPERATURE"
+        internal const val WRITE_BLOOD_GLUCOSE = PERMISSION_PREFIX + "WRITE_BLOOD_GLUCOSE"
+        internal const val WRITE_BLOOD_PRESSURE = PERMISSION_PREFIX + "WRITE_BLOOD_PRESSURE"
+        internal const val WRITE_BODY_TEMPERATURE = PERMISSION_PREFIX + "WRITE_BODY_TEMPERATURE"
+        internal const val WRITE_HEART_RATE = PERMISSION_PREFIX + "WRITE_HEART_RATE"
         internal const val WRITE_HEART_RATE_VARIABILITY =
-            "android.permission.health.WRITE_HEART_RATE_VARIABILITY"
-        internal const val WRITE_OXYGEN_SATURATION =
-            "android.permission.health.WRITE_OXYGEN_SATURATION"
-        internal const val WRITE_RESPIRATORY_RATE =
-            "android.permission.health.WRITE_RESPIRATORY_RATE"
-        internal const val WRITE_RESTING_HEART_RATE =
-            "android.permission.health.WRITE_RESTING_HEART_RATE"
+            PERMISSION_PREFIX + "WRITE_HEART_RATE_VARIABILITY"
+        internal const val WRITE_OXYGEN_SATURATION = PERMISSION_PREFIX + "WRITE_OXYGEN_SATURATION"
+        internal const val WRITE_RESPIRATORY_RATE = PERMISSION_PREFIX + "WRITE_RESPIRATORY_RATE"
+        internal const val WRITE_RESTING_HEART_RATE = PERMISSION_PREFIX + "WRITE_RESTING_HEART_RATE"
 
-        internal const val READ_PERMISSION_PREFIX = "android.permission.health.READ_"
-        internal const val WRITE_PERMISSION_PREFIX = "android.permission.health.WRITE_"
+        internal const val READ_PERMISSION_PREFIX = PERMISSION_PREFIX + "READ_"
+        internal const val WRITE_PERMISSION_PREFIX = PERMISSION_PREFIX + "WRITE_"
 
         internal val RECORD_TYPE_TO_PERMISSION =
             mapOf<KClass<out Record>, String>(
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCake.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCake.kt
new file mode 100644
index 0000000..e6994c5
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCake.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.health.connect.client.permission.platform
+
+import android.content.Context
+import android.content.Intent
+import androidx.activity.result.contract.ActivityResultContract
+import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.permission.HealthPermission.Companion.PERMISSION_PREFIX
+
+/**
+ * An [ActivityResultContract] to request Health Connect system permissions.
+ *
+ * @see androidx.activity.ComponentActivity.registerForActivityResult
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+internal class HealthDataRequestPermissionsUpsideDownCake :
+    ActivityResultContract<Set<String>, Set<String>>() {
+
+    private val requestPermissions = RequestMultiplePermissions()
+
+    override fun createIntent(context: Context, input: Set<String>): Intent {
+        require(input.all { it.startsWith(PERMISSION_PREFIX) }) {
+            "Unsupported health connect permission"
+        }
+        return requestPermissions.createIntent(context, input.toTypedArray())
+    }
+
+    override fun parseResult(resultCode: Int, intent: Intent?): Set<String> =
+        requestPermissions.parseResult(resultCode, intent).filterValues { it }.keys
+
+    override fun getSynchronousResult(
+        context: Context,
+        input: Set<String>,
+    ): SynchronousResult<Set<String>>? =
+        requestPermissions.getSynchronousResult(context, input.toTypedArray())?.let { result ->
+            SynchronousResult(result.value.filterValues { it }.keys)
+        }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/RequestExerciseRouteUpsideDownCake.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/RequestExerciseRouteUpsideDownCake.kt
new file mode 100644
index 0000000..8582568
--- /dev/null
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/permission/platform/RequestExerciseRouteUpsideDownCake.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.health.connect.client.permission.platform
+
+import android.content.Context
+import android.content.Intent
+import android.health.connect.HealthConnectManager
+import androidx.activity.result.contract.ActivityResultContract
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.health.connect.client.HealthConnectClient
+import androidx.health.connect.client.impl.platform.records.PlatformExerciseRoute
+import androidx.health.connect.client.impl.platform.records.toSdkExerciseRoute
+import androidx.health.connect.client.records.ExerciseRoute
+import androidx.health.platform.client.impl.logger.Logger
+
+/**
+ * An [ActivityResultContract] to request a route associated with an {@code ExerciseSessionRecord}.
+ *
+ * @see androidx.activity.ComponentActivity.registerForActivityResult
+ */
+@RequiresApi(34)
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+internal class RequestExerciseRouteUpsideDownCake :
+    ActivityResultContract<String?, ExerciseRoute?>() {
+    override fun createIntent(context: Context, input: String?): Intent {
+        require(!input.isNullOrEmpty()) { "Session identifier is required" }
+        return Intent(HealthConnectManager.ACTION_REQUEST_EXERCISE_ROUTE).apply {
+            putExtra(HealthConnectManager.EXTRA_SESSION_ID, input)
+        }
+    }
+
+    override fun parseResult(resultCode: Int, intent: Intent?): ExerciseRoute? {
+        val route =
+            intent?.getParcelableExtra(
+                HealthConnectManager.EXTRA_EXERCISE_ROUTE,
+                PlatformExerciseRoute::class.java
+            )
+        if (route == null) {
+            Logger.debug(HealthConnectClient.HEALTH_CONNECT_CLIENT_TAG, "No route returned.")
+            return null
+        }
+        Logger.debug(HealthConnectClient.HEALTH_CONNECT_CLIENT_TAG, "Returned a route.")
+        return route.toSdkExerciseRoute()
+    }
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/BodyTemperatureMeasurementLocation.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/BodyTemperatureMeasurementLocation.kt
index 6b77845..1b4c836 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/BodyTemperatureMeasurementLocation.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/BodyTemperatureMeasurementLocation.kt
@@ -67,8 +67,10 @@
 
 /**
  * Where on the user's body a temperature measurement was taken from.
+ *
  * @suppress
  */
+@Target(AnnotationTarget.PROPERTY, AnnotationTarget.TYPE)
 @Retention(AnnotationRetention.SOURCE)
 @IntDef(
     value =
diff --git a/health/connect/connect-client/src/main/java/androidx/health/platform/client/SdkConfig.java b/health/connect/connect-client/src/main/java/androidx/health/platform/client/SdkConfig.java
index 674c27b..f87e208 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/platform/client/SdkConfig.java
+++ b/health/connect/connect-client/src/main/java/androidx/health/platform/client/SdkConfig.java
@@ -24,7 +24,7 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 public final class SdkConfig {
     // should be increased everytime a new SDK is released
-    public static final int SDK_VERSION = 12;
+    public static final int SDK_VERSION = 112;
 
     private SdkConfig() {}
 }
diff --git a/health/connect/connect-client/src/main/java/androidx/health/platform/client/impl/sdkservice/HealthDataSdkService.java b/health/connect/connect-client/src/main/java/androidx/health/platform/client/impl/sdkservice/HealthDataSdkService.java
index ad6a2a9..5ae90a7 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/platform/client/impl/sdkservice/HealthDataSdkService.java
+++ b/health/connect/connect-client/src/main/java/androidx/health/platform/client/impl/sdkservice/HealthDataSdkService.java
@@ -49,6 +49,7 @@
                         new ThreadFactoryBuilder()
                                 .setNameFormat("HealthData-HealthDataSdkService-%d")
                                 .build());
-        return new HealthDataSdkServiceStubImpl(this, executor);
+        // Pass application context to avoid leaking the service.
+        return new HealthDataSdkServiceStubImpl(this.getApplicationContext(), executor);
     }
 }
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
index d839bb1..2b6a910 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/HealthConnectClientTest.kt
@@ -21,6 +21,7 @@
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageInfo
 import android.os.Build
+import androidx.health.connect.client.impl.HealthConnectClientImpl
 import androidx.health.platform.client.HealthDataService
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -50,10 +51,7 @@
     @Suppress("Deprecation")
     fun noBackingImplementation_unavailable() {
         val packageManager = context.packageManager
-        Shadows.shadowOf(packageManager).removePackage(PROVIDER_PACKAGE_NAME)
-        assertThat(HealthConnectClient.isApiSupported()).isTrue()
-        assertThat(HealthConnectClient.isProviderAvailable(context, PROVIDER_PACKAGE_NAME))
-            .isFalse()
+        shadowOf(packageManager).removePackage(PROVIDER_PACKAGE_NAME)
         assertThat(HealthConnectClient.getSdkStatus(context, PROVIDER_PACKAGE_NAME))
             .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED)
         assertThrows(IllegalStateException::class.java) {
@@ -65,9 +63,12 @@
     @Config(sdk = [Build.VERSION_CODES.P])
     @Suppress("Deprecation")
     fun backingImplementation_notEnabled_unavailable() {
-        installPackage(context, PROVIDER_PACKAGE_NAME, versionCode = 35001, enabled = false)
-        assertThat(HealthConnectClient.isProviderAvailable(context, PROVIDER_PACKAGE_NAME))
-            .isFalse()
+        installPackage(
+            context,
+            PROVIDER_PACKAGE_NAME,
+            versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE,
+            enabled = false
+        )
         assertThat(HealthConnectClient.getSdkStatus(context, PROVIDER_PACKAGE_NAME))
             .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED)
         assertThrows(IllegalStateException::class.java) {
@@ -79,9 +80,12 @@
     @Config(sdk = [Build.VERSION_CODES.P])
     @Suppress("Deprecation")
     fun backingImplementation_enabledNoService_unavailable() {
-        installPackage(context, PROVIDER_PACKAGE_NAME, versionCode = 35001, enabled = true)
-        assertThat(HealthConnectClient.isProviderAvailable(context, PROVIDER_PACKAGE_NAME))
-            .isFalse()
+        installPackage(
+            context,
+            PROVIDER_PACKAGE_NAME,
+            versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE,
+            enabled = true
+        )
         assertThat(HealthConnectClient.getSdkStatus(context, PROVIDER_PACKAGE_NAME))
             .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED)
         assertThrows(IllegalStateException::class.java) {
@@ -97,15 +101,13 @@
             context,
             HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME,
             versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE - 1,
-            enabled = true)
+            enabled = true
+        )
         installService(context, HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME)
 
-        assertThat(HealthConnectClient.isProviderAvailable(context)).isFalse()
         assertThat(HealthConnectClient.getSdkStatus(context, PROVIDER_PACKAGE_NAME))
             .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED)
-        assertThrows(IllegalStateException::class.java) {
-            HealthConnectClient.getOrCreate(context)
-        }
+        assertThrows(IllegalStateException::class.java) { HealthConnectClient.getOrCreate(context) }
     }
 
     @Test
@@ -116,23 +118,48 @@
             context,
             HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME,
             versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE,
-            enabled = true)
+            enabled = true
+        )
         installService(context, HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME)
 
-        assertThat(HealthConnectClient.isProviderAvailable(context)).isTrue()
-        assertThat(HealthConnectClient.getSdkStatus(
-            context, HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME))
+        assertThat(
+                HealthConnectClient.getSdkStatus(
+                    context,
+                    HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME
+                )
+            )
             .isEqualTo(HealthConnectClient.SDK_AVAILABLE)
-        HealthConnectClient.getOrCreate(context)
+        assertThat(HealthConnectClient.getOrCreate(context))
+            .isInstanceOf(HealthConnectClientImpl::class.java)
+    }
+
+    @Test
+    @Config(sdk = [Build.VERSION_CODES.P])
+    @Suppress("Deprecation")
+    fun backingImplementationLegacy_enabledSupportedVersion_isAvailable() {
+        installPackage(
+            context,
+            HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME,
+            versionCode = HealthConnectClient.DEFAULT_PROVIDER_MIN_VERSION_CODE,
+            enabled = true
+        )
+        installService(context, HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME)
+
+        assertThat(
+                HealthConnectClient.getSdkStatusLegacy(
+                    context,
+                    HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME
+                )
+            )
+            .isEqualTo(HealthConnectClient.SDK_AVAILABLE)
+        assertThat(HealthConnectClient.getOrCreateLegacy(context))
+            .isInstanceOf(HealthConnectClientImpl::class.java)
     }
 
     @Test
     @Config(sdk = [Build.VERSION_CODES.O_MR1])
     @Suppress("Deprecation")
     fun sdkVersionTooOld_unavailable() {
-        assertThat(HealthConnectClient.isApiSupported()).isFalse()
-        assertThat(HealthConnectClient.isProviderAvailable(context, PROVIDER_PACKAGE_NAME))
-            .isFalse()
         assertThat(HealthConnectClient.getSdkStatus(context, PROVIDER_PACKAGE_NAME))
             .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE)
         assertThrows(UnsupportedOperationException::class.java) {
@@ -140,6 +167,17 @@
         }
     }
 
+    @Test
+    @Config(sdk = [Build.VERSION_CODES.O_MR1])
+    @Suppress("Deprecation")
+    fun sdkVersionTooOld_legacyClient_unavailable() {
+        assertThat(HealthConnectClient.getSdkStatusLegacy(context, PROVIDER_PACKAGE_NAME))
+            .isEqualTo(HealthConnectClient.SDK_UNAVAILABLE)
+        assertThrows(UnsupportedOperationException::class.java) {
+            HealthConnectClient.getOrCreateLegacy(context, PROVIDER_PACKAGE_NAME)
+        }
+    }
+
     private fun installPackage(
         context: Context,
         packageName: String,
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/PermissionControllerTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/PermissionControllerTest.kt
index f0d031bc..00482f1 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/connect/client/PermissionControllerTest.kt
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/PermissionControllerTest.kt
@@ -17,13 +17,16 @@
 package androidx.health.connect.client
 
 import android.content.Context
+import android.os.Build.VERSION_CODES
+import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
 import androidx.health.connect.client.permission.HealthPermission
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
 
 private const val PROVIDER_PACKAGE_NAME = "com.example.fake.provider"
 
@@ -38,7 +41,7 @@
     }
 
     @Test
-    fun createIntentTest_permissionStrings() {
+    fun createIntent_permissionStrings() {
         val requestPermissionContract =
             PermissionController.createRequestPermissionResultContract(PROVIDER_PACKAGE_NAME)
         val intent =
@@ -47,7 +50,40 @@
                 setOf(HealthPermission.READ_ACTIVE_CALORIES_BURNED)
             )
 
-        Truth.assertThat(intent.action).isEqualTo("androidx.health.ACTION_REQUEST_PERMISSIONS")
-        Truth.assertThat(intent.`package`).isEqualTo(PROVIDER_PACKAGE_NAME)
+        assertThat(intent.action).isEqualTo("androidx.health.ACTION_REQUEST_PERMISSIONS")
+        assertThat(intent.`package`).isEqualTo(PROVIDER_PACKAGE_NAME)
+    }
+
+    @Test
+    @Config(minSdk = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    fun createIntent_UpsideDownCake() {
+        val requestPermissionContract =
+            PermissionController.createRequestPermissionResultContract(PROVIDER_PACKAGE_NAME)
+        val intent =
+            requestPermissionContract.createIntent(
+                context,
+                setOf(HealthPermission.WRITE_STEPS, HealthPermission.READ_DISTANCE)
+            )
+
+        assertThat(intent.action).isEqualTo(RequestMultiplePermissions.ACTION_REQUEST_PERMISSIONS)
+        assertThat(intent.getStringArrayExtra(RequestMultiplePermissions.EXTRA_PERMISSIONS))
+            .asList()
+            .containsExactly(HealthPermission.WRITE_STEPS, HealthPermission.READ_DISTANCE)
+        assertThat(intent.`package`).isNull()
+    }
+
+    @Test
+    @Config(minSdk = VERSION_CODES.UPSIDE_DOWN_CAKE)
+    fun createIntentLegacy_UpsideDownCake() {
+        val requestPermissionContract =
+            PermissionController.createRequestPermissionResultContractLegacy(PROVIDER_PACKAGE_NAME)
+        val intent =
+            requestPermissionContract.createIntent(
+                context,
+                setOf(HealthPermission.WRITE_STEPS, HealthPermission.READ_DISTANCE)
+            )
+
+        assertThat(intent.action).isEqualTo("androidx.health.ACTION_REQUEST_PERMISSIONS")
+        assertThat(intent.`package`).isEqualTo(PROVIDER_PACKAGE_NAME)
     }
 }
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCakeTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCakeTest.kt
new file mode 100644
index 0000000..2bbd4f4
--- /dev/null
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/permission/platform/HealthDataRequestPermissionsUpsideDownCakeTest.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.health.connect.client.permission.platform
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
+import androidx.health.connect.client.permission.HealthPermission
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class HealthDataRequestPermissionsUpsideDownCakeTest {
+
+    private lateinit var context: Context
+
+    @Before
+    fun setUp() {
+        context = ApplicationProvider.getApplicationContext()
+    }
+
+    @Test
+    fun createIntent() {
+        val requestPermissionContract = HealthDataRequestPermissionsUpsideDownCake()
+        val intent =
+            requestPermissionContract.createIntent(
+                context, setOf(HealthPermission.READ_STEPS, HealthPermission.WRITE_DISTANCE))
+
+        assertThat(intent.action).isEqualTo(RequestMultiplePermissions.ACTION_REQUEST_PERMISSIONS)
+        assertThat(intent.getStringArrayExtra(RequestMultiplePermissions.EXTRA_PERMISSIONS))
+            .asList()
+            .containsExactly(HealthPermission.READ_STEPS, HealthPermission.WRITE_DISTANCE)
+    }
+
+    @Test
+    fun createIntent_nonHealthPermission_throwsIAE() {
+        val requestPermissionContract = HealthDataRequestPermissionsUpsideDownCake()
+        assertFailsWith<IllegalArgumentException> {
+            requestPermissionContract.createIntent(
+                context, setOf(HealthPermission.READ_STEPS, "NON_HEALTH_PERMISSION"))
+        }
+    }
+
+    @Test
+    fun parseIntent() {
+        val requestPermissionContract = HealthDataRequestPermissionsUpsideDownCake()
+
+        val intent = Intent()
+        intent.putExtra(
+            RequestMultiplePermissions.EXTRA_PERMISSIONS,
+            arrayOf(
+                HealthPermission.READ_STEPS,
+                HealthPermission.WRITE_STEPS,
+                HealthPermission.WRITE_DISTANCE,
+                HealthPermission.READ_HEART_RATE))
+        intent.putExtra(
+            RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS,
+            intArrayOf(
+                PackageManager.PERMISSION_GRANTED,
+                PackageManager.PERMISSION_DENIED,
+                PackageManager.PERMISSION_GRANTED,
+                PackageManager.PERMISSION_DENIED))
+
+        val result = requestPermissionContract.parseResult(Activity.RESULT_OK, intent)
+
+        assertThat(result)
+            .containsExactly(HealthPermission.READ_STEPS, HealthPermission.WRITE_DISTANCE)
+    }
+}
diff --git a/health/connect/connect-client/src/test/resources/robolectric.properties b/health/connect/connect-client/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/health/connect/connect-client/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/health/health-services-client/src/test/resources/robolectric.properties b/health/health-services-client/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/health/health-services-client/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/heifwriter/heifwriter/api/api_lint.ignore b/heifwriter/heifwriter/api/api_lint.ignore
index a93261a..d3c7e43 100644
--- a/heifwriter/heifwriter/api/api_lint.ignore
+++ b/heifwriter/heifwriter/api/api_lint.ignore
@@ -1,42 +1,24 @@
 // Baseline format: 1.0
+GenericException: androidx.heifwriter.AvifWriter#stop(long):
+    Methods must not throw generic exceptions (`java.lang.Exception`)
 GenericException: androidx.heifwriter.HeifWriter#stop(long):
     Methods must not throw generic exceptions (`java.lang.Exception`)
 
 
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setGridEnabled(boolean):
-    androidx.heifwriter.HeifWriter does not declare a `isGridEnabled()` method matching method androidx.heifwriter.HeifWriter.Builder.setGridEnabled(boolean)
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setHandler(android.os.Handler):
-    androidx.heifwriter.HeifWriter does not declare a `getHandler()` method matching method androidx.heifwriter.HeifWriter.Builder.setHandler(android.os.Handler)
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setMaxImages(int):
-    androidx.heifwriter.HeifWriter does not declare a `getMaxImages()` method matching method androidx.heifwriter.HeifWriter.Builder.setMaxImages(int)
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setPrimaryIndex(int):
-    androidx.heifwriter.HeifWriter does not declare a `getPrimaryIndex()` method matching method androidx.heifwriter.HeifWriter.Builder.setPrimaryIndex(int)
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setQuality(int):
-    androidx.heifwriter.HeifWriter does not declare a `getQuality()` method matching method androidx.heifwriter.HeifWriter.Builder.setQuality(int)
-MissingGetterMatchingBuilder: androidx.heifwriter.HeifWriter.Builder#setRotation(int):
-    androidx.heifwriter.HeifWriter does not declare a `getRotation()` method matching method androidx.heifwriter.HeifWriter.Builder.setRotation(int)
-
-
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#build():
-    Missing nullability on method `build` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setGridEnabled(boolean):
-    Missing nullability on method `setGridEnabled` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setHandler(android.os.Handler):
-    Missing nullability on method `setHandler` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setMaxImages(int):
-    Missing nullability on method `setMaxImages` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setPrimaryIndex(int):
-    Missing nullability on method `setPrimaryIndex` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setQuality(int):
-    Missing nullability on method `setQuality` return
-MissingNullability: androidx.heifwriter.HeifWriter.Builder#setRotation(int):
-    Missing nullability on method `setRotation` return
-
-
+UseParcelFileDescriptor: androidx.heifwriter.AvifWriter.Builder#Builder(java.io.FileDescriptor, int, int, int) parameter #0:
+    Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.heifwriter.AvifWriter.Builder(java.io.FileDescriptor fd, int width, int height, int inputMode)
 UseParcelFileDescriptor: androidx.heifwriter.HeifWriter.Builder#Builder(java.io.FileDescriptor, int, int, int) parameter #0:
     Must use ParcelFileDescriptor instead of FileDescriptor in parameter fd in androidx.heifwriter.HeifWriter.Builder(java.io.FileDescriptor fd, int width, int height, int inputMode)
 
 
+VisiblySynchronized: androidx.heifwriter.AvifWriter#addBitmap(android.graphics.Bitmap):
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.heifwriter.AvifWriter.addBitmap(android.graphics.Bitmap)
+VisiblySynchronized: androidx.heifwriter.AvifWriter#addYuvBuffer(int, byte[]):
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.heifwriter.AvifWriter.addYuvBuffer(int,byte[])
+VisiblySynchronized: androidx.heifwriter.AvifWriter#setInputEndOfStreamTimestamp(long):
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.heifwriter.AvifWriter.setInputEndOfStreamTimestamp(long)
+VisiblySynchronized: androidx.heifwriter.AvifWriter#stop(long):
+    Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.heifwriter.AvifWriter.stop(long)
 VisiblySynchronized: androidx.heifwriter.HeifWriter#addBitmap(android.graphics.Bitmap):
     Internal locks must not be exposed (synchronizing on this or class is still externally observable): method androidx.heifwriter.HeifWriter.addBitmap(android.graphics.Bitmap)
 VisiblySynchronized: androidx.heifwriter.HeifWriter#addYuvBuffer(int, byte[]):
diff --git a/heifwriter/heifwriter/api/current.txt b/heifwriter/heifwriter/api/current.txt
index ce07b53..f6e78d2 100644
--- a/heifwriter/heifwriter/api/current.txt
+++ b/heifwriter/heifwriter/api/current.txt
@@ -1,30 +1,71 @@
 // Signature format: 4.0
 package androidx.heifwriter {
 
+  public final class AvifWriter implements java.lang.AutoCloseable {
+    method public void addBitmap(android.graphics.Bitmap);
+    method public void addExifData(int, byte[], int, int);
+    method public void addYuvBuffer(int, byte[]);
+    method public void close();
+    method public android.os.Handler? getHandler();
+    method public android.view.Surface getInputSurface();
+    method public int getMaxImages();
+    method public int getPrimaryIndex();
+    method public int getQuality();
+    method public int getRotation();
+    method public boolean isGridEnabled();
+    method public boolean isHighBitDepthEnabled();
+    method public void setInputEndOfStreamTimestamp(@IntRange(from=0) long);
+    method public void start();
+    method public void stop(@IntRange(from=0) long) throws java.lang.Exception;
+    field public static final int INPUT_MODE_BITMAP = 2; // 0x2
+    field public static final int INPUT_MODE_BUFFER = 0; // 0x0
+    field public static final int INPUT_MODE_SURFACE = 1; // 0x1
+  }
+
+  public static final class AvifWriter.Builder {
+    ctor public AvifWriter.Builder(java.io.FileDescriptor, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    ctor public AvifWriter.Builder(String, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    method public androidx.heifwriter.AvifWriter build() throws java.io.IOException;
+    method public androidx.heifwriter.AvifWriter.Builder setGridEnabled(boolean);
+    method public androidx.heifwriter.AvifWriter.Builder setHandler(android.os.Handler?);
+    method public androidx.heifwriter.AvifWriter.Builder setHighBitDepthEnabled(boolean);
+    method public androidx.heifwriter.AvifWriter.Builder setMaxImages(@IntRange(from=1) int);
+    method public androidx.heifwriter.AvifWriter.Builder setPrimaryIndex(@IntRange(from=0) int);
+    method public androidx.heifwriter.AvifWriter.Builder setQuality(@IntRange(from=0, to=100) int);
+    method public androidx.heifwriter.AvifWriter.Builder setRotation(@IntRange(from=0) int);
+  }
+
   public final class HeifWriter implements java.lang.AutoCloseable {
     method public void addBitmap(android.graphics.Bitmap);
     method public void addExifData(int, byte[], int, int);
     method public void addYuvBuffer(int, byte[]);
     method public void close();
+    method public android.os.Handler? getHandler();
     method public android.view.Surface getInputSurface();
-    method public void setInputEndOfStreamTimestamp(long);
+    method public int getMaxImages();
+    method public int getPrimaryIndex();
+    method public int getQuality();
+    method public int getRotation();
+    method public boolean isGridEnabled();
+    method public boolean isHighBitDepthEnabled();
+    method public void setInputEndOfStreamTimestamp(@IntRange(from=0) long);
     method public void start();
-    method public void stop(long) throws java.lang.Exception;
+    method public void stop(@IntRange(from=0) long) throws java.lang.Exception;
     field public static final int INPUT_MODE_BITMAP = 2; // 0x2
     field public static final int INPUT_MODE_BUFFER = 0; // 0x0
     field public static final int INPUT_MODE_SURFACE = 1; // 0x1
   }
 
   public static final class HeifWriter.Builder {
-    ctor public HeifWriter.Builder(java.io.FileDescriptor, int, int, int);
-    ctor public HeifWriter.Builder(String, int, int, int);
-    method public androidx.heifwriter.HeifWriter! build() throws java.io.IOException;
-    method public androidx.heifwriter.HeifWriter.Builder! setGridEnabled(boolean);
-    method public androidx.heifwriter.HeifWriter.Builder! setHandler(android.os.Handler?);
-    method public androidx.heifwriter.HeifWriter.Builder! setMaxImages(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setPrimaryIndex(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setQuality(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setRotation(int);
+    ctor public HeifWriter.Builder(java.io.FileDescriptor, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    ctor public HeifWriter.Builder(String, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    method public androidx.heifwriter.HeifWriter build() throws java.io.IOException;
+    method public androidx.heifwriter.HeifWriter.Builder setGridEnabled(boolean);
+    method public androidx.heifwriter.HeifWriter.Builder setHandler(android.os.Handler?);
+    method public androidx.heifwriter.HeifWriter.Builder setMaxImages(@IntRange(from=1) int);
+    method public androidx.heifwriter.HeifWriter.Builder setPrimaryIndex(@IntRange(from=0) int);
+    method public androidx.heifwriter.HeifWriter.Builder setQuality(@IntRange(from=0, to=100) int);
+    method public androidx.heifwriter.HeifWriter.Builder setRotation(@IntRange(from=0) int);
   }
 
 }
diff --git a/heifwriter/heifwriter/api/restricted_current.txt b/heifwriter/heifwriter/api/restricted_current.txt
index ce07b53..f6e78d2 100644
--- a/heifwriter/heifwriter/api/restricted_current.txt
+++ b/heifwriter/heifwriter/api/restricted_current.txt
@@ -1,30 +1,71 @@
 // Signature format: 4.0
 package androidx.heifwriter {
 
+  public final class AvifWriter implements java.lang.AutoCloseable {
+    method public void addBitmap(android.graphics.Bitmap);
+    method public void addExifData(int, byte[], int, int);
+    method public void addYuvBuffer(int, byte[]);
+    method public void close();
+    method public android.os.Handler? getHandler();
+    method public android.view.Surface getInputSurface();
+    method public int getMaxImages();
+    method public int getPrimaryIndex();
+    method public int getQuality();
+    method public int getRotation();
+    method public boolean isGridEnabled();
+    method public boolean isHighBitDepthEnabled();
+    method public void setInputEndOfStreamTimestamp(@IntRange(from=0) long);
+    method public void start();
+    method public void stop(@IntRange(from=0) long) throws java.lang.Exception;
+    field public static final int INPUT_MODE_BITMAP = 2; // 0x2
+    field public static final int INPUT_MODE_BUFFER = 0; // 0x0
+    field public static final int INPUT_MODE_SURFACE = 1; // 0x1
+  }
+
+  public static final class AvifWriter.Builder {
+    ctor public AvifWriter.Builder(java.io.FileDescriptor, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    ctor public AvifWriter.Builder(String, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    method public androidx.heifwriter.AvifWriter build() throws java.io.IOException;
+    method public androidx.heifwriter.AvifWriter.Builder setGridEnabled(boolean);
+    method public androidx.heifwriter.AvifWriter.Builder setHandler(android.os.Handler?);
+    method public androidx.heifwriter.AvifWriter.Builder setHighBitDepthEnabled(boolean);
+    method public androidx.heifwriter.AvifWriter.Builder setMaxImages(@IntRange(from=1) int);
+    method public androidx.heifwriter.AvifWriter.Builder setPrimaryIndex(@IntRange(from=0) int);
+    method public androidx.heifwriter.AvifWriter.Builder setQuality(@IntRange(from=0, to=100) int);
+    method public androidx.heifwriter.AvifWriter.Builder setRotation(@IntRange(from=0) int);
+  }
+
   public final class HeifWriter implements java.lang.AutoCloseable {
     method public void addBitmap(android.graphics.Bitmap);
     method public void addExifData(int, byte[], int, int);
     method public void addYuvBuffer(int, byte[]);
     method public void close();
+    method public android.os.Handler? getHandler();
     method public android.view.Surface getInputSurface();
-    method public void setInputEndOfStreamTimestamp(long);
+    method public int getMaxImages();
+    method public int getPrimaryIndex();
+    method public int getQuality();
+    method public int getRotation();
+    method public boolean isGridEnabled();
+    method public boolean isHighBitDepthEnabled();
+    method public void setInputEndOfStreamTimestamp(@IntRange(from=0) long);
     method public void start();
-    method public void stop(long) throws java.lang.Exception;
+    method public void stop(@IntRange(from=0) long) throws java.lang.Exception;
     field public static final int INPUT_MODE_BITMAP = 2; // 0x2
     field public static final int INPUT_MODE_BUFFER = 0; // 0x0
     field public static final int INPUT_MODE_SURFACE = 1; // 0x1
   }
 
   public static final class HeifWriter.Builder {
-    ctor public HeifWriter.Builder(java.io.FileDescriptor, int, int, int);
-    ctor public HeifWriter.Builder(String, int, int, int);
-    method public androidx.heifwriter.HeifWriter! build() throws java.io.IOException;
-    method public androidx.heifwriter.HeifWriter.Builder! setGridEnabled(boolean);
-    method public androidx.heifwriter.HeifWriter.Builder! setHandler(android.os.Handler?);
-    method public androidx.heifwriter.HeifWriter.Builder! setMaxImages(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setPrimaryIndex(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setQuality(int);
-    method public androidx.heifwriter.HeifWriter.Builder! setRotation(int);
+    ctor public HeifWriter.Builder(java.io.FileDescriptor, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    ctor public HeifWriter.Builder(String, @IntRange(from=1) int, @IntRange(from=1) int, int);
+    method public androidx.heifwriter.HeifWriter build() throws java.io.IOException;
+    method public androidx.heifwriter.HeifWriter.Builder setGridEnabled(boolean);
+    method public androidx.heifwriter.HeifWriter.Builder setHandler(android.os.Handler?);
+    method public androidx.heifwriter.HeifWriter.Builder setMaxImages(@IntRange(from=1) int);
+    method public androidx.heifwriter.HeifWriter.Builder setPrimaryIndex(@IntRange(from=0) int);
+    method public androidx.heifwriter.HeifWriter.Builder setQuality(@IntRange(from=0, to=100) int);
+    method public androidx.heifwriter.HeifWriter.Builder setRotation(@IntRange(from=0) int);
   }
 
 }
diff --git a/heifwriter/heifwriter/lint-baseline.xml b/heifwriter/heifwriter/lint-baseline.xml
index ad11f86..cd4e8c5 100644
--- a/heifwriter/heifwriter/lint-baseline.xml
+++ b/heifwriter/heifwriter/lint-baseline.xml
@@ -2,21 +2,12 @@
 <issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface ProgramType {}"
-        errorLine2="                      ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/Texture2dProgram.java"/>
-    </issue>
-
-    <issue
         id="BanSynchronizedMethods"
         message="Use of synchronized methods is not recommended"
         errorLine1="        synchronized void updateInputEOSTime(long timestampNs) {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/heifwriter/HeifEncoder.java"/>
+            file="src/main/java/androidx/heifwriter/EncoderBase.java"/>
     </issue>
 
     <issue
@@ -25,7 +16,7 @@
         errorLine1="        synchronized boolean updateLastInputAndEncoderTime(long inputTimeNs, long encoderTimeUs) {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/heifwriter/HeifEncoder.java"/>
+            file="src/main/java/androidx/heifwriter/EncoderBase.java"/>
     </issue>
 
     <issue
@@ -34,7 +25,7 @@
         errorLine1="        synchronized void updateLastOutputTime(long outputTimeUs) {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/heifwriter/HeifEncoder.java"/>
+            file="src/main/java/androidx/heifwriter/EncoderBase.java"/>
     </issue>
 
     <issue
@@ -43,7 +34,7 @@
         errorLine1="        synchronized void waitForResult(long timeoutMs) throws Exception {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
+            file="src/main/java/androidx/heifwriter/WriterBase.java"/>
     </issue>
 
     <issue
@@ -52,70 +43,16 @@
         errorLine1="        synchronized void signalResult(@Nullable Exception e) {"
         errorLine2="        ^">
         <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
+            file="src/main/java/androidx/heifwriter/WriterBase.java"/>
     </issue>
 
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setRotation(int rotation) {"
-        errorLine2="               ~~~~~~~">
+        errorLine1="    protected static String findAv1Fallback() {"
+        errorLine2="                     ~~~~~~">
         <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setGridEnabled(boolean gridEnabled) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setQuality(int quality) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setMaxImages(int maxImages) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setPrimaryIndex(int primaryIndex) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public Builder setHandler(@Nullable Handler handler) {"
-        errorLine2="               ~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
-    </issue>
-
-    <issue
-        id="UnknownNullness"
-        message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
-        errorLine1="        public HeifWriter build() throws IOException {"
-        errorLine2="               ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/heifwriter/HeifWriter.java"/>
+            file="src/main/java/androidx/heifwriter/AvifEncoder.java"/>
     </issue>
 
 </issues>
diff --git a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/AvifWriterTest.java b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/AvifWriterTest.java
new file mode 100644
index 0000000..ee27431
--- /dev/null
+++ b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/AvifWriterTest.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.heifwriter;
+
+import static androidx.heifwriter.AvifWriter.INPUT_MODE_BITMAP;
+import static androidx.heifwriter.AvifWriter.INPUT_MODE_BUFFER;
+import static androidx.heifwriter.AvifWriter.INPUT_MODE_SURFACE;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.Manifest;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.media.MediaFormat;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.util.Log;
+
+import androidx.heifwriter.test.R;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+import androidx.test.rule.GrantPermissionRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Test {@link AvifWriter}.
+ */
+@RunWith(AndroidJUnit4.class)
+@FlakyTest
+public class AvifWriterTest extends TestBase {
+    private static final String TAG = AvifWriterTest.class.getSimpleName();
+
+    @Rule
+    public GrantPermissionRule mRuntimePermissionRule1 =
+        GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);
+
+    @Rule
+    public GrantPermissionRule mRuntimePermissionRule =
+        GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+
+    private static final boolean DEBUG = true;
+    private static final boolean DUMP_YUV_INPUT = false;
+
+    private static final String AVIFWRITER_INPUT = "heifwriter_input.heic";
+    private static final int[] IMAGE_RESOURCES = new int[] {
+        R.raw.heifwriter_input
+    };
+    private static final String[] IMAGE_FILENAMES = new String[] {
+        AVIFWRITER_INPUT
+    };
+    private static final String OUTPUT_FILENAME = "output.avif";
+
+    @Before
+    public void setUp() throws Exception {
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String outputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+
+            InputStream inputStream = null;
+            FileOutputStream outputStream = null;
+            try {
+                inputStream = getApplicationContext()
+                    .getResources().openRawResource(IMAGE_RESOURCES[i]);
+                outputStream = new FileOutputStream(outputPath);
+                copy(inputStream, outputStream);
+            } finally {
+                closeQuietly(inputStream);
+                closeQuietly(outputStream);
+            }
+        }
+
+        HandlerThread handlerThread = new HandlerThread(
+            "AvifEncoderThread", Process.THREAD_PRIORITY_FOREGROUND);
+        handlerThread.start();
+        mHandler = new Handler(handlerThread.getLooper());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String imageFilePath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+            File imageFile = new File(imageFilePath);
+            if (imageFile.exists()) {
+                imageFile.delete();
+            }
+        }
+    }
+
+    @Test
+    @LargeTest
+    public void testInputBuffer_NoGrid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, false, false, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @Test
+    @LargeTest
+    public void testInputBuffer_Grid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, true, false, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @Test
+    @LargeTest
+    public void testInputBuffer_NoGrid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, false, true, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @Test
+    @LargeTest
+    public void testInputBuffer_Grid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, true, true, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputSurface_NoGrid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, false, false, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+    //
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputSurface_Grid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, true, false, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputSurface_NoGrid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, false, true, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputSurface_Grid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, true, true, OUTPUT_FILENAME);
+        doTestForVariousNumberImages(builder);
+    }
+
+
+    @Test
+    @LargeTest
+    public void testInputBitmap_NoGrid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, false, false, OUTPUT_FILENAME);
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+            doTestForVariousNumberImages(builder.setInputPath(inputPath));
+        }
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputBitmap_Grid_NoHandler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, true, false, OUTPUT_FILENAME);
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+            doTestForVariousNumberImages(builder.setInputPath(inputPath));
+        }
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputBitmap_NoGrid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, false, true, OUTPUT_FILENAME);
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+            doTestForVariousNumberImages(builder.setInputPath(inputPath));
+        }
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @LargeTest
+    public void testInputBitmap_Grid_Handler() throws Throwable {
+        if (shouldSkip()) return;
+
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, true, true, OUTPUT_FILENAME);
+        for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
+            String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                IMAGE_FILENAMES[i]).getAbsolutePath();
+            doTestForVariousNumberImages(builder.setInputPath(inputPath));
+        }
+    }
+
+    @SdkSuppress(maxSdkVersion = 29) // b/192261638
+    @Test
+    @SmallTest
+    public void testCloseWithoutStart() throws Throwable {
+        if (shouldSkip()) return;
+
+        final String outputPath = new File(getApplicationContext().getExternalFilesDir(null),
+            OUTPUT_FILENAME).getAbsolutePath();
+        AvifWriter avifWriter = new AvifWriter.Builder(
+            outputPath, 1920, 1080, INPUT_MODE_SURFACE)
+            .setGridEnabled(true)
+            .setMaxImages(4)
+            .setQuality(90)
+            .setPrimaryIndex(0)
+            .setHandler(mHandler)
+            .build();
+
+        avifWriter.close();
+    }
+
+    private void doTestForVariousNumberImages(TestConfig.Builder builder) throws Exception {
+        builder.setHighBitDepthEnabled(false);
+        builder.setNumImages(4);
+        doTest(builder.setRotation(270).build());
+        doTest(builder.setRotation(180).build());
+        doTest(builder.setRotation(90).build());
+        doTest(builder.setRotation(0).build());
+        doTest(builder.setNumImages(1).build());
+        doTest(builder.setNumImages(8).build());
+
+        builder.setHighBitDepthEnabled(true);
+        builder.setNumImages(1);
+        doTest(builder.setRotation(270).build());
+        doTest(builder.setRotation(180).build());
+        doTest(builder.setRotation(90).build());
+        doTest(builder.setRotation(0).build());
+        doTest(builder.setNumImages(1).build());
+        doTest(builder.setNumImages(8).build());
+    }
+
+    private boolean shouldSkip() {
+        return !hasEncoderForMime(MediaFormat.MIMETYPE_VIDEO_AV1);
+    }
+
+    private static byte[] mYuvData;
+    private void doTest(final TestConfig config) throws Exception {
+        final int width = config.mWidth;
+        final int height = config.mHeight;
+        final int actualNumImages = config.mActualNumImages;
+
+        mInputIndex = 0;
+        AvifWriter avifWriter = null;
+        FileInputStream inputStream = null;
+        FileOutputStream outputStream = null;
+        String outputFileName;
+        try {
+            if (DEBUG)
+                Log.d(TAG, "started: " + config);
+            outputFileName = new File(getApplicationContext().getExternalFilesDir(null),
+                    OUTPUT_FILENAME).getAbsolutePath();
+
+            if(!config.mUseHighBitDepth){
+                avifWriter =
+                    new AvifWriter.Builder(outputFileName, width, height, config.mInputMode)
+                        .setRotation(config.mRotation)
+                        .setGridEnabled(config.mUseGrid)
+                        .setMaxImages(config.mMaxNumImages)
+                        .setQuality(config.mQuality)
+                        .setPrimaryIndex(config.mMaxNumImages - 1)
+                        .setHandler(config.mUseHandler ? mHandler : null)
+                        .build();
+            } else {
+                avifWriter =
+                    new AvifWriter.Builder(outputFileName, width, height, config.mInputMode)
+                        .setRotation(config.mRotation)
+                        .setGridEnabled(config.mUseGrid)
+                        .setMaxImages(config.mMaxNumImages)
+                        .setQuality(config.mQuality)
+                        .setPrimaryIndex(config.mMaxNumImages - 1)
+                        .setHandler(config.mUseHandler ? mHandler : null)
+                        .setHighBitDepthEnabled(true)
+                        .build();
+            }
+
+            if (config.mInputMode == INPUT_MODE_SURFACE) {
+                mInputEglSurface = new EglWindowSurface(avifWriter.getInputSurface());
+            }
+
+            avifWriter.start();
+
+            if (config.mInputMode == INPUT_MODE_BUFFER) {
+                if (!config.mUseHighBitDepth) {
+                    if (mYuvData == null || mYuvData.length != width * height * 3 / 2) {
+                        mYuvData = new byte[width * height * 3 / 2];
+                    }
+                } else {
+                    if (mYuvData == null || mYuvData.length != width * height * 3) {
+                        mYuvData = new byte[width * height * 3];
+                    }
+                }
+
+                if (config.mInputPath != null) {
+                    inputStream = new FileInputStream(config.mInputPath);
+                }
+
+                if (DUMP_YUV_INPUT) {
+                    File outputFile = new File("/sdcard/input.yuv");
+                    outputFile.createNewFile();
+                    outputStream = new FileOutputStream(outputFile);
+                }
+
+                for (int i = 0; i < actualNumImages; i++) {
+                    if (DEBUG)
+                        Log.d(TAG, "fillYuvBuffer: " + i);
+                    fillYuvBuffer(i, mYuvData, width, height, inputStream);
+                    if (DUMP_YUV_INPUT) {
+                        Log.d(TAG, "@@@ dumping input YUV");
+                        outputStream.write(mYuvData);
+                    }
+                    if (!config.mUseHighBitDepth) {
+                        avifWriter.addYuvBuffer(ImageFormat.YUV_420_888, mYuvData);
+                    } else {
+                        avifWriter.addYuvBuffer(ImageFormat.YCBCR_P010, mYuvData);
+                    }
+                }
+            } else if (config.mInputMode == INPUT_MODE_SURFACE) {
+                // The input surface is a surface texture using single buffer mode, draws will be
+                // blocked until onFrameAvailable is done with the buffer, which is dependant on
+                // how fast MediaCodec processes them, which is further dependent on how fast the
+                // MediaCodec callbacks are handled. We can't put draws on the same looper that
+                // handles MediaCodec callback, it will cause deadlock.
+                for (int i = 0; i < actualNumImages; i++) {
+                    if (DEBUG)
+                        Log.d(TAG, "drawFrame: " + i);
+                    drawFrame(width, height);
+                }
+                avifWriter.setInputEndOfStreamTimestamp(
+                    1000 * computePresentationTime(actualNumImages - 1));
+            } else if (config.mInputMode == INPUT_MODE_BITMAP) {
+                if(!config.mUseHighBitDepth) {
+                    Bitmap[] bitmaps = config.mBitmaps;
+                    for (int i = 0; i < Math.min(bitmaps.length, actualNumImages); i++) {
+                        if (DEBUG) {
+                            Log.d(TAG, "addBitmap: " + i);
+                        }
+                        avifWriter.addBitmap(bitmaps[i]);
+                        bitmaps[i].recycle();
+                    }
+                } else {
+                    BitmapFactory.Options opt = new BitmapFactory.Options();
+                    opt.inPreferredConfig = Bitmap.Config.RGBA_F16;
+                    InputStream inputStream10Bit = getApplicationContext().getResources()
+                        .openRawResource(R.raw.heifwriter_input10);
+                    Bitmap bm = BitmapFactory.decodeStream(inputStream10Bit, null, opt);
+                    assertNotNull(bm);
+                    avifWriter.addBitmap(bm);
+                    bm.recycle();
+                }
+            }
+
+            avifWriter.stop(10000);
+            // The test sets the primary index to the last image.
+            // However, if we're testing early abort, the last image will not be
+            // present and the muxer is supposed to set it to 0 by default.
+            int expectedPrimary = config.mMaxNumImages - 1;
+            int expectedImageCount = config.mMaxNumImages;
+            if (actualNumImages < config.mMaxNumImages) {
+                expectedPrimary = 0;
+                expectedImageCount = actualNumImages;
+            }
+            verifyResult(config.mOutputPath, width, height, config.mRotation,
+                expectedImageCount, expectedPrimary, config.mUseGrid,
+                config.mInputMode == INPUT_MODE_SURFACE);
+            if (DEBUG)
+                Log.d(TAG, "finished: PASS");
+        } finally {
+            try {
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (IOException e) {
+            }
+
+            if (avifWriter != null) {
+                avifWriter.close();
+                avifWriter = null;
+            }
+            if (mInputEglSurface != null) {
+                // This also releases the surface from encoder.
+                mInputEglSurface.release();
+                mInputEglSurface = null;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
index b8e3752..a536c7f 100644
--- a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
+++ b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/HeifWriterTest.java
@@ -21,28 +21,15 @@
 import static androidx.heifwriter.HeifWriter.INPUT_MODE_SURFACE;
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 import android.Manifest;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
 import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecList;
-import android.media.MediaExtractor;
 import android.media.MediaFormat;
-import android.media.MediaMetadataRetriever;
-import android.opengl.GLES20;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Process;
 import android.util.Log;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.heifwriter.test.R;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.FlakyTest;
@@ -58,80 +45,52 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Arrays;
 
 /**
  * Test {@link HeifWriter}.
  */
 @RunWith(AndroidJUnit4.class)
 @FlakyTest
-public class HeifWriterTest {
+public class HeifWriterTest extends TestBase {
     private static final String TAG = HeifWriterTest.class.getSimpleName();
 
-    private static final MediaCodecList sMCL = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-
     @Rule
     public GrantPermissionRule mRuntimePermissionRule1 =
-            GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);
+        GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE);
 
     @Rule
     public GrantPermissionRule mRuntimePermissionRule =
-            GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+        GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);
 
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
     private static final boolean DUMP_YUV_INPUT = false;
 
-    private static final byte[][] TEST_YUV_COLORS = {
-            {(byte) 255, (byte) 0, (byte) 0},
-            {(byte) 255, (byte) 0, (byte) 255},
-            {(byte) 255, (byte) 255, (byte) 255},
-            {(byte) 255, (byte) 255, (byte) 0},
-    };
-    private static final Color COLOR_BLOCK =
-            Color.valueOf(1.0f, 1.0f, 1.0f);
-    private static final Color[] COLOR_BARS = {
-            Color.valueOf(0.0f, 0.0f, 0.0f),
-            Color.valueOf(0.0f, 0.0f, 0.64f),
-            Color.valueOf(0.0f, 0.64f, 0.0f),
-            Color.valueOf(0.0f, 0.64f, 0.64f),
-            Color.valueOf(0.64f, 0.0f, 0.0f),
-            Color.valueOf(0.64f, 0.0f, 0.64f),
-            Color.valueOf(0.64f, 0.64f, 0.0f),
-    };
-    private static final float MAX_DELTA = 0.025f;
-    private static final int BORDER_WIDTH = 16;
-
     private static final String HEIFWRITER_INPUT = "heifwriter_input.heic";
     private static final int[] IMAGE_RESOURCES = new int[] {
-            R.raw.heifwriter_input
+        R.raw.heifwriter_input
     };
     private static final String[] IMAGE_FILENAMES = new String[] {
-            HEIFWRITER_INPUT
+        HEIFWRITER_INPUT
     };
     private static final String OUTPUT_FILENAME = "output.heic";
 
-    private EglWindowSurface mInputEglSurface;
-    private Handler mHandler;
-    private int mInputIndex;
-
     @Before
     public void setUp() throws Exception {
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String outputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
 
             InputStream inputStream = null;
             FileOutputStream outputStream = null;
             try {
                 inputStream = getApplicationContext()
-                        .getResources().openRawResource(IMAGE_RESOURCES[i]);
+                    .getResources().openRawResource(IMAGE_RESOURCES[i]);
                 outputStream = new FileOutputStream(outputPath);
                 copy(inputStream, outputStream);
             } finally {
@@ -141,7 +100,7 @@
         }
 
         HandlerThread handlerThread = new HandlerThread(
-                "HeifEncoderThread", Process.THREAD_PRIORITY_FOREGROUND);
+            "HeifEncoderThread", Process.THREAD_PRIORITY_FOREGROUND);
         handlerThread.start();
         mHandler = new Handler(handlerThread.getLooper());
     }
@@ -150,7 +109,7 @@
     public void tearDown() throws Exception {
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String imageFilePath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
             File imageFile = new File(imageFilePath);
             if (imageFile.exists()) {
                 imageFile.delete();
@@ -164,7 +123,8 @@
     public void testInputBuffer_NoGrid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BUFFER, false, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, false, false, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -174,7 +134,8 @@
     public void testInputBuffer_Grid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BUFFER, true, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, true, false, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -184,7 +145,8 @@
     public void testInputBuffer_NoGrid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BUFFER, false, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, false, true, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -194,7 +156,8 @@
     public void testInputBuffer_Grid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BUFFER, true, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BUFFER, true, true, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -204,17 +167,19 @@
     public void testInputSurface_NoGrid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_SURFACE, false, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, false, false, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
-
+    //
     @SdkSuppress(maxSdkVersion = 29) // b/192261638
     @Test
     @LargeTest
     public void testInputSurface_Grid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_SURFACE, true, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, true, false, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -224,7 +189,8 @@
     public void testInputSurface_NoGrid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_SURFACE, false, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, false, true, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
@@ -234,20 +200,23 @@
     public void testInputSurface_Grid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_SURFACE, true, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_SURFACE, true, true, OUTPUT_FILENAME);
         doTestForVariousNumberImages(builder);
     }
 
+
     @SdkSuppress(maxSdkVersion = 29) // b/192261638
     @Test
     @LargeTest
     public void testInputBitmap_NoGrid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BITMAP, false, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, false, false, OUTPUT_FILENAME);
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
             doTestForVariousNumberImages(builder.setInputPath(inputPath));
         }
     }
@@ -258,10 +227,11 @@
     public void testInputBitmap_Grid_NoHandler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BITMAP, true, false);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, true, false, OUTPUT_FILENAME);
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
             doTestForVariousNumberImages(builder.setInputPath(inputPath));
         }
     }
@@ -272,10 +242,11 @@
     public void testInputBitmap_NoGrid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BITMAP, false, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, false, true, OUTPUT_FILENAME);
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
             doTestForVariousNumberImages(builder.setInputPath(inputPath));
         }
     }
@@ -286,10 +257,11 @@
     public void testInputBitmap_Grid_Handler() throws Throwable {
         if (shouldSkip()) return;
 
-        TestConfig.Builder builder = new TestConfig.Builder(INPUT_MODE_BITMAP, true, true);
+        TestConfig.Builder builder =
+            new TestConfig.Builder(INPUT_MODE_BITMAP, true, true, OUTPUT_FILENAME);
         for (int i = 0; i < IMAGE_RESOURCES.length; ++i) {
             String inputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                    IMAGE_FILENAMES[i]).getAbsolutePath();
+                IMAGE_FILENAMES[i]).getAbsolutePath();
             doTestForVariousNumberImages(builder.setInputPath(inputPath));
         }
     }
@@ -301,15 +273,15 @@
         if (shouldSkip()) return;
 
         final String outputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                        OUTPUT_FILENAME).getAbsolutePath();
+            OUTPUT_FILENAME).getAbsolutePath();
         HeifWriter heifWriter = new HeifWriter.Builder(
-                    outputPath, 1920, 1080, INPUT_MODE_SURFACE)
-                    .setGridEnabled(true)
-                    .setMaxImages(4)
-                    .setQuality(90)
-                    .setPrimaryIndex(0)
-                    .setHandler(mHandler)
-                    .build();
+            outputPath, 1920, 1080, INPUT_MODE_SURFACE)
+            .setGridEnabled(true)
+            .setMaxImages(4)
+            .setQuality(90)
+            .setPrimaryIndex(0)
+            .setHandler(mHandler)
+            .build();
 
         heifWriter.close();
     }
@@ -324,186 +296,11 @@
         doTest(builder.setNumImages(8).build());
     }
 
-    private void closeQuietly(Closeable closeable) {
-        if (closeable != null) {
-            try {
-                closeable.close();
-            } catch (RuntimeException rethrown) {
-                throw rethrown;
-            } catch (Exception ignored) {
-            }
-        }
-    }
-
-    private int copy(InputStream in, OutputStream out) throws IOException {
-        int total = 0;
-        byte[] buffer = new byte[8192];
-        int c;
-        while ((c = in.read(buffer)) != -1) {
-            total += c;
-            out.write(buffer, 0, c);
-        }
-        return total;
-    }
-
     private boolean shouldSkip() {
         return !hasEncoderForMime(MediaFormat.MIMETYPE_VIDEO_HEVC)
             && !hasEncoderForMime(MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
     }
 
-    private boolean hasEncoderForMime(String mime) {
-        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
-            if (info.isEncoder()) {
-                for (String type : info.getSupportedTypes()) {
-                    if (type.equalsIgnoreCase(mime)) {
-                        Log.i(TAG, "found codec " + info.getName() + " for mime " + mime);
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    private static class TestConfig {
-        final int mInputMode;
-        final boolean mUseGrid;
-        final boolean mUseHandler;
-        final int mMaxNumImages;
-        final int mActualNumImages;
-        final int mWidth;
-        final int mHeight;
-        final int mRotation;
-        final int mQuality;
-        final String mInputPath;
-        final String mOutputPath;
-        final Bitmap[] mBitmaps;
-
-        TestConfig(int inputMode, boolean useGrid, boolean useHandler,
-                   int maxNumImages, int actualNumImages, int width, int height,
-                   int rotation, int quality,
-                   String inputPath, String outputPath, Bitmap[] bitmaps) {
-            mInputMode = inputMode;
-            mUseGrid = useGrid;
-            mUseHandler = useHandler;
-            mMaxNumImages = maxNumImages;
-            mActualNumImages = actualNumImages;
-            mWidth = width;
-            mHeight = height;
-            mRotation = rotation;
-            mQuality = quality;
-            mInputPath = inputPath;
-            mOutputPath = outputPath;
-            mBitmaps = bitmaps;
-        }
-
-        static class Builder {
-            final int mInputMode;
-            final boolean mUseGrid;
-            final boolean mUseHandler;
-            int mMaxNumImages;
-            int mNumImages;
-            int mWidth;
-            int mHeight;
-            int mRotation;
-            final int mQuality;
-            String mInputPath;
-            final String mOutputPath;
-            Bitmap[] mBitmaps;
-            boolean mNumImagesSetExplicitly;
-
-
-            Builder(int inputMode, boolean useGrids, boolean useHandler) {
-                mInputMode = inputMode;
-                mUseGrid = useGrids;
-                mUseHandler = useHandler;
-                mMaxNumImages = mNumImages = 4;
-                mWidth = 1920;
-                mHeight = 1080;
-                mRotation = 0;
-                mQuality = 100;
-                mOutputPath = new File(getApplicationContext().getExternalFilesDir(null),
-                        OUTPUT_FILENAME).getAbsolutePath();
-            }
-
-            Builder setInputPath(String inputPath) {
-                mInputPath = (mInputMode == INPUT_MODE_BITMAP) ? inputPath : null;
-                return this;
-            }
-
-            Builder setNumImages(int numImages) {
-                mNumImagesSetExplicitly = true;
-                mNumImages = numImages;
-                return this;
-            }
-
-            Builder setRotation(int rotation) {
-                mRotation = rotation;
-                return this;
-            }
-
-            private void loadBitmapInputs() {
-                if (mInputMode != INPUT_MODE_BITMAP) {
-                    return;
-                }
-                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-                retriever.setDataSource(mInputPath);
-                String hasImage = retriever.extractMetadata(
-                        MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
-                if (!"yes".equals(hasImage)) {
-                    throw new IllegalArgumentException("no bitmap found!");
-                }
-                mMaxNumImages = Math.min(mMaxNumImages, Integer.parseInt(retriever.extractMetadata(
-                        MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
-                if (!mNumImagesSetExplicitly) {
-                    mNumImages = mMaxNumImages;
-                }
-                mBitmaps = new Bitmap[mMaxNumImages];
-                for (int i = 0; i < mBitmaps.length; i++) {
-                    mBitmaps[i] = retriever.getImageAtIndex(i);
-                }
-                mWidth = mBitmaps[0].getWidth();
-                mHeight = mBitmaps[0].getHeight();
-                try {
-                    retriever.release();
-                } catch (IOException e) {
-                    // Nothing we can  do about it.
-                }
-            }
-
-            private void cleanupStaleOutputs() {
-                File outputFile = new File(mOutputPath);
-                if (outputFile.exists()) {
-                    outputFile.delete();
-                }
-            }
-
-            TestConfig build() {
-                cleanupStaleOutputs();
-                loadBitmapInputs();
-
-                return new TestConfig(mInputMode, mUseGrid, mUseHandler, mMaxNumImages, mNumImages,
-                        mWidth, mHeight, mRotation, mQuality, mInputPath, mOutputPath, mBitmaps);
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "TestConfig"
-                    + ": mInputMode " + mInputMode
-                    + ", mUseGrid " + mUseGrid
-                    + ", mUseHandler " + mUseHandler
-                    + ", mMaxNumImages " + mMaxNumImages
-                    + ", mNumImages " + mActualNumImages
-                    + ", mWidth " + mWidth
-                    + ", mHeight " + mHeight
-                    + ", mRotation " + mRotation
-                    + ", mQuality " + mQuality
-                    + ", mInputPath " + mInputPath
-                    + ", mOutputPath " + mOutputPath;
-        }
-    }
-
     private static byte[] mYuvData;
     private void doTest(final TestConfig config) throws Exception {
         final int width = config.mWidth;
@@ -515,17 +312,19 @@
         FileInputStream inputStream = null;
         FileOutputStream outputStream = null;
         try {
-            if (DEBUG) Log.d(TAG, "started: " + config);
+            if (DEBUG)
+                Log.d(TAG, "started: " + config);
 
             heifWriter = new HeifWriter.Builder(
-                    config.mOutputPath, width, height, config.mInputMode)
-                    .setRotation(config.mRotation)
-                    .setGridEnabled(config.mUseGrid)
-                    .setMaxImages(config.mMaxNumImages)
-                    .setQuality(config.mQuality)
-                    .setPrimaryIndex(config.mMaxNumImages - 1)
-                    .setHandler(config.mUseHandler ? mHandler : null)
-                    .build();
+                new File(getApplicationContext().getExternalFilesDir(null),
+                    OUTPUT_FILENAME).getAbsolutePath(), width, height, config.mInputMode)
+                .setRotation(config.mRotation)
+                .setGridEnabled(config.mUseGrid)
+                .setMaxImages(config.mMaxNumImages)
+                .setQuality(config.mQuality)
+                .setPrimaryIndex(config.mMaxNumImages - 1)
+                .setHandler(config.mUseHandler ? mHandler : null)
+                .build();
 
             if (config.mInputMode == INPUT_MODE_SURFACE) {
                 mInputEglSurface = new EglWindowSurface(heifWriter.getInputSurface());
@@ -549,7 +348,8 @@
                 }
 
                 for (int i = 0; i < actualNumImages; i++) {
-                    if (DEBUG) Log.d(TAG, "fillYuvBuffer: " + i);
+                    if (DEBUG)
+                        Log.d(TAG, "fillYuvBuffer: " + i);
                     fillYuvBuffer(i, mYuvData, width, height, inputStream);
                     if (DUMP_YUV_INPUT) {
                         Log.d(TAG, "@@@ dumping input YUV");
@@ -564,15 +364,17 @@
                 // MediaCodec callbacks are handled. We can't put draws on the same looper that
                 // handles MediaCodec callback, it will cause deadlock.
                 for (int i = 0; i < actualNumImages; i++) {
-                    if (DEBUG) Log.d(TAG, "drawFrame: " + i);
+                    if (DEBUG)
+                        Log.d(TAG, "drawFrame: " + i);
                     drawFrame(width, height);
                 }
                 heifWriter.setInputEndOfStreamTimestamp(
-                        1000 * computePresentationTime(actualNumImages - 1));
+                    1000 * computePresentationTime(actualNumImages - 1));
             } else if (config.mInputMode == INPUT_MODE_BITMAP) {
                 Bitmap[] bitmaps = config.mBitmaps;
                 for (int i = 0; i < Math.min(bitmaps.length, actualNumImages); i++) {
-                    if (DEBUG) Log.d(TAG, "addBitmap: " + i);
+                    if (DEBUG)
+                        Log.d(TAG, "addBitmap: " + i);
                     heifWriter.addBitmap(bitmaps[i]);
                     bitmaps[i].recycle();
                 }
@@ -589,9 +391,10 @@
                 expectedImageCount = actualNumImages;
             }
             verifyResult(config.mOutputPath, width, height, config.mRotation,
-                    expectedImageCount, expectedPrimary, config.mUseGrid,
-                    config.mInputMode == INPUT_MODE_SURFACE);
-            if (DEBUG) Log.d(TAG, "finished: PASS");
+                expectedImageCount, expectedPrimary, config.mUseGrid,
+                config.mInputMode == INPUT_MODE_SURFACE);
+            if (DEBUG)
+                Log.d(TAG, "finished: PASS");
         } finally {
             try {
                 if (outputStream != null) {
@@ -600,7 +403,8 @@
                 if (inputStream != null) {
                     inputStream.close();
                 }
-            } catch (IOException e) {}
+            } catch (IOException e) {
+            }
 
             if (heifWriter != null) {
                 heifWriter.close();
@@ -613,139 +417,4 @@
             }
         }
     }
-
-    private long computePresentationTime(int frameIndex) {
-        return 132 + (long)frameIndex * 1000000;
-    }
-
-    private void fillYuvBuffer(int frameIndex, @NonNull byte[] data, int width, int height,
-                               @Nullable FileInputStream inputStream) throws IOException {
-        if (inputStream != null) {
-            inputStream.read(data);
-        } else {
-            byte[] color = TEST_YUV_COLORS[frameIndex % TEST_YUV_COLORS.length];
-            int sizeY = width * height;
-            Arrays.fill(data, 0, sizeY, color[0]);
-            Arrays.fill(data, sizeY, sizeY * 5 / 4, color[1]);
-            Arrays.fill(data, sizeY * 5 / 4, sizeY * 3 / 2, color[2]);
-        }
-    }
-
-    private void drawFrame(int width, int height) {
-        mInputEglSurface.makeCurrent();
-        generateSurfaceFrame(mInputIndex, width, height);
-        mInputEglSurface.setPresentationTime(1000 * computePresentationTime(mInputIndex));
-        mInputEglSurface.swapBuffers();
-        mInputIndex++;
-    }
-
-    private static Rect getColorBarRect(int index, int width, int height) {
-        int barWidth = (width - BORDER_WIDTH * 2) / COLOR_BARS.length;
-        return new Rect(BORDER_WIDTH + barWidth * index, BORDER_WIDTH,
-                BORDER_WIDTH + barWidth * (index + 1), height - BORDER_WIDTH);
-    }
-
-    private static Rect getColorBlockRect(int index, int width, int height) {
-        int blockCenterX = (width / 5) * (index % 4 + 1);
-        return new Rect(blockCenterX - width / 10, height / 6,
-                        blockCenterX + width / 10, height / 3);
-    }
-
-    private void generateSurfaceFrame(int frameIndex, int width, int height) {
-        GLES20.glViewport(0, 0, width, height);
-        GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
-        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
-        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
-        GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
-
-        for (int i = 0; i < COLOR_BARS.length; i++) {
-            Rect r = getColorBarRect(i, width, height);
-
-            GLES20.glScissor(r.left, r.top, r.width(), r.height());
-            final Color color = COLOR_BARS[i];
-            GLES20.glClearColor(color.red(), color.green(), color.blue(), 1.0f);
-            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
-        }
-
-        Rect r = getColorBlockRect(frameIndex, width, height);
-        GLES20.glScissor(r.left, r.top, r.width(), r.height());
-        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
-        r.inset(BORDER_WIDTH, BORDER_WIDTH);
-        GLES20.glScissor(r.left, r.top, r.width(), r.height());
-        GLES20.glClearColor(COLOR_BLOCK.red(), COLOR_BLOCK.green(), COLOR_BLOCK.blue(), 1.0f);
-        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
-    }
-
-    /**
-     * Determines if two color values are approximately equal.
-     */
-    private static boolean approxEquals(Color expected, Color actual) {
-        return (Math.abs(expected.red() - actual.red()) <= MAX_DELTA)
-            && (Math.abs(expected.green() - actual.green()) <= MAX_DELTA)
-            && (Math.abs(expected.blue() - actual.blue()) <= MAX_DELTA);
-    }
-
-    private void verifyResult(
-            String filename, int width, int height, int rotation,
-            int imageCount, int primary, boolean useGrid, boolean checkColor)
-            throws Exception {
-        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-        retriever.setDataSource(filename);
-        String hasImage = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
-        if (!"yes".equals(hasImage)) {
-            throw new Exception("No images found in file " + filename);
-        }
-        assertEquals("Wrong width", width,
-                Integer.parseInt(retriever.extractMetadata(
-                    MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH)));
-        assertEquals("Wrong height", height,
-                Integer.parseInt(retriever.extractMetadata(
-                    MediaMetadataRetriever.METADATA_KEY_IMAGE_HEIGHT)));
-        assertEquals("Wrong rotation", rotation,
-                Integer.parseInt(retriever.extractMetadata(
-                    MediaMetadataRetriever.METADATA_KEY_IMAGE_ROTATION)));
-        assertEquals("Wrong image count", imageCount,
-                Integer.parseInt(retriever.extractMetadata(
-                        MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
-        assertEquals("Wrong primary index", primary,
-                Integer.parseInt(retriever.extractMetadata(
-                        MediaMetadataRetriever.METADATA_KEY_IMAGE_PRIMARY)));
-        try {
-            retriever.release();
-        } catch (IOException e) {
-            // Nothing we can  do about it.
-        }
-
-        if (useGrid) {
-            MediaExtractor extractor = new MediaExtractor();
-            extractor.setDataSource(filename);
-            MediaFormat format = extractor.getTrackFormat(0);
-            int tileWidth = format.getInteger(MediaFormat.KEY_TILE_WIDTH);
-            int tileHeight = format.getInteger(MediaFormat.KEY_TILE_HEIGHT);
-            int gridRows = format.getInteger(MediaFormat.KEY_GRID_ROWS);
-            int gridCols = format.getInteger(MediaFormat.KEY_GRID_COLUMNS);
-            assertTrue("Wrong tile width or grid cols",
-                    ((width + tileWidth - 1) / tileWidth) == gridCols);
-            assertTrue("Wrong tile height or grid rows",
-                    ((height + tileHeight - 1) / tileHeight) == gridRows);
-            extractor.release();
-        }
-
-        if (checkColor) {
-            Bitmap bitmap = BitmapFactory.decodeFile(filename);
-
-            for (int i = 0; i < COLOR_BARS.length; i++) {
-                Rect r = getColorBarRect(i, width, height);
-                assertTrue("Color bar " + i + " doesn't match", approxEquals(COLOR_BARS[i],
-                        Color.valueOf(bitmap.getPixel(r.centerX(), r.centerY()))));
-            }
-
-            Rect r = getColorBlockRect(primary, width, height);
-            assertTrue("Color block doesn't match", approxEquals(COLOR_BLOCK,
-                    Color.valueOf(bitmap.getPixel(r.centerX(), height - r.centerY()))));
-
-            bitmap.recycle();
-        }
-    }
-}
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/TestBase.java b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/TestBase.java
new file mode 100644
index 0000000..39be1ea
--- /dev/null
+++ b/heifwriter/heifwriter/src/androidTest/java/androidx/heifwriter/TestBase.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package androidx.heifwriter;
+
+import static androidx.heifwriter.HeifWriter.INPUT_MODE_BITMAP;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.media.MediaMetadataRetriever;
+import android.opengl.GLES20;
+import android.os.Environment;
+import android.os.Handler;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+/**
+ * Base class holding common utilities for {@link HeifWriterTest} and {@link AvifWriterTest}.
+ */
+public class TestBase {
+    private static final String TAG = HeifWriterTest.class.getSimpleName();
+
+    private static final MediaCodecList sMCL = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+
+    private static final byte[][] TEST_YUV_COLORS = {
+        {(byte) 255, (byte) 0, (byte) 0},
+        {(byte) 255, (byte) 0, (byte) 255},
+        {(byte) 255, (byte) 255, (byte) 255},
+        {(byte) 255, (byte) 255, (byte) 0},
+    };
+    private static final byte[][] TEST_YUV_10BIT_COLORS = {
+        {(byte) 1023, (byte) 0, (byte) 0},
+        {(byte) 1023, (byte) 0, (byte) 1023},
+        {(byte) 1023, (byte) 1023, (byte) 1023},
+        {(byte) 1023, (byte) 1023, (byte) 0},
+    };
+    private static final Color COLOR_BLOCK =
+        Color.valueOf(1.0f, 1.0f, 1.0f);
+    private static final Color[] COLOR_BARS = {
+        Color.valueOf(0.0f, 0.0f, 0.0f),
+        Color.valueOf(0.0f, 0.0f, 0.64f),
+        Color.valueOf(0.0f, 0.64f, 0.0f),
+        Color.valueOf(0.0f, 0.64f, 0.64f),
+        Color.valueOf(0.64f, 0.0f, 0.0f),
+        Color.valueOf(0.64f, 0.0f, 0.64f),
+        Color.valueOf(0.64f, 0.64f, 0.0f),
+    };
+    private static final float MAX_DELTA = 0.025f;
+    private static final int BORDER_WIDTH = 16;
+
+    protected EglWindowSurface mInputEglSurface;
+    protected Handler mHandler;
+    protected int mInputIndex;
+    protected boolean mHighBitDepthEnabled = false;
+
+    protected long computePresentationTime(int frameIndex) {
+        return 132 + (long)frameIndex * 1000000;
+    }
+
+    protected void fillYuvBuffer(int frameIndex, @NonNull byte[] data, int width, int height,
+        @Nullable FileInputStream inputStream) throws IOException {
+        if (inputStream != null) {
+            inputStream.read(data);
+        } else {
+            byte[] color;
+            int sizeY = width * height;
+            if (!mHighBitDepthEnabled) {
+                color = TEST_YUV_COLORS[frameIndex % TEST_YUV_COLORS.length];
+                Arrays.fill(data, 0, sizeY, color[0]);
+                Arrays.fill(data, sizeY, sizeY * 5 / 4, color[1]);
+                Arrays.fill(data, sizeY * 5 / 4, sizeY * 3 / 2, color[2]);
+
+            } else {
+                color = TEST_YUV_10BIT_COLORS[frameIndex % TEST_YUV_10BIT_COLORS.length];
+                Arrays.fill(data, 0, sizeY, color[0]);
+                Arrays.fill(data, sizeY, sizeY * 2, color[1]);
+                Arrays.fill(data, sizeY * 2, sizeY * 3, color[2]);
+            }
+        }
+    }
+
+    protected static Rect getColorBarRect(int index, int width, int height) {
+        int barWidth = (width - BORDER_WIDTH * 2) / COLOR_BARS.length;
+        return new Rect(BORDER_WIDTH + barWidth * index, BORDER_WIDTH,
+            BORDER_WIDTH + barWidth * (index + 1), height - BORDER_WIDTH);
+    }
+
+    protected static Rect getColorBlockRect(int index, int width, int height) {
+        int blockCenterX = (width / 5) * (index % 4 + 1);
+        return new Rect(blockCenterX - width / 10, height / 6,
+            blockCenterX + width / 10, height / 3);
+    }
+
+    protected void generateSurfaceFrame(int frameIndex, int width, int height) {
+        GLES20.glViewport(0, 0, width, height);
+        GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
+        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
+
+        for (int i = 0; i < COLOR_BARS.length; i++) {
+            Rect r = getColorBarRect(i, width, height);
+
+            GLES20.glScissor(r.left, r.top, r.width(), r.height());
+            final Color color = COLOR_BARS[i];
+            GLES20.glClearColor(color.red(), color.green(), color.blue(), 1.0f);
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        }
+
+        Rect r = getColorBlockRect(frameIndex, width, height);
+        GLES20.glScissor(r.left, r.top, r.width(), r.height());
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+        r.inset(BORDER_WIDTH, BORDER_WIDTH);
+        GLES20.glScissor(r.left, r.top, r.width(), r.height());
+        GLES20.glClearColor(COLOR_BLOCK.red(), COLOR_BLOCK.green(), COLOR_BLOCK.blue(), 1.0f);
+        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+    }
+
+    /**
+     * Determines if two color values are approximately equal.
+     */
+    protected static boolean approxEquals(Color expected, Color actual) {
+        return (Math.abs(expected.red() - actual.red()) <= MAX_DELTA)
+            && (Math.abs(expected.green() - actual.green()) <= MAX_DELTA)
+            && (Math.abs(expected.blue() - actual.blue()) <= MAX_DELTA);
+    }
+
+    protected void verifyResult(
+        String filename, int width, int height, int rotation,
+        int imageCount, int primary, boolean useGrid, boolean checkColor)
+        throws Exception {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        retriever.setDataSource(filename);
+        String hasImage = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
+        if (!"yes".equals(hasImage)) {
+            throw new Exception("No images found in file " + filename);
+        }
+        assertEquals("Wrong width", width,
+            Integer.parseInt(retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH)));
+        assertEquals("Wrong height", height,
+            Integer.parseInt(retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_IMAGE_HEIGHT)));
+        assertEquals("Wrong rotation", rotation,
+            Integer.parseInt(retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_IMAGE_ROTATION)));
+        assertEquals("Wrong image count", imageCount,
+            Integer.parseInt(retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
+        assertEquals("Wrong primary index", primary,
+            Integer.parseInt(retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_IMAGE_PRIMARY)));
+        try {
+            retriever.release();
+        } catch (IOException e) {
+            // Nothing we can  do about it.
+        }
+
+        if (useGrid) {
+            MediaExtractor extractor = new MediaExtractor();
+            extractor.setDataSource(filename);
+            MediaFormat format = extractor.getTrackFormat(0);
+            int tileWidth = format.getInteger(MediaFormat.KEY_TILE_WIDTH);
+            int tileHeight = format.getInteger(MediaFormat.KEY_TILE_HEIGHT);
+            int gridRows = format.getInteger(MediaFormat.KEY_GRID_ROWS);
+            int gridCols = format.getInteger(MediaFormat.KEY_GRID_COLUMNS);
+            assertTrue("Wrong tile width or grid cols",
+                ((width + tileWidth - 1) / tileWidth) == gridCols);
+            assertTrue("Wrong tile height or grid rows",
+                ((height + tileHeight - 1) / tileHeight) == gridRows);
+            extractor.release();
+        }
+
+        if (checkColor) {
+            Bitmap bitmap = BitmapFactory.decodeFile(filename);
+
+            for (int i = 0; i < COLOR_BARS.length; i++) {
+                Rect r = getColorBarRect(i, width, height);
+                assertTrue("Color bar " + i + " doesn't match", approxEquals(COLOR_BARS[i],
+                    Color.valueOf(bitmap.getPixel(r.centerX(), r.centerY()))));
+            }
+
+            Rect r = getColorBlockRect(primary, width, height);
+            assertTrue("Color block doesn't match", approxEquals(COLOR_BLOCK,
+                Color.valueOf(bitmap.getPixel(r.centerX(), height - r.centerY()))));
+
+            bitmap.recycle();
+        }
+    }
+
+    protected void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    protected int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
+
+    protected boolean hasEncoderForMime(String mime) {
+        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
+            if (info.isEncoder()) {
+                for (String type : info.getSupportedTypes()) {
+                    if (type.equalsIgnoreCase(mime)) {
+                        Log.i(TAG, "found codec " + info.getName() + " for mime " + mime);
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    protected void drawFrame(int width, int height) {
+        mInputEglSurface.makeCurrent();
+        generateSurfaceFrame(mInputIndex, width, height);
+        mInputEglSurface.setPresentationTime(1000 * computePresentationTime(mInputIndex));
+        mInputEglSurface.swapBuffers();
+        mInputIndex++;
+    }
+
+    protected static class TestConfig {
+        final int mInputMode;
+        final boolean mUseGrid;
+        final boolean mUseHandler;
+        final boolean mUseHighBitDepth;
+        final int mMaxNumImages;
+        final int mActualNumImages;
+        final int mWidth;
+        final int mHeight;
+        final int mRotation;
+        final int mQuality;
+        final String mInputPath;
+        final String mOutputPath;
+        final Bitmap[] mBitmaps;
+
+        TestConfig(int inputMode, boolean useGrid, boolean useHandler, boolean useHighBitDepth,
+            int maxNumImages, int actualNumImages, int width, int height, int rotation,
+            int quality, String inputPath, String outputPath, Bitmap[] bitmaps) {
+            mInputMode = inputMode;
+            mUseGrid = useGrid;
+            mUseHandler = useHandler;
+            mUseHighBitDepth = useHighBitDepth;
+            mMaxNumImages = maxNumImages;
+            mActualNumImages = actualNumImages;
+            mWidth = width;
+            mHeight = height;
+            mRotation = rotation;
+            mQuality = quality;
+            mInputPath = inputPath;
+            mOutputPath = outputPath;
+            mBitmaps = bitmaps;
+        }
+
+        static class Builder {
+            final int mInputMode;
+            final boolean mUseGrid;
+            final boolean mUseHandler;
+            boolean mUseHighBitDepth;
+            int mMaxNumImages;
+            int mNumImages;
+            int mWidth;
+            int mHeight;
+            int mRotation;
+            final int mQuality;
+            String mInputPath;
+            final String mOutputPath;
+            Bitmap[] mBitmaps;
+            boolean mNumImagesSetExplicitly;
+
+
+            Builder(int inputMode, boolean useGrids, boolean useHandler, String outputFileName) {
+                mInputMode = inputMode;
+                mUseGrid = useGrids;
+                mUseHandler = useHandler;
+                mUseHighBitDepth = false;
+                mMaxNumImages = mNumImages = 4;
+                mWidth = 1920;
+                mHeight = 1080;
+                mRotation = 0;
+                mQuality = 100;
+                mOutputPath = new File(getApplicationContext().getExternalFilesDir(null),
+                    outputFileName).getAbsolutePath();
+            }
+
+            Builder setInputPath(String inputPath) {
+                mInputPath = (mInputMode == INPUT_MODE_BITMAP) ? inputPath : null;
+                return this;
+            }
+
+            Builder setNumImages(int numImages) {
+                mNumImagesSetExplicitly = true;
+                mNumImages = numImages;
+                return this;
+            }
+
+            Builder setRotation(int rotation) {
+                mRotation = rotation;
+                return this;
+            }
+
+            Builder setHighBitDepthEnabled(boolean useHighBitDepth) {
+                mUseHighBitDepth = useHighBitDepth;
+                return this;
+            }
+
+            private void loadBitmapInputs() {
+                if (mInputMode != INPUT_MODE_BITMAP) {
+                    return;
+                }
+                if (!mUseHighBitDepth) {
+                    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+                    retriever.setDataSource(mInputPath);
+                    String hasImage = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
+                    if (!"yes".equals(hasImage)) {
+                        throw new IllegalArgumentException("no bitmap found!");
+                    }
+                    mMaxNumImages = Math.min(mMaxNumImages,
+                        Integer.parseInt(retriever.extractMetadata(
+                            MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT)));
+                    if (!mNumImagesSetExplicitly) {
+                        mNumImages = mMaxNumImages;
+                    }
+                    mBitmaps = new Bitmap[mMaxNumImages];
+                    for (int i = 0; i < mBitmaps.length; i++) {
+                        mBitmaps[i] = retriever.getImageAtIndex(i);
+                    }
+                    mWidth = mBitmaps[0].getWidth();
+                    mHeight = mBitmaps[0].getHeight();
+                    try {
+                        retriever.release();
+                    } catch (IOException e) {
+                        // Nothing we can  do about it.
+                    }
+                } else {
+                    mMaxNumImages = 1;
+                    mNumImages = 1;
+                }
+            }
+
+            private void cleanupStaleOutputs() {
+                File outputFile = new File(mOutputPath);
+                if (outputFile.exists()) {
+                    outputFile.delete();
+                }
+            }
+
+            TestConfig build() {
+                cleanupStaleOutputs();
+                loadBitmapInputs();
+
+                return new TestConfig(mInputMode, mUseGrid, mUseHandler, mUseHighBitDepth,
+                    mMaxNumImages, mNumImages, mWidth, mHeight, mRotation, mQuality, mInputPath,
+                    mOutputPath, mBitmaps);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "TestConfig"
+                + ": mInputMode " + mInputMode
+                + ", mUseGrid " + mUseGrid
+                + ", mUseHandler " + mUseHandler
+                + ", mMaxNumImages " + mMaxNumImages
+                + ", mNumImages " + mActualNumImages
+                + ", mWidth " + mWidth
+                + ", mHeight " + mHeight
+                + ", mRotation " + mRotation
+                + ", mQuality " + mQuality
+                + ", mInputPath " + mInputPath
+                + ", mOutputPath " + mOutputPath;
+        }
+    }
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/androidTest/res/raw/heifwriter_input10.png b/heifwriter/heifwriter/src/androidTest/res/raw/heifwriter_input10.png
new file mode 100644
index 0000000..55503df
--- /dev/null
+++ b/heifwriter/heifwriter/src/androidTest/res/raw/heifwriter_input10.png
Binary files differ
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifEncoder.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifEncoder.java
new file mode 100644
index 0000000..6fdae4d
--- /dev/null
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifEncoder.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2022 Google Inc. All rights reserved.
+ *
+ * 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.heifwriter;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+import android.util.Range;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+
+import java.io.IOException;
+
+/**
+ * This class encodes images into HEIF-compatible samples using AV1 encoder.
+ *
+ * It currently supports three input modes: {@link #INPUT_MODE_BUFFER},
+ * {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
+ *
+ * The output format and samples are sent back in {@link
+ * Callback#onOutputFormatChanged(HeifEncoder, MediaFormat)} and {@link
+ * Callback#onDrainOutputBuffer(HeifEncoder, ByteBuffer)}. If the client
+ * requests to use grid, each tile will be sent back individually.
+ *
+ * HeifEncoder is made a separate class from {@link HeifWriter}, as some more
+ * advanced use cases might want to build solutions on top of the HeifEncoder directly.
+ * (eg. mux still images and video tracks into a single container).
+ *
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public final class AvifEncoder extends EncoderBase {
+    private static final String TAG = "AvifEncoder";
+    private static final boolean DEBUG = false;
+
+    protected static final int GRID_WIDTH = 512;
+    protected static final int GRID_HEIGHT = 512;
+    protected static final double MAX_COMPRESS_RATIO = 0.25f;
+
+    private static final MediaCodecList sMCL =
+        new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+
+    /**
+     * Configure the avif encoding session. Should only be called once.
+     *
+     * @param width Width of the image.
+     * @param height Height of the image.
+     * @param useGrid Whether to encode image into tiles. If enabled, tile size will be
+     *                automatically chosen.
+     * @param quality A number between 0 and 100 (inclusive), with 100 indicating the best quality
+     *                supported by this implementation (which often results in larger file size).
+     * @param inputMode The input type of this encoding session.
+     * @param handler If not null, client will receive all callbacks on the handler's looper.
+     *                Otherwise, client will receive callbacks on a looper created by us.
+     * @param cb The callback to receive various messages from the avif encoder.
+     */
+    public AvifEncoder(int width, int height, boolean useGrid,
+            int quality, @InputMode int inputMode,
+            @Nullable Handler handler, @NonNull Callback cb,
+            boolean useBitDepth10) throws IOException {
+        super("AVIF", width, height, useGrid, quality, inputMode, handler, cb, useBitDepth10);
+        mEncoder.setCallback(new Av1EncoderCallback(), mHandler);
+        finishSettingUpEncoder(useBitDepth10);
+    }
+
+    protected static String findAv1Fallback() {
+        String av1 = null; // first AV1 encoder
+        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
+            if (!info.isEncoder()) {
+                continue;
+            }
+            MediaCodecInfo.CodecCapabilities caps = null;
+            try {
+                caps = info.getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_AV1);
+            } catch (IllegalArgumentException e) { // mime is not supported
+                continue;
+            }
+            if (!caps.getVideoCapabilities().isSizeSupported(GRID_WIDTH, GRID_HEIGHT)) {
+                continue;
+            }
+            if (caps.getEncoderCapabilities().isBitrateModeSupported(
+                MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
+                // Encoder that supports CQ mode is preferred over others,
+                // return the first encoder that supports CQ mode.
+                // (No need to check if it's hw based, it's already listed in
+                // order of preference.)
+                return info.getName();
+            }
+            if (av1 == null) {
+                av1 = info.getName();
+            }
+        }
+        // If no encoders support CQ, return the first AV1 encoder.
+        return av1;
+    }
+
+    /**
+     * MediaCodec callback for AV1 encoding.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected class Av1EncoderCallback extends EncoderCallback {
+        @Override
+        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
+            if (codec != mEncoder) return;
+
+            if (DEBUG) Log.d(TAG, "onOutputFormatChanged: " + format);
+
+            // TODO(b/252835975) replace "image/avif" with  MIMETYPE_IMAGE_AVIF.
+            if (!format.getString(MediaFormat.KEY_MIME).equals("image/avif")) {
+                format.setString(MediaFormat.KEY_MIME, "image/avif");
+                format.setInteger(MediaFormat.KEY_WIDTH, mWidth);
+                format.setInteger(MediaFormat.KEY_HEIGHT, mHeight);
+
+                if (mUseGrid) {
+                    format.setInteger(MediaFormat.KEY_TILE_WIDTH, mGridWidth);
+                    format.setInteger(MediaFormat.KEY_TILE_HEIGHT, mGridHeight);
+                    format.setInteger(MediaFormat.KEY_GRID_ROWS, mGridRows);
+                    format.setInteger(MediaFormat.KEY_GRID_COLUMNS, mGridCols);
+                }
+            }
+
+            mCallback.onOutputFormatChanged(AvifEncoder.this, format);
+        }
+    }
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifWriter.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifWriter.java
new file mode 100644
index 0000000..188d164
--- /dev/null
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/AvifWriter.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2022 Google Inc. All rights reserved.
+ *
+ * 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.heifwriter;
+
+import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_HEIF;
+
+import android.annotation.SuppressLint;
+import android.graphics.Bitmap;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class writes one or more still images (of the same dimensions) into
+ * an AVIF file.
+ *
+ * It currently supports three input modes: {@link #INPUT_MODE_BUFFER},
+ * {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
+ *
+ * The general sequence (in pseudo-code) to write a avif file using this class is as follows:
+ *
+ * 1) Construct the writer:
+ * AvifWriter avifwriter = new AvifWriter(...);
+ *
+ * 2) If using surface input mode, obtain the input surface:
+ * Surface surface = avifwriter.getInputSurface();
+ *
+ * 3) Call start:
+ * avifwriter.start();
+ *
+ * 4) Depending on the chosen input mode, add one or more images using one of these methods:
+ * avifwriter.addYuvBuffer(...);   Or
+ * avifwriter.addBitmap(...);   Or
+ * render to the previously obtained surface
+ *
+ * 5) Call stop:
+ * avifwriter.stop(...);
+ *
+ * 6) Close the writer:
+ * avifwriter.close();
+ *
+ * Please refer to the documentations on individual methods for the exact usage.
+ */
+@SuppressWarnings("HiddenSuperclass")
+public final class AvifWriter extends WriterBase {
+
+    private static final String TAG = "AvifWriter";
+    private static final boolean DEBUG = false;
+
+    /**
+     * The input mode where the client adds input buffers with YUV data.
+     *
+     * @see #addYuvBuffer(int, byte[])
+     */
+    public static final int INPUT_MODE_BUFFER = WriterBase.INPUT_MODE_BUFFER;
+
+    /**
+     * The input mode where the client renders the images to an input Surface created by the writer.
+     *
+     * The input surface operates in single buffer mode. As a result, for use case where camera
+     * directly outputs to the input surface, this mode will not work because camera framework
+     * requires multiple buffers to operate in a pipeline fashion.
+     *
+     * @see #getInputSurface()
+     */
+    public static final int INPUT_MODE_SURFACE = WriterBase.INPUT_MODE_SURFACE;
+
+    /**
+     * The input mode where the client adds bitmaps.
+     *
+     * @see #addBitmap(Bitmap)
+     */
+    public static final int INPUT_MODE_BITMAP = WriterBase.INPUT_MODE_BITMAP;
+
+    /**
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        INPUT_MODE_BUFFER, INPUT_MODE_SURFACE, INPUT_MODE_BITMAP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InputMode {
+
+    }
+
+    /**
+     * Builder class for constructing a AvifWriter object from specified parameters.
+     */
+    public static final class Builder {
+        private final String mPath;
+        private final FileDescriptor mFd;
+        private final int mWidth;
+        private final int mHeight;
+        private final @InputMode int mInputMode;
+        private boolean mGridEnabled = true;
+        private int mQuality = 100;
+        private int mMaxImages = 1;
+        private int mPrimaryIndex = 0;
+        private int mRotation = 0;
+        private Handler mHandler;
+        private boolean mHighBitDepthEnabled = false;
+
+        /**
+         * Construct a Builder with output specified by its path.
+         *
+         * @param path Path of the file to be written.
+         * @param width Width of the image in number of pixels.
+         * @param height Height of the image in number of pixels.
+         * @param inputMode Input mode for this writer, must be one of {@link #INPUT_MODE_BUFFER},
+         *                  {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
+         */
+        public Builder(@NonNull String path,
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
+            this(path, null, width, height, inputMode);
+        }
+
+        /**
+         * Construct a Builder with output specified by its file descriptor.
+         *
+         * @param fd File descriptor of the file to be written.
+         * @param width Width of the image in number of pixels.
+         * @param height Height of the image in number of pixels.
+         * @param inputMode Input mode for this writer, must be one of {@link #INPUT_MODE_BUFFER},
+         *                  {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
+         */
+        public Builder(@NonNull FileDescriptor fd,
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
+            this(null, fd, width, height, inputMode);
+        }
+
+        private Builder(String path, FileDescriptor fd,
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
+            mPath = path;
+            mFd = fd;
+            mWidth = width;
+            mHeight = height;
+            mInputMode = inputMode;
+        }
+
+        /**
+         * Set the image rotation in degrees.
+         *
+         * @param rotation Rotation angle in degrees (clockwise) of the image, must be 0, 90,
+         *                 180 or 270. Default is 0.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setRotation(@IntRange(from = 0) int rotation) {
+            if (rotation != 0 && rotation != 90 && rotation != 180 && rotation != 270) {
+                throw new IllegalArgumentException("Invalid rotation angle: " + rotation);
+            }
+            mRotation = rotation;
+            return this;
+        }
+
+        /**
+         * Set whether to enable grid option.
+         *
+         * @param gridEnabled Whether to enable grid option. If enabled, the tile size will be
+         *                    automatically chosen. Default is to enable.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setGridEnabled(boolean gridEnabled) {
+            mGridEnabled = gridEnabled;
+            return this;
+        }
+
+        /**
+         * Set the quality for encoding images.
+         *
+         * @param quality A number between 0 and 100 (inclusive), with 100 indicating the best
+         *                quality supported by this implementation. Default is 100.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setQuality(@IntRange(from = 0, to = 100) int quality) {
+            if (quality < 0 || quality > 100) {
+                throw new IllegalArgumentException("Invalid quality: " + quality);
+            }
+            mQuality = quality;
+            return this;
+        }
+
+        /**
+         * Set the maximum number of images to write.
+         *
+         * @param maxImages Max number of images to write. Frames exceeding this number will not be
+         *                  written to file. The writing can be stopped earlier before this number
+         *                  of images are written by {@link #stop(long)}, except for the input mode
+         *                  of {@link #INPUT_MODE_SURFACE}, where the EOS timestamp must be
+         *                  specified (via {@link #setInputEndOfStreamTimestamp(long)} and reached.
+         *                  Default is 1.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setMaxImages(@IntRange(from = 1) int maxImages) {
+            if (maxImages <= 0) {
+                throw new IllegalArgumentException("Invalid maxImage: " + maxImages);
+            }
+            mMaxImages = maxImages;
+            return this;
+        }
+
+        /**
+         * Set the primary image index.
+         *
+         * @param primaryIndex Index of the image that should be marked as primary, must be within
+         *                     range [0, maxImages - 1] inclusive. Default is 0.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setPrimaryIndex(@IntRange(from = 0) int primaryIndex) {
+            mPrimaryIndex = primaryIndex;
+            return this;
+        }
+
+        /**
+         * Provide a handler for the AvifWriter to use.
+         *
+         * @param handler If not null, client will receive all callbacks on the handler's looper.
+         *                Otherwise, client will receive callbacks on a looper created by the
+         *                writer. Default is null.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setHandler(@Nullable Handler handler) {
+            mHandler = handler;
+            return this;
+        }
+
+        /**
+         * Provide a setting for the AvifWriter to use high bit-depth or not.
+         *
+         * @param highBitDepthEnabled Whether to enable high bit-depth mode. Default is false, if
+         *                            true, AvifWriter will encode with high bit-depth.
+         * @return this Builder object.
+         */
+        public @NonNull Builder setHighBitDepthEnabled(boolean highBitDepthEnabled) {
+            mHighBitDepthEnabled = highBitDepthEnabled;
+            return this;
+        }
+
+        /**
+         * Build a AvifWriter object.
+         *
+         * @return a AvifWriter object built according to the specifications.
+         * @throws IOException if failed to create the writer, possibly due to failure to create
+         *                     {@link android.media.MediaMuxer} or {@link android.media.MediaCodec}.
+         */
+        public @NonNull AvifWriter build() throws IOException {
+            return new AvifWriter(mPath, mFd, mWidth, mHeight, mRotation, mGridEnabled, mQuality,
+                mMaxImages, mPrimaryIndex, mInputMode, mHandler, mHighBitDepthEnabled);
+        }
+    }
+
+    @SuppressLint("WrongConstant")
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    AvifWriter(@NonNull String path,
+        @NonNull FileDescriptor fd,
+        int width,
+        int height,
+        int rotation,
+        boolean gridEnabled,
+        int quality,
+        int maxImages,
+        int primaryIndex,
+        @InputMode int inputMode,
+        @Nullable Handler handler,
+        boolean highBitDepthEnabled) throws IOException {
+        super(rotation, inputMode, maxImages, primaryIndex, gridEnabled, quality,
+            handler, highBitDepthEnabled);
+
+        if (DEBUG) {
+            Log.d(TAG, "width: " + width
+                + ", height: " + height
+                + ", rotation: " + rotation
+                + ", gridEnabled: " + gridEnabled
+                + ", quality: " + quality
+                + ", maxImages: " + maxImages
+                + ", primaryIndex: " + primaryIndex
+                + ", inputMode: " + inputMode);
+        }
+
+        // set to 1 initially, and wait for output format to know for sure
+        mNumTiles = 1;
+
+        mMuxer = (path != null) ? new MediaMuxer(path, MUXER_OUTPUT_HEIF)
+            : new MediaMuxer(fd, MUXER_OUTPUT_HEIF);
+
+        mEncoder = new AvifEncoder(width, height, gridEnabled, quality,
+            mInputMode, mHandler, new WriterCallback(), highBitDepthEnabled);
+    }
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
index 9b59d28..4aade72 100644
--- a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EglWindowSurface.java
@@ -25,6 +25,8 @@
 import android.util.Log;
 import android.view.Surface;
 
+import androidx.annotation.NonNull;
+
 import java.util.Objects;
 
 /**
@@ -50,18 +52,22 @@
      * Creates an EglWindowSurface from a Surface.
      */
     public EglWindowSurface(Surface surface) {
+        this(surface, false);
+    }
+
+    public EglWindowSurface(Surface surface, boolean useHighBitDepth) {
         if (surface == null) {
             throw new NullPointerException();
         }
         mSurface = surface;
 
-        eglSetup();
+        eglSetup(useHighBitDepth);
     }
 
     /**
      * Prepares EGL. We want a GLES 2.0 context and a surface that supports recording.
      */
-    private void eglSetup() {
+    private void eglSetup(boolean useHighBitDepth) {
         mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
         if (Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) {
             throw new RuntimeException("unable to get EGL14 display");
@@ -74,27 +80,31 @@
 
         // Configure EGL for recordable and OpenGL ES 2.0.  We want enough RGB bits
         // to minimize artifacts from possible YUV conversion.
-        int[] attribList = {
-                EGL14.EGL_RED_SIZE, 8,
-                EGL14.EGL_GREEN_SIZE, 8,
-                EGL14.EGL_BLUE_SIZE, 8,
-                EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
-                EGLExt.EGL_RECORDABLE_ANDROID, 1,
-                EGL14.EGL_NONE
+        int eglColorSize = useHighBitDepth ? 10: 8;
+        int eglAlphaSize = useHighBitDepth ? 2: 0;
+        int recordable = useHighBitDepth ? 0: 1;
+        int[] configAttribList = {
+            EGL14.EGL_RED_SIZE, eglColorSize,
+            EGL14.EGL_GREEN_SIZE, eglColorSize,
+            EGL14.EGL_BLUE_SIZE, eglColorSize,
+            EGL14.EGL_ALPHA_SIZE, eglAlphaSize,
+            EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+            EGLExt.EGL_RECORDABLE_ANDROID, recordable,
+            EGL14.EGL_NONE
         };
         int[] numConfigs = new int[1];
-        if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, mConfigs, 0, mConfigs.length,
-                numConfigs, 0)) {
+        if (!EGL14.eglChooseConfig(mEGLDisplay, configAttribList, 0, mConfigs, 0, mConfigs.length,
+            numConfigs, 0)) {
             throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config");
         }
 
         // Configure context for OpenGL ES 2.0.
-        int[] attrib_list = {
-                EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
-                EGL14.EGL_NONE
+        int[] contextAttribList = {
+            EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
+            EGL14.EGL_NONE
         };
         mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mConfigs[0], EGL14.EGL_NO_CONTEXT,
-                attrib_list, 0);
+            contextAttribList, 0);
         checkEglError("eglCreateContext");
         if (mEGLContext == null) {
             throw new RuntimeException("null context");
@@ -186,7 +196,7 @@
     /**
      * Returns the Surface that the MediaCodec receives buffers from.
      */
-    public Surface getSurface() {
+    public @NonNull Surface getSurface() {
         return mSurface;
     }
 
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EncoderBase.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EncoderBase.java
new file mode 100644
index 0000000..c8ac8d1
--- /dev/null
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/EncoderBase.java
@@ -0,0 +1,1067 @@
+/*
+ * Copyright 2022 Google Inc. All rights reserved.
+ *
+ * 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.heifwriter;
+
+import android.graphics.Bitmap;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.media.Image;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodec.CodecException;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.opengl.GLES20;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.util.Log;
+import android.util.Range;
+import android.view.Surface;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class holds common utilities for {@link HeifEncoder} and {@link AvifEncoder}, and
+ * calls media framework and encodes images into HEIF- or AVIF- compatible samples using
+ * HEVC or AV1 encoder.
+ *
+ * It currently supports three input modes: {@link #INPUT_MODE_BUFFER},
+ * {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
+ *
+ * Callback#onOutputFormatChanged(MediaCodec, MediaFormat)} and {@link
+ * Callback#onDrainOutputBuffer(MediaCodec, ByteBuffer)}. If the client
+ * requests to use grid, each tile will be sent back individually.
+ *
+ *
+ *  * HeifEncoder is made a separate class from {@link HeifWriter}, as some more
+ *  * advanced use cases might want to build solutions on top of the HeifEncoder directly.
+ *  * (eg. mux still images and video tracks into a single container).
+ *
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class EncoderBase implements AutoCloseable,
+    SurfaceTexture.OnFrameAvailableListener {
+    private static final String TAG = "EncoderBase";
+    private static final boolean DEBUG = false;
+
+    private String MIME;
+    private int GRID_WIDTH;
+    private int GRID_HEIGHT;
+    private double MAX_COMPRESS_RATIO;
+    private int INPUT_BUFFER_POOL_SIZE = 2;
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+        MediaCodec mEncoder;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final MediaFormat mCodecFormat;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final Callback mCallback;
+    private final HandlerThread mHandlerThread;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Handler mHandler;
+    private final @InputMode int mInputMode;
+    private final boolean mUseBitDepth10;
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final int mWidth;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mHeight;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mGridWidth;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mGridHeight;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mGridRows;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mGridCols;
+    private final int mNumTiles;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final boolean mUseGrid;
+
+    private int mInputIndex;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+        boolean mInputEOS;
+    private final Rect mSrcRect;
+    private final Rect mDstRect;
+    private ByteBuffer mCurrentBuffer;
+    private final ArrayList<ByteBuffer> mEmptyBuffers = new ArrayList<>();
+    private final ArrayList<ByteBuffer> mFilledBuffers = new ArrayList<>();
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final ArrayList<Integer> mCodecInputBuffers = new ArrayList<>();
+    private final boolean mCopyTiles;
+
+    // Helper for tracking EOS when surface is used
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+        SurfaceEOSTracker mEOSTracker;
+
+    // Below variables are to handle GL copy from client's surface
+    // to encoder surface when tiles are used.
+    private SurfaceTexture mInputTexture;
+    private Surface mInputSurface;
+    private Surface mEncoderSurface;
+    private EglWindowSurface mEncoderEglSurface;
+    private EglRectBlt mRectBlt;
+    private int mTextureId;
+    private final float[] mTmpMatrix = new float[16];
+    private final AtomicBoolean mStopping = new AtomicBoolean(false);
+
+    public static final int INPUT_MODE_BUFFER = HeifWriter.INPUT_MODE_BUFFER;
+    public static final int INPUT_MODE_SURFACE = HeifWriter.INPUT_MODE_SURFACE;
+    public static final int INPUT_MODE_BITMAP = HeifWriter.INPUT_MODE_BITMAP;
+    @IntDef({
+        INPUT_MODE_BUFFER,
+        INPUT_MODE_SURFACE,
+        INPUT_MODE_BITMAP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InputMode {}
+
+    public static abstract class Callback {
+        /**
+         * Called when the output format has changed.
+         *
+         * @param encoder The EncoderBase object.
+         * @param format The new output format.
+         */
+        public abstract void onOutputFormatChanged(
+            @NonNull EncoderBase encoder, @NonNull MediaFormat format);
+
+        /**
+         * Called when an output buffer becomes available.
+         *
+         * @param encoder The EncoderBase object.
+         * @param byteBuffer the available output buffer.
+         */
+        public abstract void onDrainOutputBuffer(
+            @NonNull EncoderBase encoder, @NonNull ByteBuffer byteBuffer);
+
+        /**
+         * Called when encoding reached the end of stream without error.
+         *
+         * @param encoder The EncoderBase object.
+         */
+        public abstract void onComplete(@NonNull EncoderBase encoder);
+
+        /**
+         * Called when encoding hits an error.
+         *
+         * @param encoder The EncoderBase object.
+         * @param e The exception that the codec reported.
+         */
+        public abstract void onError(@NonNull EncoderBase encoder, @NonNull CodecException e);
+    }
+
+    /**
+     * Configure the encoder. Should only be called once.
+     *
+     * @param mimeType mime type. Currently it supports "HEIC" and "AVIF".
+     * @param width Width of the image.
+     * @param height Height of the image.
+     * @param useGrid Whether to encode image into tiles. If enabled, tile size will be
+     *                automatically chosen.
+     * @param quality A number between 0 and 100 (inclusive), with 100 indicating the best quality
+     *                supported by this implementation (which often results in larger file size).
+     * @param inputMode The input type of this encoding session.
+     * @param handler If not null, client will receive all callbacks on the handler's looper.
+     *                Otherwise, client will receive callbacks on a looper created by us.
+     * @param cb The callback to receive various messages from the heif encoder.
+     */
+    protected EncoderBase(@NonNull String mimeType, int width, int height, boolean useGrid,
+        int quality, @InputMode int inputMode,
+        @Nullable Handler handler, @NonNull Callback cb,
+        boolean useBitDepth10) throws IOException {
+        if (DEBUG)
+            Log.d(TAG, "width: " + width + ", height: " + height +
+                ", useGrid: " + useGrid + ", quality: " + quality +
+                ", inputMode: " + inputMode +
+                ", useBitDepth10: " + String.valueOf(useBitDepth10));
+
+        if (width < 0 || height < 0 || quality < 0 || quality > 100) {
+            throw new IllegalArgumentException("invalid encoder inputs");
+        }
+
+        switch (mimeType) {
+            case "HEIC":
+                MIME = mimeType;
+                GRID_WIDTH = HeifEncoder.GRID_WIDTH;
+                GRID_HEIGHT = HeifEncoder.GRID_HEIGHT;
+                MAX_COMPRESS_RATIO = HeifEncoder.MAX_COMPRESS_RATIO;
+                break;
+            case "AVIF":
+                MIME = mimeType;
+                GRID_WIDTH = AvifEncoder.GRID_WIDTH;
+                GRID_HEIGHT = AvifEncoder.GRID_HEIGHT;
+                MAX_COMPRESS_RATIO = AvifEncoder.MAX_COMPRESS_RATIO;
+                break;
+            default:
+                Log.e(TAG, "Not supported mime type: " + mimeType);
+        }
+
+        boolean useHeicEncoder = false;
+        MediaCodecInfo.CodecCapabilities caps = null;
+        switch (MIME) {
+            case "HEIC":
+                try {
+                    mEncoder = MediaCodec.createEncoderByType(
+                        MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
+                    caps = mEncoder.getCodecInfo().getCapabilitiesForType(
+                        MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
+                    // If the HEIC encoder can't support the size, fall back to HEVC encoder.
+                    if (!caps.getVideoCapabilities().isSizeSupported(width, height)) {
+                        mEncoder.release();
+                        mEncoder = null;
+                        throw new Exception();
+                    }
+                    useHeicEncoder = true;
+                } catch (Exception e) {
+                    mEncoder = MediaCodec.createByCodecName(HeifEncoder.findHevcFallback());
+                    caps = mEncoder.getCodecInfo()
+                        .getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_HEVC);
+                    // Disable grid if the image is too small
+                    useGrid &= (width > GRID_WIDTH || height > GRID_HEIGHT);
+                    // Always enable grid if the size is too large for the HEVC encoder
+                    useGrid |= !caps.getVideoCapabilities().isSizeSupported(width, height);
+                }
+                break;
+            case "AVIF":
+                mEncoder = MediaCodec.createByCodecName(AvifEncoder.findAv1Fallback());
+                caps = mEncoder.getCodecInfo()
+                    .getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_AV1);
+                // Disable grid if the image is too small
+                useGrid &= (width > GRID_WIDTH || height > GRID_HEIGHT);
+                // Always enable grid if the size is too large for the AV1 encoder
+                useGrid |= !caps.getVideoCapabilities().isSizeSupported(width, height);
+                break;
+            default:
+                Log.e(TAG, "Not supported mime type: " + MIME);
+        }
+
+        mInputMode = inputMode;
+        mUseBitDepth10 = useBitDepth10;
+        mCallback = cb;
+
+        Looper looper = (handler != null) ? handler.getLooper() : null;
+        if (looper == null) {
+            mHandlerThread = new HandlerThread("HeifEncoderThread",
+                Process.THREAD_PRIORITY_FOREGROUND);
+            mHandlerThread.start();
+            looper = mHandlerThread.getLooper();
+        } else {
+            mHandlerThread = null;
+        }
+        mHandler = new Handler(looper);
+        boolean useSurfaceInternally =
+            (inputMode == INPUT_MODE_SURFACE) || (inputMode == INPUT_MODE_BITMAP);
+        int colorFormat = useSurfaceInternally ? CodecCapabilities.COLOR_FormatSurface :
+                (useBitDepth10 ? CodecCapabilities.COLOR_FormatYUVP010 :
+                CodecCapabilities.COLOR_FormatYUV420Flexible);
+        mCopyTiles = (useGrid && !useHeicEncoder) || (inputMode == INPUT_MODE_BITMAP);
+
+        mWidth = width;
+        mHeight = height;
+        mUseGrid = useGrid;
+
+        int gridWidth, gridHeight, gridRows, gridCols;
+
+        if (useGrid) {
+            gridWidth = GRID_WIDTH;
+            gridHeight = GRID_HEIGHT;
+            gridRows = (height + GRID_HEIGHT - 1) / GRID_HEIGHT;
+            gridCols = (width + GRID_WIDTH - 1) / GRID_WIDTH;
+        } else {
+            gridWidth = mWidth;
+            gridHeight = mHeight;
+            gridRows = 1;
+            gridCols = 1;
+        }
+
+        MediaFormat codecFormat;
+        if (useHeicEncoder) {
+            codecFormat = MediaFormat.createVideoFormat(
+                MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC, mWidth, mHeight);
+        } else {
+            codecFormat = MediaFormat.createVideoFormat(
+                MediaFormat.MIMETYPE_VIDEO_HEVC, gridWidth, gridHeight);
+        }
+
+        if (useGrid) {
+            codecFormat.setInteger(MediaFormat.KEY_TILE_WIDTH, gridWidth);
+            codecFormat.setInteger(MediaFormat.KEY_TILE_HEIGHT, gridHeight);
+            codecFormat.setInteger(MediaFormat.KEY_GRID_COLUMNS, gridCols);
+            codecFormat.setInteger(MediaFormat.KEY_GRID_ROWS, gridRows);
+        }
+
+        if (useHeicEncoder) {
+            mGridWidth = width;
+            mGridHeight = height;
+            mGridRows = 1;
+            mGridCols = 1;
+        } else {
+            mGridWidth = gridWidth;
+            mGridHeight = gridHeight;
+            mGridRows = gridRows;
+            mGridCols = gridCols;
+        }
+        mNumTiles = mGridRows * mGridCols;
+
+        codecFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);
+        codecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
+        codecFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mNumTiles);
+
+        // When we're doing tiles, set the operating rate higher as the size
+        // is small, otherwise set to the normal 30fps.
+        if (mNumTiles > 1) {
+            codecFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, 120);
+        } else {
+            codecFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, 30);
+        }
+
+        if (useSurfaceInternally && !mCopyTiles) {
+            // Use fixed PTS gap and disable backward frame drop
+            Log.d(TAG, "Setting fixed pts gap");
+            codecFormat.setLong(MediaFormat.KEY_MAX_PTS_GAP_TO_ENCODER, -1000000);
+        }
+
+        MediaCodecInfo.EncoderCapabilities encoderCaps = caps.getEncoderCapabilities();
+
+        if (encoderCaps.isBitrateModeSupported(
+            MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
+            Log.d(TAG, "Setting bitrate mode to constant quality");
+            Range<Integer> qualityRange = encoderCaps.getQualityRange();
+            Log.d(TAG, "Quality range: " + qualityRange);
+            codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
+                MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
+            codecFormat.setInteger(MediaFormat.KEY_QUALITY, (int) (qualityRange.getLower() +
+                (qualityRange.getUpper() - qualityRange.getLower()) * quality / 100.0));
+        } else {
+            if (encoderCaps.isBitrateModeSupported(
+                MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR)) {
+                Log.d(TAG, "Setting bitrate mode to constant bitrate");
+                codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
+                    MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
+            } else { // assume VBR
+                Log.d(TAG, "Setting bitrate mode to variable bitrate");
+                codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
+                    MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
+            }
+            // Calculate the bitrate based on image dimension, max compression ratio and quality.
+            // Note that we set the frame rate to the number of tiles, so the bitrate would be the
+            // intended bits for one image.
+            int bitrate = caps.getVideoCapabilities().getBitrateRange().clamp(
+                (int) (width * height * 1.5 * 8 * MAX_COMPRESS_RATIO * quality / 100.0f));
+            codecFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+        }
+
+        mCodecFormat = codecFormat;
+
+        mDstRect = new Rect(0, 0, mGridWidth, mGridHeight);
+        mSrcRect = new Rect();
+    }
+
+    /**
+     * Finish setting up the encoder.
+     * Call MediaCodec.configure() method so that mEncoder enters configured stage, then add input
+     * surface or add input buffers if needed.
+     *
+     * Note: this method must be called after the constructor.
+     */
+    protected void finishSettingUpEncoder(boolean useBitDepth10) {
+        boolean useSurfaceInternally =
+            (mInputMode == INPUT_MODE_SURFACE) || (mInputMode == INPUT_MODE_BITMAP);
+
+        mEncoder.configure(mCodecFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+
+        if (useSurfaceInternally) {
+            mEncoderSurface = mEncoder.createInputSurface();
+
+            mEOSTracker = new SurfaceEOSTracker(mCopyTiles);
+
+            if (mCopyTiles) {
+                mEncoderEglSurface = new EglWindowSurface(mEncoderSurface, useBitDepth10);
+                mEncoderEglSurface.makeCurrent();
+
+                mRectBlt = new EglRectBlt(
+                    new Texture2dProgram((mInputMode == INPUT_MODE_BITMAP)
+                        ? Texture2dProgram.TEXTURE_2D
+                        : Texture2dProgram.TEXTURE_EXT),
+                    mWidth, mHeight);
+
+                mTextureId = mRectBlt.createTextureObject();
+
+                if (mInputMode == INPUT_MODE_SURFACE) {
+                    // use single buffer mode to block on input
+                    mInputTexture = new SurfaceTexture(mTextureId, true);
+                    mInputTexture.setOnFrameAvailableListener(this);
+                    mInputTexture.setDefaultBufferSize(mWidth, mHeight);
+                    mInputSurface = new Surface(mInputTexture);
+                }
+
+                // make uncurrent since onFrameAvailable could be called on arbituray thread.
+                // making the context current on a different thread will cause error.
+                mEncoderEglSurface.makeUnCurrent();
+            } else {
+                mInputSurface = mEncoderSurface;
+            }
+        } else {
+            for (int i = 0; i < INPUT_BUFFER_POOL_SIZE; i++) {
+                int bufferSize = mUseBitDepth10 ? mWidth * mHeight * 3 : mWidth * mHeight * 3 / 2;
+                mEmptyBuffers.add(ByteBuffer.allocateDirect(bufferSize));
+            }
+        }
+    }
+
+    /**
+     * Copies from source frame to encoder inputs using GL. The source could be either
+     * client's input surface, or the input bitmap loaded to texture.
+     */
+    private void copyTilesGL() {
+        GLES20.glViewport(0, 0, mGridWidth, mGridHeight);
+
+        for (int row = 0; row < mGridRows; row++) {
+            for (int col = 0; col < mGridCols; col++) {
+                int left = col * mGridWidth;
+                int top = row * mGridHeight;
+                mSrcRect.set(left, top, left + mGridWidth, top + mGridHeight);
+                try {
+                    mRectBlt.copyRect(mTextureId, Texture2dProgram.V_FLIP_MATRIX, mSrcRect);
+                } catch (RuntimeException e) {
+                    // EGL copy could throw if the encoder input surface is no longer valid
+                    // after encoder is released. This is not an error because we're already
+                    // stopping (either after EOS is received or requested by client).
+                    if (mStopping.get()) {
+                        return;
+                    }
+                    throw e;
+                }
+                mEncoderEglSurface.setPresentationTime(
+                    1000 * computePresentationTime(mInputIndex++));
+                mEncoderEglSurface.swapBuffers();
+            }
+        }
+    }
+
+    @Override
+    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+        synchronized (this) {
+            if (mEncoderEglSurface == null) {
+                return;
+            }
+
+            mEncoderEglSurface.makeCurrent();
+
+            surfaceTexture.updateTexImage();
+            surfaceTexture.getTransformMatrix(mTmpMatrix);
+
+            long timestampNs = surfaceTexture.getTimestamp();
+
+            if (DEBUG) Log.d(TAG, "onFrameAvailable: timestampUs " + (timestampNs / 1000));
+
+            boolean takeFrame = mEOSTracker.updateLastInputAndEncoderTime(timestampNs,
+                computePresentationTime(mInputIndex + mNumTiles - 1));
+
+            if (takeFrame) {
+                copyTilesGL();
+            }
+
+            surfaceTexture.releaseTexImage();
+
+            // make uncurrent since the onFrameAvailable could be called on arbituray thread.
+            // making the context current on a different thread will cause error.
+            mEncoderEglSurface.makeUnCurrent();
+        }
+    }
+
+    /**
+     * Start the encoding process.
+     */
+    public void start() {
+        mEncoder.start();
+    }
+
+    /**
+     * Add one YUV buffer to be encoded. This might block if the encoder can't process the input
+     * buffers fast enough.
+     *
+     * After the call returns, the client can reuse the data array.
+     *
+     * @param format The YUV format as defined in {@link android.graphics.ImageFormat}, currently
+     *               only support YUV_420_888.
+     *
+     * @param data byte array containing the YUV data. If the format has more than one planes,
+     *             they must be concatenated.
+     */
+    public void addYuvBuffer(int format, @NonNull byte[] data) {
+        if (mInputMode != INPUT_MODE_BUFFER) {
+            throw new IllegalStateException(
+                "addYuvBuffer is only allowed in buffer input mode");
+        }
+        if ((mUseBitDepth10 && format != ImageFormat.YCBCR_P010)
+                || (!mUseBitDepth10 && format != ImageFormat.YUV_420_888)) {
+            throw new IllegalStateException("Wrong color format.");
+        }
+        if (data == null
+                || (mUseBitDepth10 && data.length != mWidth * mHeight * 3)
+                || (!mUseBitDepth10 && data.length != mWidth * mHeight * 3 / 2)) {
+            throw new IllegalArgumentException("invalid data");
+        }
+        addYuvBufferInternal(data);
+    }
+
+    /**
+     * Retrieves the input surface for encoding.
+     *
+     * Will only return valid value if configured to use surface input.
+     */
+    public @NonNull Surface getInputSurface() {
+        if (mInputMode != INPUT_MODE_SURFACE) {
+            throw new IllegalStateException(
+                "getInputSurface is only allowed in surface input mode");
+        }
+        return mInputSurface;
+    }
+
+    /**
+     * Sets the timestamp (in nano seconds) of the last input frame to encode. Frames with
+     * timestamps larger than the specified value will not be encoded. However, if a frame
+     * already started encoding when this is set, all tiles within that frame will be encoded.
+     *
+     * This method only applies when surface is used.
+     */
+    public void setEndOfInputStreamTimestamp(long timestampNs) {
+        if (mInputMode != INPUT_MODE_SURFACE) {
+            throw new IllegalStateException(
+                "setEndOfInputStreamTimestamp is only allowed in surface input mode");
+        }
+        if (mEOSTracker != null) {
+            mEOSTracker.updateInputEOSTime(timestampNs);
+        }
+    }
+
+    /**
+     * Adds one bitmap to be encoded.
+     */
+    public void addBitmap(@NonNull Bitmap bitmap) {
+        if (mInputMode != INPUT_MODE_BITMAP) {
+            throw new IllegalStateException("addBitmap is only allowed in bitmap input mode");
+        }
+
+        boolean takeFrame = mEOSTracker.updateLastInputAndEncoderTime(
+            computePresentationTime(mInputIndex) * 1000,
+            computePresentationTime(mInputIndex + mNumTiles - 1));
+
+        if (!takeFrame) return;
+
+        synchronized (this) {
+            if (mEncoderEglSurface == null) {
+                return;
+            }
+
+            mEncoderEglSurface.makeCurrent();
+
+            mRectBlt.loadTexture(mTextureId, bitmap);
+
+            copyTilesGL();
+
+            // make uncurrent since the onFrameAvailable could be called on arbituray thread.
+            // making the context current on a different thread will cause error.
+            mEncoderEglSurface.makeUnCurrent();
+        }
+    }
+
+    /**
+     * Sends input EOS to the encoder. Result will be notified asynchronously via
+     * {@link Callback#onComplete(EncoderBase)} if encoder reaches EOS without error, or
+     * {@link Callback#onError(EncoderBase, CodecException)} otherwise.
+     */
+    public void stopAsync() {
+        if (mInputMode == INPUT_MODE_BITMAP) {
+            // here we simply set the EOS timestamp to 0, so that the cut off will be the last
+            // bitmap ever added.
+            mEOSTracker.updateInputEOSTime(0);
+        } else if (mInputMode == INPUT_MODE_BUFFER) {
+            addYuvBufferInternal(null);
+        }
+    }
+
+    /**
+     * Generates the presentation time for input frame N, in microseconds.
+     * The timestamp advances 1 sec for every whole frame.
+     */
+    private long computePresentationTime(int frameIndex) {
+        return 132 + (long)frameIndex * 1000000 / mNumTiles;
+    }
+
+    /**
+     * Obtains one empty input buffer and copies the data into it. Before input
+     * EOS is sent, this would block until the data is copied. After input EOS
+     * is sent, this would return immediately.
+     */
+    private void addYuvBufferInternal(@Nullable byte[] data) {
+        ByteBuffer buffer = acquireEmptyBuffer();
+        if (buffer == null) {
+            return;
+        }
+        buffer.clear();
+        if (data != null) {
+            buffer.put(data);
+        }
+        buffer.flip();
+        synchronized (mFilledBuffers) {
+            mFilledBuffers.add(buffer);
+        }
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                maybeCopyOneTileYUV();
+            }
+        });
+    }
+
+    /**
+     * Routine to copy one tile if we have both input and codec buffer available.
+     *
+     * Must be called on the handler looper that also handles the MediaCodec callback.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    void maybeCopyOneTileYUV() {
+        ByteBuffer currentBuffer;
+        while ((currentBuffer = getCurrentBuffer()) != null && !mCodecInputBuffers.isEmpty()) {
+            int index = mCodecInputBuffers.remove(0);
+
+            // 0-length input means EOS.
+            boolean inputEOS = (mInputIndex % mNumTiles == 0) && (currentBuffer.remaining() == 0);
+
+            if (!inputEOS) {
+                Image image = mEncoder.getInputImage(index);
+                int left = mGridWidth * (mInputIndex % mGridCols);
+                int top = mGridHeight * (mInputIndex / mGridCols % mGridRows);
+                mSrcRect.set(left, top, left + mGridWidth, top + mGridHeight);
+                copyOneTileYUV(currentBuffer, image, mWidth, mHeight, mSrcRect, mDstRect,
+                        mUseBitDepth10);
+            }
+
+            mEncoder.queueInputBuffer(index, 0,
+                inputEOS ? 0 : mEncoder.getInputBuffer(index).capacity(),
+                computePresentationTime(mInputIndex++),
+                inputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+
+            if (inputEOS || mInputIndex % mNumTiles == 0) {
+                returnEmptyBufferAndNotify(inputEOS);
+            }
+        }
+    }
+
+    /**
+     * Copies from a rect from src buffer to dst image.
+     * TOOD: This will be replaced by JNI.
+     */
+    private static void copyOneTileYUV(ByteBuffer srcBuffer, Image dstImage,
+            int srcWidth, int srcHeight, Rect srcRect, Rect dstRect, boolean useBitDepth10) {
+        if (srcRect.width() != dstRect.width() || srcRect.height() != dstRect.height()) {
+            throw new IllegalArgumentException("src and dst rect size are different!");
+        }
+        if (srcWidth % 2 != 0      || srcHeight % 2 != 0      ||
+            srcRect.left % 2 != 0  || srcRect.top % 2 != 0    ||
+            srcRect.right % 2 != 0 || srcRect.bottom % 2 != 0 ||
+            dstRect.left % 2 != 0  || dstRect.top % 2 != 0    ||
+            dstRect.right % 2 != 0 || dstRect.bottom % 2 != 0) {
+            throw new IllegalArgumentException("src or dst are not aligned!");
+        }
+
+        Image.Plane[] planes = dstImage.getPlanes();
+        if (useBitDepth10) {
+            // Assume pixel format is P010
+            // Y plane, UV interlaced
+            // pixel step = 2
+            for (int n = 0; n < planes.length; n++) {
+                ByteBuffer dstBuffer = planes[n].getBuffer();
+                int colStride = planes[n].getPixelStride();
+                int copyWidth = Math.min(srcRect.width(), srcWidth - srcRect.left);
+                int copyHeight = Math.min(srcRect.height(), srcHeight - srcRect.top);
+                int srcPlanePos = 0, div = 1;
+                if (n > 0) {
+                    div = 2;
+                    srcPlanePos = srcWidth * srcHeight;
+                    if (n == 2) {
+                        srcPlanePos += colStride / 2;
+                    }
+                }
+                for (int i = 0; i < copyHeight / div; i++) {
+                    srcBuffer.position(srcPlanePos +
+                        (i + srcRect.top / div) * srcWidth + srcRect.left / div);
+                    dstBuffer.position((i + dstRect.top / div) * planes[n].getRowStride()
+                        + dstRect.left * colStride / div);
+
+                    for (int j = 0; j < copyWidth / div; j++) {
+                        dstBuffer.put(srcBuffer.get());
+                        dstBuffer.put(srcBuffer.get());
+                        if (colStride > 2 /*pixel step*/ && j != copyWidth / div - 1) {
+                            dstBuffer.position(dstBuffer.position() + colStride / 2);
+                        }
+                    }
+                }
+            }
+        } else {
+            // Assume pixel format is YUV_420_Planer
+            // pixel step = 1
+            for (int n = 0; n < planes.length; n++) {
+                ByteBuffer dstBuffer = planes[n].getBuffer();
+                int colStride = planes[n].getPixelStride();
+                int copyWidth = Math.min(srcRect.width(), srcWidth - srcRect.left);
+                int copyHeight = Math.min(srcRect.height(), srcHeight - srcRect.top);
+                int srcPlanePos = 0, div = 1;
+                if (n > 0) {
+                    div = 2;
+                    srcPlanePos = srcWidth * srcHeight * (n + 3) / 4;
+                }
+                for (int i = 0; i < copyHeight / div; i++) {
+                    srcBuffer.position(srcPlanePos +
+                        (i + srcRect.top / div) * srcWidth / div + srcRect.left / div);
+                    dstBuffer.position((i + dstRect.top / div) * planes[n].getRowStride()
+                        + dstRect.left * colStride / div);
+
+                    for (int j = 0; j < copyWidth / div; j++) {
+                        dstBuffer.put(srcBuffer.get());
+                        if (colStride > 1 && j != copyWidth / div - 1) {
+                            dstBuffer.position(dstBuffer.position() + colStride - 1);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private ByteBuffer acquireEmptyBuffer() {
+        synchronized (mEmptyBuffers) {
+            // wait for an empty input buffer first
+            while (!mInputEOS && mEmptyBuffers.isEmpty()) {
+                try {
+                    mEmptyBuffers.wait();
+                } catch (InterruptedException e) {}
+            }
+
+            // if already EOS, return null to stop further encoding.
+            return mInputEOS ? null : mEmptyBuffers.remove(0);
+        }
+    }
+
+    /**
+     * Routine to get the current input buffer to copy from.
+     * Only called on callback handler thread.
+     */
+    private ByteBuffer getCurrentBuffer() {
+        if (!mInputEOS && mCurrentBuffer == null) {
+            synchronized (mFilledBuffers) {
+                mCurrentBuffer = mFilledBuffers.isEmpty() ?
+                    null : mFilledBuffers.remove(0);
+            }
+        }
+        return mInputEOS ? null : mCurrentBuffer;
+    }
+
+    /**
+     * Routine to put the consumed input buffer back into the empty buffer pool.
+     * Only called on callback handler thread.
+     */
+    private void returnEmptyBufferAndNotify(boolean inputEOS) {
+        synchronized (mEmptyBuffers) {
+            mInputEOS |= inputEOS;
+            mEmptyBuffers.add(mCurrentBuffer);
+            mEmptyBuffers.notifyAll();
+        }
+        mCurrentBuffer = null;
+    }
+
+    /**
+     * Routine to release all resources. Must be run on the same looper that
+     * handles the MediaCodec callbacks.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    void stopInternal() {
+        if (DEBUG) Log.d(TAG, "stopInternal");
+
+        // set stopping, so that the tile copy would bail out
+        // if it hits failure after this point.
+        mStopping.set(true);
+
+        // after start, mEncoder is only accessed on handler, so no need to sync.
+        try {
+            if (mEncoder != null) {
+                mEncoder.stop();
+                mEncoder.release();
+            }
+        } catch (Exception e) {
+        } finally {
+            mEncoder = null;
+        }
+
+        // unblock the addBuffer() if we're tearing down before EOS is sent.
+        synchronized (mEmptyBuffers) {
+            mInputEOS = true;
+            mEmptyBuffers.notifyAll();
+        }
+
+        // Clean up surface and Egl related refs. This lock must come after encoder
+        // release. When we're closing, we insert stopInternal() at the front of queue
+        // so that the shutdown can be processed promptly, this means there might be
+        // some output available requests queued after this. As the tile copies trying
+        // to finish the current frame, there is a chance is might get stuck because
+        // those outputs were not returned. Shutting down the encoder will make break
+        // the tile copier out of that.
+        synchronized(this) {
+            try {
+                if (mRectBlt != null) {
+                    mRectBlt.release(false);
+                }
+            } catch (Exception e) {
+            } finally {
+                mRectBlt = null;
+            }
+
+            try {
+                if (mEncoderEglSurface != null) {
+                    // Note that this frees mEncoderSurface too. If mEncoderEglSurface is not
+                    // there, client is responsible to release the input surface it got from us,
+                    // we don't release mEncoderSurface here.
+                    mEncoderEglSurface.release();
+                }
+            } catch (Exception e) {
+            } finally {
+                mEncoderEglSurface = null;
+            }
+
+            try {
+                if (mInputTexture != null) {
+                    mInputTexture.release();
+                }
+            } catch (Exception e) {
+            } finally {
+                mInputTexture = null;
+            }
+        }
+    }
+
+    /**
+     * This class handles EOS for surface or bitmap inputs.
+     *
+     * When encoding from surface or bitmap, we can't call
+     * {@link MediaCodec#signalEndOfInputStream()} immediately after input is drawn, since this
+     * could drop all pending frames in the buffer queue. When there are tiles, this could leave
+     * us a partially encoded image.
+     *
+     * So here we track the EOS status by timestamps, and only signal EOS to the encoder
+     * when we collected all images we need.
+     *
+     * Since this is updated from multiple threads ({@link #setEndOfInputStreamTimestamp(long)},
+     * {@link EncoderCallback#onOutputBufferAvailable(MediaCodec, int, BufferInfo)},
+     * {@link #addBitmap(Bitmap)} and {@link #onFrameAvailable(SurfaceTexture)}), it must be fully
+     * synchronized.
+     *
+     * Note that when buffer input is used, the EOS flag is set in
+     * {@link EncoderCallback#onInputBufferAvailable(MediaCodec, int)} and this class is not used.
+     */
+    private class SurfaceEOSTracker {
+        private static final boolean DEBUG_EOS = false;
+
+        final boolean mCopyTiles;
+        long mInputEOSTimeNs = -1;
+        long mLastInputTimeNs = -1;
+        long mEncoderEOSTimeUs = -1;
+        long mLastEncoderTimeUs = -1;
+        long mLastOutputTimeUs = -1;
+        boolean mSignaled;
+
+        SurfaceEOSTracker(boolean copyTiles) {
+            mCopyTiles = copyTiles;
+        }
+
+        synchronized void updateInputEOSTime(long timestampNs) {
+            if (DEBUG_EOS) Log.d(TAG, "updateInputEOSTime: " + timestampNs);
+
+            if (mCopyTiles) {
+                if (mInputEOSTimeNs < 0) {
+                    mInputEOSTimeNs = timestampNs;
+                }
+            } else {
+                if (mEncoderEOSTimeUs < 0) {
+                    mEncoderEOSTimeUs = timestampNs / 1000;
+                }
+            }
+            updateEOSLocked();
+        }
+
+        synchronized boolean updateLastInputAndEncoderTime(long inputTimeNs, long encoderTimeUs) {
+            if (DEBUG_EOS) Log.d(TAG,
+                "updateLastInputAndEncoderTime: " + inputTimeNs + ", " + encoderTimeUs);
+
+            boolean shouldTakeFrame = mInputEOSTimeNs < 0 || inputTimeNs <= mInputEOSTimeNs;
+            if (shouldTakeFrame) {
+                mLastEncoderTimeUs = encoderTimeUs;
+            }
+            mLastInputTimeNs = inputTimeNs;
+            updateEOSLocked();
+            return shouldTakeFrame;
+        }
+
+        synchronized void updateLastOutputTime(long outputTimeUs) {
+            if (DEBUG_EOS) Log.d(TAG, "updateLastOutputTime: " + outputTimeUs);
+
+            mLastOutputTimeUs = outputTimeUs;
+            updateEOSLocked();
+        }
+
+        private void updateEOSLocked() {
+            if (mSignaled) {
+                return;
+            }
+            if (mEncoderEOSTimeUs < 0) {
+                if (mInputEOSTimeNs >= 0 && mLastInputTimeNs >= mInputEOSTimeNs) {
+                    if (mLastEncoderTimeUs < 0) {
+                        doSignalEOSLocked();
+                        return;
+                    }
+                    // mEncoderEOSTimeUs tracks the timestamp of the last output buffer we
+                    // will wait for. When that buffer arrives, encoder will be signalled EOS.
+                    mEncoderEOSTimeUs = mLastEncoderTimeUs;
+                    if (DEBUG_EOS) Log.d(TAG,
+                        "updateEOSLocked: mEncoderEOSTimeUs " + mEncoderEOSTimeUs);
+                }
+            }
+            if (mEncoderEOSTimeUs >= 0 && mEncoderEOSTimeUs <= mLastOutputTimeUs) {
+                doSignalEOSLocked();
+            }
+        }
+
+        private void doSignalEOSLocked() {
+            if (DEBUG_EOS) Log.d(TAG, "doSignalEOSLocked");
+
+            mHandler.post(new Runnable() {
+                @Override public void run() {
+                    if (mEncoder != null) {
+                        mEncoder.signalEndOfInputStream();
+                    }
+                }
+            });
+
+            mSignaled = true;
+        }
+    }
+
+
+    /**
+     * MediaCodec callback for HEVC/AV1 encoding.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    abstract class EncoderCallback extends MediaCodec.Callback {
+        private boolean mOutputEOS;
+
+        @Override
+        public void onInputBufferAvailable(MediaCodec codec, int index) {
+            if (codec != mEncoder || mInputEOS) return;
+
+            if (DEBUG) Log.d(TAG, "onInputBufferAvailable: " + index);
+            mCodecInputBuffers.add(index);
+            maybeCopyOneTileYUV();
+        }
+
+        @Override
+        public void onOutputBufferAvailable(MediaCodec codec, int index, BufferInfo info) {
+            if (codec != mEncoder || mOutputEOS) return;
+
+            if (DEBUG) {
+                Log.d(TAG, "onOutputBufferAvailable: " + index
+                    + ", time " + info.presentationTimeUs
+                    + ", size " + info.size
+                    + ", flags " + info.flags);
+            }
+
+            if ((info.size > 0) && ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0)) {
+                ByteBuffer outputBuffer = codec.getOutputBuffer(index);
+
+                // reset position as addBuffer() modifies it
+                outputBuffer.position(info.offset);
+                outputBuffer.limit(info.offset + info.size);
+
+                if (mEOSTracker != null) {
+                    mEOSTracker.updateLastOutputTime(info.presentationTimeUs);
+                }
+
+                mCallback.onDrainOutputBuffer(EncoderBase.this, outputBuffer);
+            }
+
+            mOutputEOS |= ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0);
+
+            codec.releaseOutputBuffer(index, false);
+
+            if (mOutputEOS) {
+                stopAndNotify(null);
+            }
+        }
+
+        @Override
+        public void onError(MediaCodec codec, CodecException e) {
+            if (codec != mEncoder) return;
+
+            Log.e(TAG, "onError: " + e);
+            stopAndNotify(e);
+        }
+
+        private void stopAndNotify(@Nullable CodecException e) {
+            stopInternal();
+            if (e == null) {
+                mCallback.onComplete(EncoderBase.this);
+            } else {
+                mCallback.onError(EncoderBase.this, e);
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        // unblock the addBuffer() if we're tearing down before EOS is sent.
+        synchronized (mEmptyBuffers) {
+            mInputEOS = true;
+            mEmptyBuffers.notifyAll();
+        }
+
+        mHandler.postAtFrontOfQueue(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    stopInternal();
+                } catch (Exception e) {
+                    // We don't want to crash when closing.
+                }
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifEncoder.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifEncoder.java
index e520056..a0b0e9a 100644
--- a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifEncoder.java
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifEncoder.java
@@ -16,36 +16,20 @@
 
 package androidx.heifwriter;
 
-import android.graphics.Bitmap;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.media.Image;
 import android.media.MediaCodec;
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaCodec.CodecException;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
-import android.opengl.GLES20;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Process;
 import android.util.Log;
 import android.util.Range;
-import android.view.Surface;
 
-import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * This class encodes images into HEIF-compatible samples using HEVC encoder.
@@ -62,115 +46,16 @@
  * advanced use cases might want to build solutions on top of the HeifEncoder directly.
  * (eg. mux still images and video tracks into a single container).
  */
-final class HeifEncoder implements AutoCloseable,
-        SurfaceTexture.OnFrameAvailableListener {
+final class HeifEncoder extends EncoderBase {
     private static final String TAG = "HeifEncoder";
     private static final boolean DEBUG = false;
 
-    private static final int GRID_WIDTH = 512;
-    private static final int GRID_HEIGHT = 512;
-    private static final double MAX_COMPRESS_RATIO = 0.25f;
-    private static final int INPUT_BUFFER_POOL_SIZE = 2;
+    protected static final int GRID_WIDTH = 512;
+    protected static final int GRID_HEIGHT = 512;
+    protected static final double MAX_COMPRESS_RATIO = 0.25f;
 
     private static final MediaCodecList sMCL =
-            new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    MediaCodec mEncoder;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final Callback mCallback;
-    private final HandlerThread mHandlerThread;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final Handler mHandler;
-    private final @InputMode int mInputMode;
-
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mWidth;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mHeight;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mGridWidth;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mGridHeight;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mGridRows;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mGridCols;
-    private final int mNumTiles;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final boolean mUseGrid;
-
-    private int mInputIndex;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    boolean mInputEOS;
-    private final Rect mSrcRect;
-    private final Rect mDstRect;
-    private ByteBuffer mCurrentBuffer;
-    private final ArrayList<ByteBuffer> mEmptyBuffers = new ArrayList<>();
-    private final ArrayList<ByteBuffer> mFilledBuffers = new ArrayList<>();
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final ArrayList<Integer> mCodecInputBuffers = new ArrayList<>();
-
-    // Helper for tracking EOS when surface is used
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    SurfaceEOSTracker mEOSTracker;
-
-    // Below variables are to handle GL copy from client's surface
-    // to encoder surface when tiles are used.
-    private SurfaceTexture mInputTexture;
-    private Surface mInputSurface;
-    private Surface mEncoderSurface;
-    private EglWindowSurface mEncoderEglSurface;
-    private EglRectBlt mRectBlt;
-    private int mTextureId;
-    private final float[] mTmpMatrix = new float[16];
-    private final AtomicBoolean mStopping = new AtomicBoolean(false);
-
-    public static final int INPUT_MODE_BUFFER = HeifWriter.INPUT_MODE_BUFFER;
-    public static final int INPUT_MODE_SURFACE = HeifWriter.INPUT_MODE_SURFACE;
-    public static final int INPUT_MODE_BITMAP = HeifWriter.INPUT_MODE_BITMAP;
-    @IntDef({
-        INPUT_MODE_BUFFER,
-        INPUT_MODE_SURFACE,
-        INPUT_MODE_BITMAP,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface InputMode {}
-
-    public static abstract class Callback {
-        /**
-         * Called when the output format has changed.
-         *
-         * @param encoder The HeifEncoder object.
-         * @param format The new output format.
-         */
-        public abstract void onOutputFormatChanged(
-                @NonNull HeifEncoder encoder, @NonNull MediaFormat format);
-
-        /**
-         * Called when an output buffer becomes available.
-         *
-         * @param encoder The HeifEncoder object.
-         * @param byteBuffer the available output buffer.
-         */
-        public abstract void onDrainOutputBuffer(
-                @NonNull HeifEncoder encoder, @NonNull ByteBuffer byteBuffer);
-
-        /**
-         * Called when encoding reached the end of stream without error.
-         *
-         * @param encoder The HeifEncoder object.
-         */
-        public abstract void onComplete(@NonNull HeifEncoder encoder);
-
-        /**
-         * Called when encoding hits an error.
-         *
-         * @param encoder The HeifEncoder object.
-         * @param e The exception that the codec reported.
-         */
-        public abstract void onError(@NonNull HeifEncoder encoder, @NonNull CodecException e);
-    }
+        new MediaCodecList(MediaCodecList.REGULAR_CODECS);
 
     /**
      * Configure the heif encoding session. Should only be called once.
@@ -187,198 +72,15 @@
      * @param cb The callback to receive various messages from the heif encoder.
      */
     public HeifEncoder(int width, int height, boolean useGrid,
-                       int quality, @InputMode int inputMode,
-                       @Nullable Handler handler, @NonNull Callback cb) throws IOException {
-        if (DEBUG) Log.d(TAG, "width: " + width + ", height: " + height +
-                ", useGrid: " + useGrid + ", quality: " + quality + ", inputMode: " + inputMode);
-
-        if (width < 0 || height < 0 || quality < 0 || quality > 100) {
-            throw new IllegalArgumentException("invalid encoder inputs");
-        }
-
-        // Disable grid if the image is too small
-        useGrid &= (width > GRID_WIDTH || height > GRID_HEIGHT);
-
-        boolean useHeicEncoder = false;
-        MediaCodecInfo.CodecCapabilities caps = null;
-        try {
-            mEncoder = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
-            caps = mEncoder.getCodecInfo().getCapabilitiesForType(
-                    MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
-            // If the HEIC encoder can't support the size, fall back to HEVC encoder.
-            if (!caps.getVideoCapabilities().isSizeSupported(width, height)) {
-                mEncoder.release();
-                mEncoder = null;
-                throw new Exception();
-            }
-            useHeicEncoder = true;
-        } catch (Exception e) {
-            mEncoder = MediaCodec.createByCodecName(findHevcFallback());
-            caps = mEncoder.getCodecInfo().getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_HEVC);
-            // Always enable grid if the size is too large for the HEVC encoder
-            useGrid |= !caps.getVideoCapabilities().isSizeSupported(width, height);
-        }
-
-        mInputMode = inputMode;
-
-        mCallback = cb;
-
-        Looper looper = (handler != null) ? handler.getLooper() : null;
-        if (looper == null) {
-            mHandlerThread = new HandlerThread("HeifEncoderThread",
-                    Process.THREAD_PRIORITY_FOREGROUND);
-            mHandlerThread.start();
-            looper = mHandlerThread.getLooper();
-        } else {
-            mHandlerThread = null;
-        }
-        mHandler = new Handler(looper);
-        boolean useSurfaceInternally =
-                (inputMode == INPUT_MODE_SURFACE) || (inputMode == INPUT_MODE_BITMAP);
-        int colorFormat = useSurfaceInternally ? CodecCapabilities.COLOR_FormatSurface :
-                CodecCapabilities.COLOR_FormatYUV420Flexible;
-        boolean copyTiles = (useGrid && !useHeicEncoder) || (inputMode == INPUT_MODE_BITMAP);
-
-        mWidth = width;
-        mHeight = height;
-        mUseGrid = useGrid;
-
-        int gridWidth, gridHeight, gridRows, gridCols;
-
-        if (useGrid) {
-            gridWidth = GRID_WIDTH;
-            gridHeight = GRID_HEIGHT;
-            gridRows = (height + GRID_HEIGHT - 1) / GRID_HEIGHT;
-            gridCols = (width + GRID_WIDTH - 1) / GRID_WIDTH;
-        } else {
-            gridWidth = mWidth;
-            gridHeight = mHeight;
-            gridRows = 1;
-            gridCols = 1;
-        }
-
-        MediaFormat codecFormat;
-        if (useHeicEncoder) {
-            codecFormat = MediaFormat.createVideoFormat(
-                    MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC, mWidth, mHeight);
-        } else {
-            codecFormat = MediaFormat.createVideoFormat(
-                    MediaFormat.MIMETYPE_VIDEO_HEVC, gridWidth, gridHeight);
-        }
-
-        if (useGrid) {
-            codecFormat.setInteger(MediaFormat.KEY_TILE_WIDTH, gridWidth);
-            codecFormat.setInteger(MediaFormat.KEY_TILE_HEIGHT, gridHeight);
-            codecFormat.setInteger(MediaFormat.KEY_GRID_COLUMNS, gridCols);
-            codecFormat.setInteger(MediaFormat.KEY_GRID_ROWS, gridRows);
-        }
-
-        if (useHeicEncoder) {
-            mGridWidth = width;
-            mGridHeight = height;
-            mGridRows = 1;
-            mGridCols = 1;
-        } else {
-            mGridWidth = gridWidth;
-            mGridHeight = gridHeight;
-            mGridRows = gridRows;
-            mGridCols = gridCols;
-        }
-        mNumTiles = mGridRows * mGridCols;
-
-        codecFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 0);
-        codecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
-        codecFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mNumTiles);
-
-        // When we're doing tiles, set the operating rate higher as the size
-        // is small, otherwise set to the normal 30fps.
-        if (mNumTiles > 1) {
-            codecFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, 120);
-        } else {
-            codecFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, 30);
-        }
-
-        if (useSurfaceInternally && !copyTiles) {
-            // Use fixed PTS gap and disable backward frame drop
-            Log.d(TAG, "Setting fixed pts gap");
-            codecFormat.setLong(MediaFormat.KEY_MAX_PTS_GAP_TO_ENCODER, -1000000);
-        }
-
-        MediaCodecInfo.EncoderCapabilities encoderCaps = caps.getEncoderCapabilities();
-
-        if (encoderCaps.isBitrateModeSupported(
-                MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
-            Log.d(TAG, "Setting bitrate mode to constant quality");
-            Range<Integer> qualityRange = encoderCaps.getQualityRange();
-            Log.d(TAG, "Quality range: " + qualityRange);
-            codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
-                    MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
-            codecFormat.setInteger(MediaFormat.KEY_QUALITY, (int) (qualityRange.getLower() +
-                            (qualityRange.getUpper() - qualityRange.getLower()) * quality / 100.0));
-        } else {
-            if (encoderCaps.isBitrateModeSupported(
-                    MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR)) {
-                Log.d(TAG, "Setting bitrate mode to constant bitrate");
-                codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
-                        MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
-            } else { // assume VBR
-                Log.d(TAG, "Setting bitrate mode to variable bitrate");
-                codecFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
-                        MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
-            }
-            // Calculate the bitrate based on image dimension, max compression ratio and quality.
-            // Note that we set the frame rate to the number of tiles, so the bitrate would be the
-            // intended bits for one image.
-            int bitrate = caps.getVideoCapabilities().getBitrateRange().clamp(
-                    (int) (width * height * 1.5 * 8 * MAX_COMPRESS_RATIO * quality / 100.0f));
-            codecFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
-        }
-
-        mEncoder.setCallback(new EncoderCallback(), mHandler);
-        mEncoder.configure(codecFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
-
-        if (useSurfaceInternally) {
-            mEncoderSurface = mEncoder.createInputSurface();
-
-            mEOSTracker = new SurfaceEOSTracker(copyTiles);
-
-            if (copyTiles) {
-                mEncoderEglSurface = new EglWindowSurface(mEncoderSurface);
-                mEncoderEglSurface.makeCurrent();
-
-                mRectBlt = new EglRectBlt(
-                        new Texture2dProgram((inputMode == INPUT_MODE_BITMAP)
-                                ? Texture2dProgram.TEXTURE_2D
-                                : Texture2dProgram.TEXTURE_EXT),
-                        mWidth, mHeight);
-
-                mTextureId = mRectBlt.createTextureObject();
-
-                if (inputMode == INPUT_MODE_SURFACE) {
-                    // use single buffer mode to block on input
-                    mInputTexture = new SurfaceTexture(mTextureId, true);
-                    mInputTexture.setOnFrameAvailableListener(this);
-                    mInputTexture.setDefaultBufferSize(mWidth, mHeight);
-                    mInputSurface = new Surface(mInputTexture);
-                }
-
-                // make uncurrent since onFrameAvailable could be called on arbituray thread.
-                // making the context current on a different thread will cause error.
-                mEncoderEglSurface.makeUnCurrent();
-            } else {
-                mInputSurface = mEncoderSurface;
-            }
-        } else {
-            for (int i = 0; i < INPUT_BUFFER_POOL_SIZE; i++) {
-                mEmptyBuffers.add(ByteBuffer.allocateDirect(mWidth * mHeight * 3 / 2));
-            }
-        }
-
-        mDstRect = new Rect(0, 0, mGridWidth, mGridHeight);
-        mSrcRect = new Rect();
+            int quality, @InputMode int inputMode,
+            @Nullable Handler handler, @NonNull Callback cb) throws IOException {
+        super("HEIC", width, height, useGrid, quality, inputMode, handler, cb,
+            /* useBitDepth10 */ false);
+        mEncoder.setCallback(new HevcEncoderCallback(), mHandler);
+        finishSettingUpEncoder(/* useBitDepth10 */ false);
     }
 
-    private String findHevcFallback() {
+    protected static String findHevcFallback() {
         String hevc = null; // first HEVC encoder
         for (MediaCodecInfo info : sMCL.getCodecInfos()) {
             if (!info.isEncoder()) {
@@ -394,7 +96,7 @@
                 continue;
             }
             if (caps.getEncoderCapabilities().isBitrateModeSupported(
-                    MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
+                MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
                 // Encoder that supports CQ mode is preferred over others,
                 // return the first encoder that supports CQ mode.
                 // (No need to check if it's hw based, it's already listed in
@@ -408,508 +110,12 @@
         // If no encoders support CQ, return the first HEVC encoder.
         return hevc;
     }
-    /**
-     * Copies from source frame to encoder inputs using GL. The source could be either
-     * client's input surface, or the input bitmap loaded to texture.
-     */
-    private void copyTilesGL() {
-        GLES20.glViewport(0, 0, mGridWidth, mGridHeight);
-
-        for (int row = 0; row < mGridRows; row++) {
-            for (int col = 0; col < mGridCols; col++) {
-                int left = col * mGridWidth;
-                int top = row * mGridHeight;
-                mSrcRect.set(left, top, left + mGridWidth, top + mGridHeight);
-                try {
-                    mRectBlt.copyRect(mTextureId, Texture2dProgram.V_FLIP_MATRIX, mSrcRect);
-                } catch (RuntimeException e) {
-                    // EGL copy could throw if the encoder input surface is no longer valid
-                    // after encoder is released. This is not an error because we're already
-                    // stopping (either after EOS is received or requested by client).
-                    if (mStopping.get()) {
-                        return;
-                    }
-                    throw e;
-                }
-                mEncoderEglSurface.setPresentationTime(
-                        1000 * computePresentationTime(mInputIndex++));
-                mEncoderEglSurface.swapBuffers();
-            }
-        }
-    }
-
-    @Override
-    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
-        synchronized (this) {
-            if (mEncoderEglSurface == null) {
-                return;
-            }
-
-            mEncoderEglSurface.makeCurrent();
-
-            surfaceTexture.updateTexImage();
-            surfaceTexture.getTransformMatrix(mTmpMatrix);
-
-            long timestampNs = surfaceTexture.getTimestamp();
-
-            if (DEBUG) Log.d(TAG, "onFrameAvailable: timestampUs " + (timestampNs / 1000));
-
-            boolean takeFrame = mEOSTracker.updateLastInputAndEncoderTime(timestampNs,
-                    computePresentationTime(mInputIndex + mNumTiles - 1));
-
-            if (takeFrame) {
-                copyTilesGL();
-            }
-
-            surfaceTexture.releaseTexImage();
-
-            // make uncurrent since the onFrameAvailable could be called on arbituray thread.
-            // making the context current on a different thread will cause error.
-            mEncoderEglSurface.makeUnCurrent();
-        }
-    }
-
-    /**
-     * Start the encoding process.
-     */
-    public void start() {
-        mEncoder.start();
-    }
-
-    /**
-     * Add one YUV buffer to be encoded. This might block if the encoder can't process the input
-     * buffers fast enough.
-     *
-     * After the call returns, the client can reuse the data array.
-     *
-     * @param format The YUV format as defined in {@link android.graphics.ImageFormat}, currently
-     *               only support YUV_420_888.
-     *
-     * @param data byte array containing the YUV data. If the format has more than one planes,
-     *             they must be concatenated.
-     */
-    public void addYuvBuffer(int format, @NonNull byte[] data) {
-        if (mInputMode != INPUT_MODE_BUFFER) {
-            throw new IllegalStateException(
-                    "addYuvBuffer is only allowed in buffer input mode");
-        }
-        if (data == null || data.length != mWidth * mHeight * 3 / 2) {
-            throw new IllegalArgumentException("invalid data");
-        }
-        addYuvBufferInternal(data);
-    }
-
-    /**
-     * Retrieves the input surface for encoding.
-     *
-     * Will only return valid value if configured to use surface input.
-     */
-    public @NonNull Surface getInputSurface() {
-        if (mInputMode != INPUT_MODE_SURFACE) {
-            throw new IllegalStateException(
-                    "getInputSurface is only allowed in surface input mode");
-        }
-        return mInputSurface;
-    }
-
-    /**
-     * Sets the timestamp (in nano seconds) of the last input frame to encode. Frames with
-     * timestamps larger than the specified value will not be encoded. However, if a frame
-     * already started encoding when this is set, all tiles within that frame will be encoded.
-     *
-     * This method only applies when surface is used.
-     */
-    public void setEndOfInputStreamTimestamp(long timestampNs) {
-        if (mInputMode != INPUT_MODE_SURFACE) {
-            throw new IllegalStateException(
-                    "setEndOfInputStreamTimestamp is only allowed in surface input mode");
-        }
-        if (mEOSTracker != null) {
-            mEOSTracker.updateInputEOSTime(timestampNs);
-        }
-    }
-
-    /**
-     * Adds one bitmap to be encoded.
-     */
-    public void addBitmap(@NonNull Bitmap bitmap) {
-        if (mInputMode != INPUT_MODE_BITMAP) {
-            throw new IllegalStateException("addBitmap is only allowed in bitmap input mode");
-        }
-
-        boolean takeFrame = mEOSTracker.updateLastInputAndEncoderTime(
-                computePresentationTime(mInputIndex) * 1000,
-                computePresentationTime(mInputIndex + mNumTiles - 1));
-
-        if (!takeFrame) return;
-
-        synchronized (this) {
-            if (mEncoderEglSurface == null) {
-                return;
-            }
-
-            mEncoderEglSurface.makeCurrent();
-
-            mRectBlt.loadTexture(mTextureId, bitmap);
-
-            copyTilesGL();
-
-            // make uncurrent since the onFrameAvailable could be called on arbituray thread.
-            // making the context current on a different thread will cause error.
-            mEncoderEglSurface.makeUnCurrent();
-        }
-    }
-
-    /**
-     * Sends input EOS to the encoder. Result will be notified asynchronously via
-     * {@link Callback#onComplete(HeifEncoder)} if encoder reaches EOS without error, or
-     * {@link Callback#onError(HeifEncoder, CodecException)} otherwise.
-     */
-    public void stopAsync() {
-        if (mInputMode == INPUT_MODE_BITMAP) {
-            // here we simply set the EOS timestamp to 0, so that the cut off will be the last
-            // bitmap ever added.
-            mEOSTracker.updateInputEOSTime(0);
-        } else if (mInputMode == INPUT_MODE_BUFFER) {
-            addYuvBufferInternal(null);
-        }
-    }
-
-    /**
-     * Generates the presentation time for input frame N, in microseconds.
-     * The timestamp advances 1 sec for every whole frame.
-     */
-    private long computePresentationTime(int frameIndex) {
-        return 132 + (long)frameIndex * 1000000 / mNumTiles;
-    }
-
-    /**
-     * Obtains one empty input buffer and copies the data into it. Before input
-     * EOS is sent, this would block until the data is copied. After input EOS
-     * is sent, this would return immediately.
-     */
-    private void addYuvBufferInternal(@Nullable byte[] data) {
-        ByteBuffer buffer = acquireEmptyBuffer();
-        if (buffer == null) {
-            return;
-        }
-        buffer.clear();
-        if (data != null) {
-            buffer.put(data);
-        }
-        buffer.flip();
-        synchronized (mFilledBuffers) {
-            mFilledBuffers.add(buffer);
-        }
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                maybeCopyOneTileYUV();
-            }
-        });
-    }
-
-    /**
-     * Routine to copy one tile if we have both input and codec buffer available.
-     *
-     * Must be called on the handler looper that also handles the MediaCodec callback.
-     */
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    void maybeCopyOneTileYUV() {
-        ByteBuffer currentBuffer;
-        while ((currentBuffer = getCurrentBuffer()) != null && !mCodecInputBuffers.isEmpty()) {
-            int index = mCodecInputBuffers.remove(0);
-
-            // 0-length input means EOS.
-            boolean inputEOS = (mInputIndex % mNumTiles == 0) && (currentBuffer.remaining() == 0);
-
-            if (!inputEOS) {
-                Image image = mEncoder.getInputImage(index);
-                int left = mGridWidth * (mInputIndex % mGridCols);
-                int top = mGridHeight * (mInputIndex / mGridCols % mGridRows);
-                mSrcRect.set(left, top, left + mGridWidth, top + mGridHeight);
-                copyOneTileYUV(currentBuffer, image, mWidth, mHeight, mSrcRect, mDstRect);
-            }
-
-            mEncoder.queueInputBuffer(index, 0,
-                    inputEOS ? 0 : mEncoder.getInputBuffer(index).capacity(),
-                    computePresentationTime(mInputIndex++),
-                    inputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
-
-            if (inputEOS || mInputIndex % mNumTiles == 0) {
-                returnEmptyBufferAndNotify(inputEOS);
-            }
-        }
-    }
-
-    /**
-     * Copies from a rect from src buffer to dst image.
-     * TOOD: This will be replaced by JNI.
-     */
-    private static void copyOneTileYUV(
-            ByteBuffer srcBuffer, Image dstImage,
-            int srcWidth, int srcHeight,
-            Rect srcRect, Rect dstRect) {
-        if (srcRect.width() != dstRect.width() || srcRect.height() != dstRect.height()) {
-            throw new IllegalArgumentException("src and dst rect size are different!");
-        }
-        if (srcWidth % 2 != 0      || srcHeight % 2 != 0      ||
-                srcRect.left % 2 != 0  || srcRect.top % 2 != 0    ||
-                srcRect.right % 2 != 0 || srcRect.bottom % 2 != 0 ||
-                dstRect.left % 2 != 0  || dstRect.top % 2 != 0    ||
-                dstRect.right % 2 != 0 || dstRect.bottom % 2 != 0) {
-            throw new IllegalArgumentException("src or dst are not aligned!");
-        }
-
-        Image.Plane[] planes = dstImage.getPlanes();
-        for (int n = 0; n < planes.length; n++) {
-            ByteBuffer dstBuffer = planes[n].getBuffer();
-            int colStride = planes[n].getPixelStride();
-            int copyWidth = Math.min(srcRect.width(), srcWidth - srcRect.left);
-            int copyHeight = Math.min(srcRect.height(), srcHeight - srcRect.top);
-            int srcPlanePos = 0, div = 1;
-            if (n > 0) {
-                div = 2;
-                srcPlanePos = srcWidth * srcHeight * (n + 3) / 4;
-            }
-            for (int i = 0; i < copyHeight / div; i++) {
-                srcBuffer.position(srcPlanePos +
-                        (i + srcRect.top / div) * srcWidth / div + srcRect.left / div);
-                dstBuffer.position((i + dstRect.top / div) * planes[n].getRowStride()
-                        + dstRect.left * colStride / div);
-
-                for (int j = 0; j < copyWidth / div; j++) {
-                    dstBuffer.put(srcBuffer.get());
-                    if (colStride > 1 && j != copyWidth / div - 1) {
-                        dstBuffer.position(dstBuffer.position() + colStride - 1);
-                    }
-                }
-            }
-        }
-    }
-
-    private ByteBuffer acquireEmptyBuffer() {
-        synchronized (mEmptyBuffers) {
-            // wait for an empty input buffer first
-            while (!mInputEOS && mEmptyBuffers.isEmpty()) {
-                try {
-                    mEmptyBuffers.wait();
-                } catch (InterruptedException e) {}
-            }
-
-            // if already EOS, return null to stop further encoding.
-            return mInputEOS ? null : mEmptyBuffers.remove(0);
-        }
-    }
-
-    /**
-     * Routine to get the current input buffer to copy from.
-     * Only called on callback handler thread.
-     */
-    private ByteBuffer getCurrentBuffer() {
-        if (!mInputEOS && mCurrentBuffer == null) {
-            synchronized (mFilledBuffers) {
-                mCurrentBuffer = mFilledBuffers.isEmpty() ?
-                        null : mFilledBuffers.remove(0);
-            }
-        }
-        return mInputEOS ? null : mCurrentBuffer;
-    }
-
-    /**
-     * Routine to put the consumed input buffer back into the empty buffer pool.
-     * Only called on callback handler thread.
-     */
-    private void returnEmptyBufferAndNotify(boolean inputEOS) {
-        synchronized (mEmptyBuffers) {
-            mInputEOS |= inputEOS;
-            mEmptyBuffers.add(mCurrentBuffer);
-            mEmptyBuffers.notifyAll();
-        }
-        mCurrentBuffer = null;
-    }
-
-    /**
-     * Routine to release all resources. Must be run on the same looper that
-     * handles the MediaCodec callbacks.
-     */
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    void stopInternal() {
-        if (DEBUG) Log.d(TAG, "stopInternal");
-
-        // set stopping, so that the tile copy would bail out
-        // if it hits failure after this point.
-        mStopping.set(true);
-
-        // after start, mEncoder is only accessed on handler, so no need to sync.
-        try {
-            if (mEncoder != null) {
-                mEncoder.stop();
-                mEncoder.release();
-            }
-        } catch (Exception e) {
-        } finally {
-            mEncoder = null;
-        }
-
-        // unblock the addBuffer() if we're tearing down before EOS is sent.
-        synchronized (mEmptyBuffers) {
-            mInputEOS = true;
-            mEmptyBuffers.notifyAll();
-        }
-
-        // Clean up surface and Egl related refs. This lock must come after encoder
-        // release. When we're closing, we insert stopInternal() at the front of queue
-        // so that the shutdown can be processed promptly, this means there might be
-        // some output available requests queued after this. As the tile copies trying
-        // to finish the current frame, there is a chance is might get stuck because
-        // those outputs were not returned. Shutting down the encoder will make break
-        // the tile copier out of that.
-        synchronized(this) {
-            try {
-                if (mRectBlt != null) {
-                    mRectBlt.release(false);
-                }
-            } catch (Exception e) {
-            } finally {
-                mRectBlt = null;
-            }
-
-            try {
-                if (mEncoderEglSurface != null) {
-                    // Note that this frees mEncoderSurface too. If mEncoderEglSurface is not
-                    // there, client is responsible to release the input surface it got from us,
-                    // we don't release mEncoderSurface here.
-                    mEncoderEglSurface.release();
-                }
-            } catch (Exception e) {
-            } finally {
-                mEncoderEglSurface = null;
-            }
-
-            try {
-                if (mInputTexture != null) {
-                    mInputTexture.release();
-                }
-            } catch (Exception e) {
-            } finally {
-                mInputTexture = null;
-            }
-        }
-    }
-
-    /**
-     * This class handles EOS for surface or bitmap inputs.
-     *
-     * When encoding from surface or bitmap, we can't call {@link MediaCodec#signalEndOfInputStream()}
-     * immediately after input is drawn, since this could drop all pending frames in the
-     * buffer queue. When there are tiles, this could leave us a partially encoded image.
-     *
-     * So here we track the EOS status by timestamps, and only signal EOS to the encoder
-     * when we collected all images we need.
-     *
-     * Since this is updated from multiple threads ({@link #setEndOfInputStreamTimestamp(long)},
-     * {@link EncoderCallback#onOutputBufferAvailable(MediaCodec, int, BufferInfo)},
-     * {@link #addBitmap(Bitmap)} and {@link #onFrameAvailable(SurfaceTexture)}), it must be fully
-     * synchronized.
-     *
-     * Note that when buffer input is used, the EOS flag is set in
-     * {@link EncoderCallback#onInputBufferAvailable(MediaCodec, int)} and this class is not used.
-     */
-    private class SurfaceEOSTracker {
-        private static final boolean DEBUG_EOS = false;
-
-        final boolean mCopyTiles;
-        long mInputEOSTimeNs = -1;
-        long mLastInputTimeNs = -1;
-        long mEncoderEOSTimeUs = -1;
-        long mLastEncoderTimeUs = -1;
-        long mLastOutputTimeUs = -1;
-        boolean mSignaled;
-
-        SurfaceEOSTracker(boolean copyTiles) {
-            mCopyTiles = copyTiles;
-        }
-
-        synchronized void updateInputEOSTime(long timestampNs) {
-            if (DEBUG_EOS) Log.d(TAG, "updateInputEOSTime: " + timestampNs);
-
-            if (mCopyTiles) {
-                if (mInputEOSTimeNs < 0) {
-                    mInputEOSTimeNs = timestampNs;
-                }
-            } else {
-                if (mEncoderEOSTimeUs < 0) {
-                    mEncoderEOSTimeUs = timestampNs / 1000;
-                }
-            }
-            updateEOSLocked();
-        }
-
-        synchronized boolean updateLastInputAndEncoderTime(long inputTimeNs, long encoderTimeUs) {
-            if (DEBUG_EOS) Log.d(TAG,
-                    "updateLastInputAndEncoderTime: " + inputTimeNs + ", " + encoderTimeUs);
-
-            boolean shouldTakeFrame = mInputEOSTimeNs < 0 || inputTimeNs <= mInputEOSTimeNs;
-            if (shouldTakeFrame) {
-                mLastEncoderTimeUs = encoderTimeUs;
-            }
-            mLastInputTimeNs = inputTimeNs;
-            updateEOSLocked();
-            return shouldTakeFrame;
-        }
-
-        synchronized void updateLastOutputTime(long outputTimeUs) {
-            if (DEBUG_EOS) Log.d(TAG, "updateLastOutputTime: " + outputTimeUs);
-
-            mLastOutputTimeUs = outputTimeUs;
-            updateEOSLocked();
-        }
-
-        private void updateEOSLocked() {
-            if (mSignaled) {
-                return;
-            }
-            if (mEncoderEOSTimeUs < 0) {
-                if (mInputEOSTimeNs >= 0 && mLastInputTimeNs >= mInputEOSTimeNs) {
-                    if (mLastEncoderTimeUs < 0) {
-                        doSignalEOSLocked();
-                        return;
-                    }
-                    // mEncoderEOSTimeUs tracks the timestamp of the last output buffer we
-                    // will wait for. When that buffer arrives, encoder will be signalled EOS.
-                    mEncoderEOSTimeUs = mLastEncoderTimeUs;
-                    if (DEBUG_EOS) Log.d(TAG,
-                            "updateEOSLocked: mEncoderEOSTimeUs " + mEncoderEOSTimeUs);
-                }
-            }
-            if (mEncoderEOSTimeUs >= 0 && mEncoderEOSTimeUs <= mLastOutputTimeUs) {
-                doSignalEOSLocked();
-            }
-        }
-
-        private void doSignalEOSLocked() {
-            if (DEBUG_EOS) Log.d(TAG, "doSignalEOSLocked");
-
-            mHandler.post(new Runnable() {
-                @Override public void run() {
-                    if (mEncoder != null) {
-                        mEncoder.signalEndOfInputStream();
-                    }
-                }
-            });
-
-            mSignaled = true;
-        }
-    }
 
     /**
      * MediaCodec callback for HEVC encoding.
      */
     @SuppressWarnings("WeakerAccess") /* synthetic access */
-    class EncoderCallback extends MediaCodec.Callback {
-        private boolean mOutputEOS;
-
+    protected class HevcEncoderCallback extends EncoderCallback {
         @Override
         public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
             if (codec != mEncoder) return;
@@ -917,7 +123,7 @@
             if (DEBUG) Log.d(TAG, "onOutputFormatChanged: " + format);
 
             if (!MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC.equals(
-                    format.getString(MediaFormat.KEY_MIME))) {
+                format.getString(MediaFormat.KEY_MIME))) {
                 format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC);
                 format.setInteger(MediaFormat.KEY_WIDTH, mWidth);
                 format.setInteger(MediaFormat.KEY_HEIGHT, mHeight);
@@ -932,85 +138,5 @@
 
             mCallback.onOutputFormatChanged(HeifEncoder.this, format);
         }
-
-        @Override
-        public void onInputBufferAvailable(MediaCodec codec, int index) {
-            if (codec != mEncoder || mInputEOS) return;
-
-            if (DEBUG) Log.d(TAG, "onInputBufferAvailable: " + index);
-            mCodecInputBuffers.add(index);
-            maybeCopyOneTileYUV();
-        }
-
-        @Override
-        public void onOutputBufferAvailable(MediaCodec codec, int index, BufferInfo info) {
-            if (codec != mEncoder || mOutputEOS) return;
-
-            if (DEBUG) {
-                Log.d(TAG, "onOutputBufferAvailable: " + index
-                        + ", time " + info.presentationTimeUs
-                        + ", size " + info.size
-                        + ", flags " + info.flags);
-            }
-
-            if ((info.size > 0) && ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0)) {
-                ByteBuffer outputBuffer = codec.getOutputBuffer(index);
-
-                // reset position as addBuffer() modifies it
-                outputBuffer.position(info.offset);
-                outputBuffer.limit(info.offset + info.size);
-
-                if (mEOSTracker != null) {
-                    mEOSTracker.updateLastOutputTime(info.presentationTimeUs);
-                }
-
-                mCallback.onDrainOutputBuffer(HeifEncoder.this, outputBuffer);
-            }
-
-            mOutputEOS |= ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0);
-
-            codec.releaseOutputBuffer(index, false);
-
-            if (mOutputEOS) {
-                stopAndNotify(null);
-            }
-        }
-
-        @Override
-        public void onError(MediaCodec codec, CodecException e) {
-            if (codec != mEncoder) return;
-
-            Log.e(TAG, "onError: " + e);
-            stopAndNotify(e);
-        }
-
-        private void stopAndNotify(@Nullable CodecException e) {
-            stopInternal();
-            if (e == null) {
-                mCallback.onComplete(HeifEncoder.this);
-            } else {
-                mCallback.onError(HeifEncoder.this, e);
-            }
-        }
     }
-
-    @Override
-    public void close() {
-        // unblock the addBuffer() if we're tearing down before EOS is sent.
-        synchronized (mEmptyBuffers) {
-            mInputEOS = true;
-            mEmptyBuffers.notifyAll();
-        }
-
-        mHandler.postAtFrontOfQueue(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    stopInternal();
-                } catch (Exception e) {
-                    // We don't want to crash when closing.
-                }
-            }
-        });
-    }
-}
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifWriter.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifWriter.java
index 4279d6f..a64aa21 100644
--- a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifWriter.java
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/HeifWriter.java
@@ -32,6 +32,7 @@
 import android.view.Surface;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
@@ -78,42 +79,17 @@
  *
  * <p>Please refer to the documentations on individual methods for the exact usage.
  */
-public final class HeifWriter implements AutoCloseable {
+@SuppressWarnings("HiddenSuperclass")
+public final class HeifWriter extends WriterBase {
     private static final String TAG = "HeifWriter";
     private static final boolean DEBUG = false;
-    private static final int MUXER_DATA_FLAG = 16;
-
-    private final @InputMode int mInputMode;
-    private final HandlerThread mHandlerThread;
-    private final Handler mHandler;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    int mNumTiles;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mRotation;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mMaxImages;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final int mPrimaryIndex;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    final ResultWaiter mResultWaiter = new ResultWaiter();
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    MediaMuxer mMuxer;
-    private HeifEncoder mHeifEncoder;
-    final AtomicBoolean mMuxerStarted = new AtomicBoolean(false);
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    int[] mTrackIndexArray;
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    int mOutputIndex;
-    private boolean mStarted;
-
-    private final List<Pair<Integer, ByteBuffer>> mExifList = new ArrayList<>();
 
     /**
      * The input mode where the client adds input buffers with YUV data.
      *
      * @see #addYuvBuffer(int, byte[])
      */
-    public static final int INPUT_MODE_BUFFER = 0;
+    public static final int INPUT_MODE_BUFFER = WriterBase.INPUT_MODE_BUFFER;
 
     /**
      * The input mode where the client renders the images to an input Surface
@@ -126,18 +102,18 @@
      *
      * @see #getInputSurface()
      */
-    public static final int INPUT_MODE_SURFACE = 1;
+    public static final int INPUT_MODE_SURFACE = WriterBase.INPUT_MODE_SURFACE;
 
     /**
      * The input mode where the client adds bitmaps.
      *
      * @see #addBitmap(Bitmap)
      */
-    public static final int INPUT_MODE_BITMAP = 2;
+    public static final int INPUT_MODE_BITMAP = WriterBase.INPUT_MODE_BITMAP;
 
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({
-            INPUT_MODE_BUFFER, INPUT_MODE_SURFACE, INPUT_MODE_BITMAP,
+        INPUT_MODE_BUFFER, INPUT_MODE_SURFACE, INPUT_MODE_BITMAP,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface InputMode {}
@@ -162,13 +138,15 @@
          * Construct a Builder with output specified by its path.
          *
          * @param path Path of the file to be written.
-         * @param width Width of the image.
-         * @param height Height of the image.
+         * @param width Width of the image in number of pixels.
+         * @param height Height of the image in number of pixels.
          * @param inputMode Input mode for this writer, must be one of {@link #INPUT_MODE_BUFFER},
          *                  {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
          */
         public Builder(@NonNull String path,
-                       int width, int height, @InputMode int inputMode) {
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
             this(path, null, width, height, inputMode);
         }
 
@@ -176,21 +154,22 @@
          * Construct a Builder with output specified by its file descriptor.
          *
          * @param fd File descriptor of the file to be written.
-         * @param width Width of the image.
-         * @param height Height of the image.
+         * @param width Width of the image in number of pixels.
+         * @param height Height of the image in number of pixels.
          * @param inputMode Input mode for this writer, must be one of {@link #INPUT_MODE_BUFFER},
          *                  {@link #INPUT_MODE_SURFACE}, or {@link #INPUT_MODE_BITMAP}.
          */
         public Builder(@NonNull FileDescriptor fd,
-                       int width, int height, @InputMode int inputMode) {
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
             this(null, fd, width, height, inputMode);
         }
 
         private Builder(String path, FileDescriptor fd,
-                        int width, int height, @InputMode int inputMode) {
-            if (width <= 0 || height <= 0) {
-                throw new IllegalArgumentException("Invalid image size: " + width + "x" + height);
-            }
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @InputMode int inputMode) {
             mPath = path;
             mFd = fd;
             mWidth = width;
@@ -201,11 +180,11 @@
         /**
          * Set the image rotation in degrees.
          *
-         * @param rotation Rotation angle (clockwise) of the image, must be 0, 90, 180 or 270.
-         *                 Default is 0.
+         * @param rotation Rotation angle in degrees (clockwise) of the image, must be 0, 90,
+         *                 180 or 270. Default is 0.
          * @return this Builder object.
          */
-        public Builder setRotation(int rotation) {
+        public @NonNull Builder setRotation(@IntRange(from = 0)  int rotation) {
             if (rotation != 0 && rotation != 90 && rotation != 180 && rotation != 270) {
                 throw new IllegalArgumentException("Invalid rotation angle: " + rotation);
             }
@@ -220,7 +199,7 @@
          *                    automatically chosen. Default is to enable.
          * @return this Builder object.
          */
-        public Builder setGridEnabled(boolean gridEnabled) {
+        public @NonNull Builder setGridEnabled(boolean gridEnabled) {
             mGridEnabled = gridEnabled;
             return this;
         }
@@ -232,7 +211,7 @@
          *                quality supported by this implementation. Default is 100.
          * @return this Builder object.
          */
-        public Builder setQuality(int quality) {
+        public @NonNull Builder setQuality(@IntRange(from = 0, to = 100) int quality) {
             if (quality < 0 || quality > 100) {
                 throw new IllegalArgumentException("Invalid quality: " + quality);
             }
@@ -251,7 +230,7 @@
          *                  Default is 1.
          * @return this Builder object.
          */
-        public Builder setMaxImages(int maxImages) {
+        public @NonNull Builder setMaxImages(@IntRange(from = 1) int maxImages) {
             if (maxImages <= 0) {
                 throw new IllegalArgumentException("Invalid maxImage: " + maxImages);
             }
@@ -266,10 +245,7 @@
          *                     range [0, maxImages - 1] inclusive. Default is 0.
          * @return this Builder object.
          */
-        public Builder setPrimaryIndex(int primaryIndex) {
-            if (primaryIndex < 0) {
-                throw new IllegalArgumentException("Invalid primaryIndex: " + primaryIndex);
-            }
+        public @NonNull Builder setPrimaryIndex(@IntRange(from = 0) int primaryIndex) {
             mPrimaryIndex = primaryIndex;
             return this;
         }
@@ -282,7 +258,7 @@
          *                writer. Default is null.
          * @return this Builder object.
          */
-        public Builder setHandler(@Nullable Handler handler) {
+        public @NonNull Builder setHandler(@Nullable Handler handler) {
             mHandler = handler;
             return this;
         }
@@ -294,428 +270,46 @@
          * @throws IOException if failed to create the writer, possibly due to failure to create
          *                     {@link android.media.MediaMuxer} or {@link android.media.MediaCodec}.
          */
-        public HeifWriter build() throws IOException {
+        public @NonNull HeifWriter build() throws IOException {
             return new HeifWriter(mPath, mFd, mWidth, mHeight, mRotation, mGridEnabled, mQuality,
-                    mMaxImages, mPrimaryIndex, mInputMode, mHandler);
+                mMaxImages, mPrimaryIndex, mInputMode, mHandler);
         }
     }
 
     @SuppressLint("WrongConstant")
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     HeifWriter(@NonNull String path,
-                       @NonNull FileDescriptor fd,
-                       int width,
-                       int height,
-                       int rotation,
-                       boolean gridEnabled,
-                       int quality,
-                       int maxImages,
-                       int primaryIndex,
-                       @InputMode int inputMode,
-                       @Nullable Handler handler) throws IOException {
-        if (primaryIndex >= maxImages) {
-            throw new IllegalArgumentException(
-                    "Invalid maxImages (" + maxImages + ") or primaryIndex (" + primaryIndex + ")");
-        }
+        @NonNull FileDescriptor fd,
+        int width,
+        int height,
+        int rotation,
+        boolean gridEnabled,
+        int quality,
+        int maxImages,
+        int primaryIndex,
+        @InputMode int inputMode,
+        @Nullable Handler handler) throws IOException {
+        super(rotation, inputMode, maxImages, primaryIndex, gridEnabled, quality,
+            handler, /* highBitDepthEnabled */ false);
 
         if (DEBUG) {
             Log.d(TAG, "width: " + width
-                    + ", height: " + height
-                    + ", rotation: " + rotation
-                    + ", gridEnabled: " + gridEnabled
-                    + ", quality: " + quality
-                    + ", maxImages: " + maxImages
-                    + ", primaryIndex: " + primaryIndex
-                    + ", inputMode: " + inputMode);
+                + ", height: " + height
+                + ", rotation: " + rotation
+                + ", gridEnabled: " + gridEnabled
+                + ", quality: " + quality
+                + ", maxImages: " + maxImages
+                + ", primaryIndex: " + primaryIndex
+                + ", inputMode: " + inputMode);
         }
 
         // set to 1 initially, and wait for output format to know for sure
         mNumTiles = 1;
 
-        mRotation = rotation;
-        mInputMode = inputMode;
-        mMaxImages = maxImages;
-        mPrimaryIndex = primaryIndex;
-
-        Looper looper = (handler != null) ? handler.getLooper() : null;
-        if (looper == null) {
-            mHandlerThread = new HandlerThread("HeifEncoderThread",
-                    Process.THREAD_PRIORITY_FOREGROUND);
-            mHandlerThread.start();
-            looper = mHandlerThread.getLooper();
-        } else {
-            mHandlerThread = null;
-        }
-        mHandler = new Handler(looper);
-
         mMuxer = (path != null) ? new MediaMuxer(path, MUXER_OUTPUT_HEIF)
-                                : new MediaMuxer(fd, MUXER_OUTPUT_HEIF);
+            : new MediaMuxer(fd, MUXER_OUTPUT_HEIF);
 
-        mHeifEncoder = new HeifEncoder(width, height, gridEnabled, quality,
-                mInputMode, mHandler, new HeifCallback());
+        mEncoder = new HeifEncoder(width, height, gridEnabled, quality,
+            mInputMode, mHandler, new WriterCallback());
     }
-
-    /**
-     * Start the heif writer. Can only be called once.
-     *
-     * @throws IllegalStateException if called more than once.
-     */
-    public void start() {
-        checkStarted(false);
-        mStarted = true;
-        mHeifEncoder.start();
-    }
-
-    /**
-     * Add one YUV buffer to the heif file.
-     *
-     * @param format The YUV format as defined in {@link android.graphics.ImageFormat}, currently
-     *               only support YUV_420_888.
-     *
-     * @param data byte array containing the YUV data. If the format has more than one planes,
-     *             they must be concatenated.
-     *
-     * @throws IllegalStateException if not started or not configured to use buffer input.
-     */
-    public void addYuvBuffer(int format, @NonNull byte[] data) {
-        checkStartedAndMode(INPUT_MODE_BUFFER);
-        synchronized (this) {
-            if (mHeifEncoder != null) {
-                mHeifEncoder.addYuvBuffer(format, data);
-            }
-        }
-    }
-
-    /**
-     * Retrieves the input surface for encoding.
-     *
-     * @return the input surface if configured to use surface input.
-     *
-     * @throws IllegalStateException if called after start or not configured to use surface input.
-     */
-    public @NonNull Surface getInputSurface() {
-        checkStarted(false);
-        checkMode(INPUT_MODE_SURFACE);
-        return mHeifEncoder.getInputSurface();
-    }
-
-    /**
-     * Set the timestamp (in nano seconds) of the last input frame to encode.
-     *
-     * This call is only valid for surface input. Client can use this to stop the heif writer
-     * earlier before the maximum number of images are written. If not called, the writer will
-     * only stop when the maximum number of images are written.
-     *
-     * @param timestampNs timestamp (in nano seconds) of the last frame that will be written to the
-     *                    heif file. Frames with timestamps larger than the specified value will not
-     *                    be written. However, if a frame already started encoding when this is set,
-     *                    all tiles within that frame will be encoded.
-     *
-     * @throws IllegalStateException if not started or not configured to use surface input.
-     */
-    public void setInputEndOfStreamTimestamp(long timestampNs) {
-        checkStartedAndMode(INPUT_MODE_SURFACE);
-        synchronized (this) {
-            if (mHeifEncoder != null) {
-                mHeifEncoder.setEndOfInputStreamTimestamp(timestampNs);
-            }
-        }
-    }
-
-    /**
-     * Add one bitmap to the heif file.
-     *
-     * @param bitmap the bitmap to be added to the file.
-     * @throws IllegalStateException if not started or not configured to use bitmap input.
-     */
-    public void addBitmap(@NonNull Bitmap bitmap) {
-        checkStartedAndMode(INPUT_MODE_BITMAP);
-        synchronized (this) {
-            if (mHeifEncoder != null) {
-                mHeifEncoder.addBitmap(bitmap);
-            }
-        }
-    }
-
-    /**
-     * Add Exif data for the specified image. The data must be a valid Exif data block,
-     * starting with "Exif\0\0" followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)
-     *
-     * @param imageIndex index of the image, must be a valid index for the max number of image
-     *                   specified by {@link Builder#setMaxImages(int)}.
-     * @param exifData byte buffer containing a Exif data block.
-     * @param offset offset of the Exif data block within exifData.
-     * @param length length of the Exif data block.
-     */
-    public void addExifData(int imageIndex, @NonNull byte[] exifData, int offset, int length) {
-        checkStarted(true);
-
-        ByteBuffer buffer = ByteBuffer.allocateDirect(length);
-        buffer.put(exifData, offset, length);
-        buffer.flip();
-        // Put it in a queue, as we might not be able to process it at this time.
-        synchronized (mExifList) {
-            mExifList.add(new Pair<Integer, ByteBuffer>(imageIndex, buffer));
-        }
-        processExifData();
-    }
-
-    @SuppressLint("WrongConstant")
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    void processExifData() {
-        if (!mMuxerStarted.get()) {
-            return;
-        }
-
-        while (true) {
-            Pair<Integer, ByteBuffer> entry;
-            synchronized (mExifList) {
-                if (mExifList.isEmpty()) {
-                    return;
-                }
-                entry = mExifList.remove(0);
-            }
-            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-            info.set(entry.second.position(), entry.second.remaining(), 0, MUXER_DATA_FLAG);
-            mMuxer.writeSampleData(mTrackIndexArray[entry.first], entry.second, info);
-        }
-    }
-
-    /**
-     * Stop the heif writer synchronously. Throws exception if the writer didn't finish writing
-     * successfully. Upon a success return:
-     *
-     * - For buffer and bitmap inputs, all images sent before stop will be written.
-     *
-     * - For surface input, images with timestamp on or before that specified in
-     *   {@link #setInputEndOfStreamTimestamp(long)} will be written. In case where
-     *   {@link #setInputEndOfStreamTimestamp(long)} was never called, stop will block
-     *   until maximum number of images are received.
-     *
-     * @param timeoutMs Maximum time (in microsec) to wait for the writer to complete, with zero
-     *                  indicating waiting indefinitely.
-     * @see #setInputEndOfStreamTimestamp(long)
-     * @throws Exception if encountered error, in which case the output file may not be valid. In
-     *                   particular, {@link TimeoutException} is thrown when timed out, and {@link
-     *                   MediaCodec.CodecException} is thrown when encountered codec error.
-     */
-    public void stop(long timeoutMs) throws Exception {
-        checkStarted(true);
-        synchronized (this) {
-            if (mHeifEncoder != null) {
-                mHeifEncoder.stopAsync();
-            }
-        }
-        mResultWaiter.waitForResult(timeoutMs);
-        processExifData();
-        closeInternal();
-    }
-
-    private void checkStarted(boolean requiredStarted) {
-        if (mStarted != requiredStarted) {
-            throw new IllegalStateException("Already started");
-        }
-    }
-
-    private void checkMode(@InputMode int requiredMode) {
-        if (mInputMode != requiredMode) {
-            throw new IllegalStateException("Not valid in input mode " + mInputMode);
-        }
-    }
-
-    private void checkStartedAndMode(@InputMode int requiredMode) {
-        checkStarted(true);
-        checkMode(requiredMode);
-    }
-
-    /**
-     * Routine to stop and release writer, must be called on the same looper
-     * that receives heif encoder callbacks.
-     */
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    void closeInternal() {
-        if (DEBUG) Log.d(TAG, "closeInternal");
-        // We don't want to crash when closing, catch all exceptions.
-        try {
-            // Muxer could throw exceptions if stop is called without samples.
-            // Don't crash in that case.
-            if (mMuxer != null) {
-                mMuxer.stop();
-                mMuxer.release();
-            }
-        } catch (Exception e) {
-        } finally {
-            mMuxer = null;
-        }
-        try {
-            if (mHeifEncoder != null) {
-                mHeifEncoder.close();
-            }
-        } catch (Exception e) {
-        } finally {
-            synchronized (this) {
-                mHeifEncoder = null;
-            }
-        }
-    }
-
-    /**
-     * Callback from the heif encoder.
-     */
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    class HeifCallback extends HeifEncoder.Callback {
-        private boolean mEncoderStopped;
-        /**
-         * Upon receiving output format from the encoder, add the requested number of
-         * image tracks to the muxer and start the muxer.
-         */
-        @Override
-        public void onOutputFormatChanged(
-                @NonNull HeifEncoder encoder, @NonNull MediaFormat format) {
-            if (mEncoderStopped) return;
-
-            if (DEBUG) {
-                Log.d(TAG, "onOutputFormatChanged: " + format);
-            }
-            if (mTrackIndexArray != null) {
-                stopAndNotify(new IllegalStateException(
-                        "Output format changed after muxer started"));
-                return;
-            }
-
-            try {
-                int gridRows = format.getInteger(MediaFormat.KEY_GRID_ROWS);
-                int gridCols = format.getInteger(MediaFormat.KEY_GRID_COLUMNS);
-                mNumTiles = gridRows * gridCols;
-            } catch (NullPointerException | ClassCastException  e) {
-                mNumTiles = 1;
-            }
-
-            // add mMaxImages image tracks of the same format
-            mTrackIndexArray = new int[mMaxImages];
-
-            // set rotation angle
-            if (mRotation > 0) {
-                Log.d(TAG, "setting rotation: " + mRotation);
-                mMuxer.setOrientationHint(mRotation);
-            }
-            for (int i = 0; i < mTrackIndexArray.length; i++) {
-                // mark primary
-                format.setInteger(MediaFormat.KEY_IS_DEFAULT, (i == mPrimaryIndex) ? 1 : 0);
-                mTrackIndexArray[i] = mMuxer.addTrack(format);
-            }
-            mMuxer.start();
-            mMuxerStarted.set(true);
-            processExifData();
-        }
-
-        /**
-         * Upon receiving an output buffer from the encoder (which is one image when
-         * grid is not used, or one tile if grid is used), add that sample to the muxer.
-         */
-        @Override
-        public void onDrainOutputBuffer(
-                @NonNull HeifEncoder encoder, @NonNull ByteBuffer byteBuffer) {
-            if (mEncoderStopped) return;
-
-            if (DEBUG) {
-                Log.d(TAG, "onDrainOutputBuffer: " + mOutputIndex);
-            }
-            if (mTrackIndexArray == null) {
-                stopAndNotify(new IllegalStateException(
-                        "Output buffer received before format info"));
-                return;
-            }
-
-            if (mOutputIndex < mMaxImages * mNumTiles) {
-                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-                info.set(byteBuffer.position(), byteBuffer.remaining(), 0, 0);
-                mMuxer.writeSampleData(
-                        mTrackIndexArray[mOutputIndex / mNumTiles], byteBuffer, info);
-            }
-
-            mOutputIndex++;
-
-            // post EOS if reached max number of images allowed.
-            if (mOutputIndex == mMaxImages * mNumTiles) {
-                stopAndNotify(null);
-            }
-        }
-
-        @Override
-        public void onComplete(@NonNull HeifEncoder encoder) {
-            stopAndNotify(null);
-        }
-
-        @Override
-        public void onError(@NonNull HeifEncoder encoder, @NonNull MediaCodec.CodecException e) {
-            stopAndNotify(e);
-        }
-
-        private void stopAndNotify(@Nullable Exception error) {
-            if (mEncoderStopped) return;
-
-            mEncoderStopped = true;
-            mResultWaiter.signalResult(error);
-        }
-    }
-
-    @SuppressWarnings("WeakerAccess") /* synthetic access */
-    static class ResultWaiter {
-        private boolean mDone;
-        private Exception mException;
-
-        synchronized void waitForResult(long timeoutMs) throws Exception {
-            if (timeoutMs < 0) {
-                throw new IllegalArgumentException("timeoutMs is negative");
-            }
-            if (timeoutMs == 0) {
-                while (!mDone) {
-                    try {
-                        wait();
-                    } catch (InterruptedException ex) {}
-                }
-            } else {
-                final long startTimeMs = System.currentTimeMillis();
-                long remainingWaitTimeMs = timeoutMs;
-                // avoid early termination by "spurious" wakeup.
-                while (!mDone && remainingWaitTimeMs > 0) {
-                    try {
-                        wait(remainingWaitTimeMs);
-                    } catch (InterruptedException ex) {}
-                    remainingWaitTimeMs -= (System.currentTimeMillis() - startTimeMs);
-                }
-            }
-            if (!mDone) {
-                mDone = true;
-                mException = new TimeoutException("timed out waiting for result");
-            }
-            if (mException != null) {
-                throw mException;
-            }
-        }
-
-        synchronized void signalResult(@Nullable Exception e) {
-            if (!mDone) {
-                mDone = true;
-                mException = e;
-                notifyAll();
-            }
-        }
-    }
-
-    @Override
-    public void close() {
-        mHandler.postAtFrontOfQueue(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    closeInternal();
-                } catch (Exception e) {
-                    // If the client called stop() properly, any errors would have been
-                    // reported there. We don't want to crash when closing.
-                }
-            }
-        });
-    }
-}
+}
\ No newline at end of file
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/Texture2dProgram.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/Texture2dProgram.java
index 668a660..4e279a6 100644
--- a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/Texture2dProgram.java
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/Texture2dProgram.java
@@ -24,6 +24,7 @@
 import android.util.Log;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -61,7 +62,8 @@
     public static final int TEXTURE_2D = 0;
     public static final int TEXTURE_EXT = 1;
 
-    /** @hide */
+    /** */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({
         TEXTURE_2D,
         TEXTURE_EXT,
diff --git a/heifwriter/heifwriter/src/main/java/androidx/heifwriter/WriterBase.java b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/WriterBase.java
new file mode 100644
index 0000000..1d369b2
--- /dev/null
+++ b/heifwriter/heifwriter/src/main/java/androidx/heifwriter/WriterBase.java
@@ -0,0 +1,573 @@
+/*
+ * Copyright 2022 Google Inc. All rights reserved.
+ *
+ * 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.heifwriter;
+
+import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_HEIF;
+
+import android.annotation.SuppressLint;
+import android.graphics.Bitmap;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Process;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class holds common utliities for {@link HeifWriter} and {@link AvifWriter}.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public class WriterBase implements AutoCloseable {
+    private static final String TAG = "WriterBase";
+    private static final boolean DEBUG = false;
+    private static final int MUXER_DATA_FLAG = 16;
+
+    /**
+     * The input mode where the client adds input buffers with YUV data.
+     *
+     * @see #addYuvBuffer(int, byte[])
+     */
+    protected static final int INPUT_MODE_BUFFER = 0;
+
+    /**
+     * The input mode where the client renders the images to an input Surface
+     * created by the writer.
+     *
+     * The input surface operates in single buffer mode. As a result, for use case
+     * where camera directly outputs to the input surface, this mode will not work
+     * because camera framework requires multiple buffers to operate in a pipeline
+     * fashion.
+     *
+     * @see #getInputSurface()
+     */
+    protected static final int INPUT_MODE_SURFACE = 1;
+
+    /**
+     * The input mode where the client adds bitmaps.
+     *
+     * @see #addBitmap(Bitmap)
+     */
+    protected static final int INPUT_MODE_BITMAP = 2;
+
+    /** */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    @IntDef({
+        INPUT_MODE_BUFFER, INPUT_MODE_SURFACE, INPUT_MODE_BITMAP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InputMode {}
+
+    protected final @InputMode int mInputMode;
+    protected final boolean mHighBitDepthEnabled;
+    protected final HandlerThread mHandlerThread;
+    protected final Handler mHandler;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected int mNumTiles;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mRotation;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mMaxImages;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected final int mPrimaryIndex;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final ResultWaiter mResultWaiter = new ResultWaiter();
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    @NonNull protected MediaMuxer mMuxer;
+    @NonNull protected EncoderBase mEncoder;
+    final AtomicBoolean mMuxerStarted = new AtomicBoolean(false);
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    int[] mTrackIndexArray;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    int mOutputIndex;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    boolean mGridEnabled;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    int mQuality;
+    private boolean mStarted;
+
+    private final List<Pair<Integer, ByteBuffer>> mExifList = new ArrayList<>();
+
+    protected WriterBase(int rotation,
+        @InputMode int inputMode,
+        int maxImages,
+        int primaryIndex,
+        boolean gridEnabled,
+        int quality,
+        @Nullable Handler handler,
+        boolean highBitDepthEnabled) throws IOException {
+        if (primaryIndex >= maxImages) {
+            throw new IllegalArgumentException(
+                "Invalid maxImages (" + maxImages + ") or primaryIndex (" + primaryIndex + ")");
+        }
+
+        mRotation = rotation;
+        mInputMode = inputMode;
+        mMaxImages = maxImages;
+        mPrimaryIndex = primaryIndex;
+        mGridEnabled = gridEnabled;
+        mQuality = quality;
+        mHighBitDepthEnabled = highBitDepthEnabled;
+
+        Looper looper = (handler != null) ? handler.getLooper() : null;
+        if (looper == null) {
+            mHandlerThread = new HandlerThread("HeifEncoderThread",
+                Process.THREAD_PRIORITY_FOREGROUND);
+            mHandlerThread.start();
+            looper = mHandlerThread.getLooper();
+        } else {
+            mHandlerThread = null;
+        }
+        mHandler = new Handler(looper);
+    }
+
+    /**
+     * Start the heif writer. Can only be called once.
+     *
+     * @throws IllegalStateException if called more than once.
+     */
+    public void start() {
+        checkStarted(false);
+        mStarted = true;
+        mEncoder.start();
+    }
+
+    /**
+     * Add one YUV buffer to the heif file.
+     *
+     * @param format The YUV format as defined in {@link android.graphics.ImageFormat}, currently
+     *               only support YUV_420_888.
+     *
+     * @param data byte array containing the YUV data. If the format has more than one planes,
+     *             they must be concatenated.
+     *
+     * @throws IllegalStateException if not started or not configured to use buffer input.
+     */
+    public void addYuvBuffer(int format, @NonNull byte[] data) {
+        checkStartedAndMode(INPUT_MODE_BUFFER);
+        synchronized (this) {
+            if (mEncoder != null) {
+                mEncoder.addYuvBuffer(format, data);
+            }
+        }
+    }
+
+    /**
+     * Retrieves the input surface for encoding.
+     *
+     * @return the input surface if configured to use surface input.
+     *
+     * @throws IllegalStateException if called after start or not configured to use surface input.
+     */
+    public @NonNull Surface getInputSurface() {
+        checkStarted(false);
+        checkMode(INPUT_MODE_SURFACE);
+        return mEncoder.getInputSurface();
+    }
+
+    /**
+     * Set the timestamp (in nano seconds) of the last input frame to encode.
+     *
+     * This call is only valid for surface input. Client can use this to stop the heif writer
+     * earlier before the maximum number of images are written. If not called, the writer will
+     * only stop when the maximum number of images are written.
+     *
+     * @param timestampNs timestamp (in nano seconds) of the last frame that will be written to the
+     *                    heif file. Frames with timestamps larger than the specified value will not
+     *                    be written. However, if a frame already started encoding when this is set,
+     *                    all tiles within that frame will be encoded.
+     *
+     * @throws IllegalStateException if not started or not configured to use surface input.
+     */
+    public void setInputEndOfStreamTimestamp(@IntRange(from = 0) long timestampNs) {
+        checkStartedAndMode(INPUT_MODE_SURFACE);
+        synchronized (this) {
+            if (mEncoder != null) {
+                mEncoder.setEndOfInputStreamTimestamp(timestampNs);
+            }
+        }
+    }
+
+    /**
+     * Add one bitmap to the heif file.
+     *
+     * @param bitmap the bitmap to be added to the file.
+     * @throws IllegalStateException if not started or not configured to use bitmap input.
+     */
+    public void addBitmap(@NonNull Bitmap bitmap) {
+        checkStartedAndMode(INPUT_MODE_BITMAP);
+        synchronized (this) {
+            if (mEncoder != null) {
+                mEncoder.addBitmap(bitmap);
+            }
+        }
+    }
+
+    /**
+     * Add Exif data for the specified image. The data must be a valid Exif data block,
+     * starting with "Exif\0\0" followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)
+     *
+     * @param imageIndex index of the image, must be a valid index for the max number of image
+     *                   specified by {@link Builder#setMaxImages(int)}.
+     * @param exifData byte buffer containing a Exif data block.
+     * @param offset offset of the Exif data block within exifData.
+     * @param length length of the Exif data block.
+     */
+    public void addExifData(int imageIndex, @NonNull byte[] exifData, int offset, int length) {
+        checkStarted(true);
+
+        ByteBuffer buffer = ByteBuffer.allocateDirect(length);
+        buffer.put(exifData, offset, length);
+        buffer.flip();
+        // Put it in a queue, as we might not be able to process it at this time.
+        synchronized (mExifList) {
+            mExifList.add(new Pair<Integer, ByteBuffer>(imageIndex, buffer));
+        }
+        processExifData();
+    }
+
+    @SuppressLint("WrongConstant")
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    void processExifData() {
+        if (!mMuxerStarted.get()) {
+            return;
+        }
+
+        while (true) {
+            Pair<Integer, ByteBuffer> entry;
+            synchronized (mExifList) {
+                if (mExifList.isEmpty()) {
+                    return;
+                }
+                entry = mExifList.remove(0);
+            }
+            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+            info.set(entry.second.position(), entry.second.remaining(), 0, MUXER_DATA_FLAG);
+            mMuxer.writeSampleData(mTrackIndexArray[entry.first], entry.second, info);
+        }
+    }
+
+    /**
+     * Stop the heif writer synchronously. Throws exception if the writer didn't finish writing
+     * successfully. Upon a success return:
+     *
+     * - For buffer and bitmap inputs, all images sent before stop will be written.
+     *
+     * - For surface input, images with timestamp on or before that specified in
+     *   {@link #setInputEndOfStreamTimestamp(long)} will be written. In case where
+     *   {@link #setInputEndOfStreamTimestamp(long)} was never called, stop will block
+     *   until maximum number of images are received.
+     *
+     * @param timeoutMs Maximum time (in microsec) to wait for the writer to complete, with zero
+     *                  indicating waiting indefinitely.
+     * @see #setInputEndOfStreamTimestamp(long)
+     * @throws Exception if encountered error, in which case the output file may not be valid. In
+     *                   particular, {@link TimeoutException} is thrown when timed out, and {@link
+     *                   MediaCodec.CodecException} is thrown when encountered codec error.
+     */
+    public void stop(@IntRange(from = 0) long timeoutMs) throws Exception {
+        checkStarted(true);
+        synchronized (this) {
+            if (mEncoder != null) {
+                mEncoder.stopAsync();
+            }
+        }
+        mResultWaiter.waitForResult(timeoutMs);
+        processExifData();
+        closeInternal();
+    }
+
+    private void checkStarted(boolean requiredStarted) {
+        if (mStarted != requiredStarted) {
+            throw new IllegalStateException("Already started");
+        }
+    }
+
+    private void checkMode(@InputMode int requiredMode) {
+        if (mInputMode != requiredMode) {
+            throw new IllegalStateException("Not valid in input mode " + mInputMode);
+        }
+    }
+
+    private void checkStartedAndMode(@InputMode int requiredMode) {
+        checkStarted(true);
+        checkMode(requiredMode);
+    }
+
+    /**
+     * Routine to stop and release writer, must be called on the same looper
+     * that receives heif encoder callbacks.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    void closeInternal() {
+        if (DEBUG) Log.d(TAG, "closeInternal");
+        // We don't want to crash when closing, catch all exceptions.
+        try {
+            // Muxer could throw exceptions if stop is called without samples.
+            // Don't crash in that case.
+            if (mMuxer != null) {
+                mMuxer.stop();
+                mMuxer.release();
+            }
+        } catch (Exception e) {
+        } finally {
+            mMuxer = null;
+        }
+        try {
+            if (mEncoder != null) {
+                mEncoder.close();
+            }
+        } catch (Exception e) {
+        } finally {
+            synchronized (this) {
+                mEncoder = null;
+            }
+        }
+    }
+
+    /**
+     * Callback from the encoder.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    protected class WriterCallback extends EncoderBase.Callback {
+        private boolean mEncoderStopped;
+        /**
+         * Upon receiving output format from the encoder, add the requested number of
+         * image tracks to the muxer and start the muxer.
+         */
+        @Override
+        public void onOutputFormatChanged(
+            @NonNull EncoderBase encoder, @NonNull MediaFormat format) {
+            if (mEncoderStopped) return;
+
+            if (DEBUG) {
+                Log.d(TAG, "onOutputFormatChanged: " + format);
+            }
+            if (mTrackIndexArray != null) {
+                stopAndNotify(new IllegalStateException(
+                    "Output format changed after muxer started"));
+                return;
+            }
+
+            try {
+                int gridRows = format.getInteger(MediaFormat.KEY_GRID_ROWS);
+                int gridCols = format.getInteger(MediaFormat.KEY_GRID_COLUMNS);
+                mNumTiles = gridRows * gridCols;
+            } catch (NullPointerException | ClassCastException  e) {
+                mNumTiles = 1;
+            }
+
+            // add mMaxImages image tracks of the same format
+            mTrackIndexArray = new int[mMaxImages];
+
+            // set rotation angle
+            if (mRotation > 0) {
+                Log.d(TAG, "setting rotation: " + mRotation);
+                mMuxer.setOrientationHint(mRotation);
+            }
+            for (int i = 0; i < mTrackIndexArray.length; i++) {
+                // mark primary
+                format.setInteger(MediaFormat.KEY_IS_DEFAULT, (i == mPrimaryIndex) ? 1 : 0);
+                mTrackIndexArray[i] = mMuxer.addTrack(format);
+            }
+            mMuxer.start();
+            mMuxerStarted.set(true);
+            processExifData();
+        }
+
+        /**
+         * Upon receiving an output buffer from the encoder (which is one image when
+         * grid is not used, or one tile if grid is used), add that sample to the muxer.
+         */
+        @Override
+        public void onDrainOutputBuffer(
+            @NonNull EncoderBase encoder, @NonNull ByteBuffer byteBuffer) {
+            if (mEncoderStopped) return;
+
+            if (DEBUG) {
+                Log.d(TAG, "onDrainOutputBuffer: " + mOutputIndex);
+            }
+            if (mTrackIndexArray == null) {
+                stopAndNotify(new IllegalStateException(
+                    "Output buffer received before format info"));
+                return;
+            }
+
+            if (mOutputIndex < mMaxImages * mNumTiles) {
+                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+                info.set(byteBuffer.position(), byteBuffer.remaining(), 0, 0);
+                mMuxer.writeSampleData(
+                    mTrackIndexArray[mOutputIndex / mNumTiles], byteBuffer, info);
+            }
+
+            mOutputIndex++;
+
+            // post EOS if reached max number of images allowed.
+            if (mOutputIndex == mMaxImages * mNumTiles) {
+                stopAndNotify(null);
+            }
+        }
+
+        @Override
+        public void onComplete(@NonNull EncoderBase encoder) {
+            stopAndNotify(null);
+        }
+
+        @Override
+        public void onError(@NonNull EncoderBase encoder, @NonNull MediaCodec.CodecException e) {
+            stopAndNotify(e);
+        }
+
+        private void stopAndNotify(@Nullable Exception error) {
+            if (mEncoderStopped) return;
+
+            mEncoderStopped = true;
+            mResultWaiter.signalResult(error);
+        }
+    }
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    static class ResultWaiter {
+        private boolean mDone;
+        private Exception mException;
+
+        synchronized void waitForResult(long timeoutMs) throws Exception {
+            if (timeoutMs < 0) {
+                throw new IllegalArgumentException("timeoutMs is negative");
+            }
+            if (timeoutMs == 0) {
+                while (!mDone) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ex) {}
+                }
+            } else {
+                final long startTimeMs = System.currentTimeMillis();
+                long remainingWaitTimeMs = timeoutMs;
+                // avoid early termination by "spurious" wakeup.
+                while (!mDone && remainingWaitTimeMs > 0) {
+                    try {
+                        wait(remainingWaitTimeMs);
+                    } catch (InterruptedException ex) {}
+                    remainingWaitTimeMs -= (System.currentTimeMillis() - startTimeMs);
+                }
+            }
+            if (!mDone) {
+                mDone = true;
+                mException = new TimeoutException("timed out waiting for result");
+            }
+            if (mException != null) {
+                throw mException;
+            }
+        }
+
+        synchronized void signalResult(@Nullable Exception e) {
+            if (!mDone) {
+                mDone = true;
+                mException = e;
+                notifyAll();
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        mHandler.postAtFrontOfQueue(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    closeInternal();
+                } catch (Exception e) {
+                    // If the client called stop() properly, any errors would have been
+                    // reported there. We don't want to crash when closing.
+                }
+            }
+        });
+    }
+
+    /*
+     * Gets rotation.
+     */
+    public int getRotation() {
+        return mRotation;
+    }
+
+    /*
+     * Returns true if grid is enabled.
+     */
+    public boolean isGridEnabled() {
+        return mGridEnabled;
+    }
+
+    /*
+     * Gets configured quality.
+     */
+    public int getQuality() {
+        return mQuality;
+    }
+
+    /*
+     * Gets number of maximum images.
+     */
+    public int getMaxImages() {
+        return mMaxImages;
+    }
+
+    /*
+     * Gets index of the primary image.
+     */
+    public int getPrimaryIndex() {
+        return mPrimaryIndex;
+    }
+
+    /*
+     * Gets handler.
+     *
+     * The result is the same as clients' input from setHandler() method.
+     * If not null, client will receive all callbacks on the handler's looper.
+     * Otherwise, client will receive callbacks on the current looper.
+     */
+    public @Nullable Handler getHandler() {
+        return mHandler;
+    }
+
+    /*
+     * Returns true if high bit-depth is enabled.
+     */
+    public boolean isHighBitDepthEnabled() {
+        return mHighBitDepthEnabled;
+    }
+}
\ No newline at end of file
diff --git a/leanback/leanback/api/api_lint.ignore b/leanback/leanback/api/api_lint.ignore
index a72d2ae..a568a48 100644
--- a/leanback/leanback/api/api_lint.ignore
+++ b/leanback/leanback/api/api_lint.ignore
@@ -147,8 +147,6 @@
     Invalid nullability on parameter `view` in method `onViewCreated`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.leanback.widget.GuidedActionEditText#onTouchEvent(android.view.MotionEvent) parameter #0:
     Invalid nullability on parameter `event` in method `onTouchEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.leanback.widget.ShadowOverlayContainer#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 
 
 KotlinOperator: androidx.leanback.widget.ObjectAdapter#get(int):
@@ -1135,6 +1133,8 @@
     Missing nullability on field `TOP_FRACTION` in class `class androidx.leanback.graphics.CompositeDrawable.ChildDrawable`
 MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#PROPERTY_VERTICAL_OFFSET:
     Missing nullability on field `PROPERTY_VERTICAL_OFFSET` in class `class androidx.leanback.graphics.FitWidthBitmapDrawable`
+MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#getBitmap():
     Missing nullability on method `getBitmap` return
 MissingNullability: androidx.leanback.graphics.FitWidthBitmapDrawable#getConstantState():
@@ -2189,6 +2189,8 @@
     Missing nullability on parameter `context` in method `ShadowOverlayContainer`
 MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#ShadowOverlayContainer(android.content.Context, android.util.AttributeSet, int) parameter #1:
     Missing nullability on parameter `attrs` in method `ShadowOverlayContainer`
+MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#getWrappedView():
     Missing nullability on method `getWrappedView` return
 MissingNullability: androidx.leanback.widget.ShadowOverlayContainer#prepareParentForShadow(android.view.ViewGroup) parameter #0:
diff --git a/libraryversions.toml b/libraryversions.toml
index a8188fa..9d7ddfe 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -1,5 +1,5 @@
 [versions]
-ACTIVITY = "1.8.0-alpha05"
+ACTIVITY = "1.8.0-alpha06"
 ANNOTATION = "1.7.0-alpha03"
 ANNOTATION_EXPERIMENTAL = "1.4.0-alpha01"
 APPACTIONS_BUILTINTYPES = "1.0.0-alpha01"
@@ -9,12 +9,12 @@
 ARCH_CORE = "2.3.0-alpha01"
 ASYNCLAYOUTINFLATER = "1.1.0-alpha02"
 AUTOFILL = "1.3.0-alpha02"
-BENCHMARK = "1.2.0-alpha15"
+BENCHMARK = "1.2.0-alpha16"
 BIOMETRIC = "1.2.0-alpha06"
 BLUETOOTH = "1.0.0-alpha01"
 BROWSER = "1.6.0-beta01"
 BUILDSRC_TESTS = "1.0.0-alpha01"
-CAMERA = "1.3.0-alpha08"
+CAMERA = "1.3.0-beta01"
 CAMERA_PIPE = "1.0.0-alpha01"
 CARDVIEW = "1.1.0-alpha01"
 CAR_APP = "1.4.0-alpha01"
@@ -29,9 +29,9 @@
 CONSTRAINTLAYOUT_CORE = "1.1.0-alpha11"
 CONTENTPAGER = "1.1.0-alpha01"
 COORDINATORLAYOUT = "1.3.0-alpha01"
-CORE = "1.11.0-beta02"
-CORE_ANIMATION = "1.0.0-beta02"
-CORE_ANIMATION_TESTING = "1.0.0-beta01"
+CORE = "1.12.0-alpha05"
+CORE_ANIMATION = "1.0.0-rc01"
+CORE_ANIMATION_TESTING = "1.0.0-rc01"
 CORE_APPDIGEST = "1.0.0-alpha01"
 CORE_GOOGLE_SHORTCUTS = "1.2.0-alpha01"
 CORE_HAPTICS = "1.0.0-alpha01"
@@ -41,8 +41,9 @@
 CORE_REMOTEVIEWS = "1.0.0-beta05"
 CORE_ROLE = "1.2.0-alpha01"
 CORE_SPLASHSCREEN = "1.1.0-alpha01"
+CORE_TELECOM = "1.0.0-alpha01"
 CORE_UWB = "1.0.0-alpha06"
-CREDENTIALS = "1.0.0-alpha09"
+CREDENTIALS = "1.2.0-alpha05"
 CURSORADAPTER = "1.1.0-alpha01"
 CUSTOMVIEW = "1.2.0-alpha03"
 CUSTOMVIEW_POOLINGCONTAINER = "1.1.0-alpha01"
@@ -56,18 +57,19 @@
 EMOJI2 = "1.4.0-beta05"
 ENTERPRISE = "1.1.0-rc01"
 EXIFINTERFACE = "1.4.0-alpha01"
-FRAGMENT = "1.7.0-alpha01"
+FRAGMENT = "1.7.0-alpha02"
 FUTURES = "1.2.0-alpha01"
 GLANCE = "1.0.0-beta02"
 GLANCE_PREVIEW = "1.0.0-alpha06"
 GLANCE_TEMPLATE = "1.0.0-alpha06"
 GLANCE_WEAR_TILES = "1.0.0-alpha06"
 GRAPHICS_CORE = "1.0.0-alpha04"
+GRAPHICS_PATH = "1.0.0-alpha02"
 GRAPHICS_FILTERS = "1.0.0-alpha01"
 GRAPHICS_SHAPES = "1.0.0-alpha03"
 GRIDLAYOUT = "1.1.0-beta02"
-HEALTH_CONNECT = "1.0.0-alpha11"
-HEALTH_SERVICES_CLIENT = "1.0.0-rc01"
+HEALTH_CONNECT = "1.1.0-alpha02"
+HEALTH_SERVICES_CLIENT = "1.1.0-alpha01"
 HEIFWRITER = "1.1.0-alpha02"
 HILT = "1.1.0-alpha03"
 HILT_NAVIGATION_COMPOSE = "1.1.0-alpha02"
@@ -87,17 +89,17 @@
 LOADER = "1.2.0-alpha01"
 MEDIA = "1.7.0-alpha02"
 MEDIA2 = "1.3.0-alpha01"
-MEDIAROUTER = "1.5.0-alpha02"
+MEDIAROUTER = "1.6.0-alpha04"
 METRICS = "1.0.0-alpha05"
-NAVIGATION = "2.7.0-beta01"
-PAGING = "3.2.0-beta01"
+NAVIGATION = "2.7.0-beta02"
+PAGING = "3.2.0-rc01"
 PALETTE = "1.1.0-alpha01"
 PERCENTLAYOUT = "1.1.0-alpha01"
 PREFERENCE = "1.3.0-alpha01"
 PRINT = "1.1.0-beta01"
-PRIVACYSANDBOX_ADS = "1.0.0-beta05"
+PRIVACYSANDBOX_ADS = "1.1.0-alpha01"
 PRIVACYSANDBOX_PLUGINS = "1.0.0-alpha02"
-PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha05"
+PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha06"
 PRIVACYSANDBOX_TOOLS = "1.0.0-alpha05"
 PRIVACYSANDBOX_UI = "1.0.0-alpha04"
 PROFILEINSTALLER = "1.4.0-alpha01"
@@ -129,14 +131,14 @@
 TESTSCREENSHOT = "1.0.0-alpha01"
 TEST_UIAUTOMATOR = "2.3.0-alpha04"
 TEXT = "1.0.0-alpha01"
-TRACING = "1.3.0-alpha01"
-TRACING_PERFETTO = "1.0.0-alpha16"
+TRACING = "1.3.0-alpha02"
+TRACING_PERFETTO = "1.0.0-alpha17"
 TRANSITION = "1.5.0-alpha01"
-TV = "1.0.0-alpha07"
+TV = "1.0.0-alpha08"
 TVPROVIDER = "1.1.0-alpha02"
-VECTORDRAWABLE = "1.2.0-beta02"
-VECTORDRAWABLE_ANIMATED = "1.2.0-beta01"
-VECTORDRAWABLE_SEEKABLE = "1.0.0-beta02"
+VECTORDRAWABLE = "1.2.0-rc01"
+VECTORDRAWABLE_ANIMATED = "1.2.0-rc01"
+VECTORDRAWABLE_SEEKABLE = "1.0.0-rc01"
 VERSIONED_PARCELABLE = "1.2.0-alpha01"
 VIEWPAGER = "1.1.0-alpha02"
 VIEWPAGER2 = "1.1.0-beta03"
@@ -147,9 +149,9 @@
 WEAR_INPUT_TESTING = "1.2.0-alpha03"
 WEAR_ONGOING = "1.1.0-alpha01"
 WEAR_PHONE_INTERACTIONS = "1.1.0-alpha04"
-WEAR_PROTOLAYOUT = "1.0.0-alpha11"
+WEAR_PROTOLAYOUT = "1.0.0-beta01"
 WEAR_REMOTE_INTERACTIONS = "1.1.0-alpha01"
-WEAR_TILES = "1.2.0-alpha07"
+WEAR_TILES = "1.2.0-beta01"
 WEAR_WATCHFACE = "1.2.0-alpha09"
 WEBKIT = "1.8.0-alpha01"
 WINDOW = "1.2.0-alpha03"
diff --git a/lifecycle/lifecycle-common-java8/api/2.6.0-beta02.txt b/lifecycle/lifecycle-common-java8/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-common-java8/api/2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/lifecycle/lifecycle-common-java8/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-common-java8/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-common-java8/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/lifecycle/lifecycle-common-java8/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-common-java8/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-common-java8/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/lifecycle/lifecycle-common/api/2.6.0-beta02.txt b/lifecycle/lifecycle-common/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..f3dc4c9
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/2.6.0-beta02.txt
@@ -0,0 +1,99 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
+    method public default void onCreate(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onDestroy(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onPause(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onResume(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStart(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStop(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  public abstract class Lifecycle {
+    ctor public Lifecycle();
+    method @MainThread public abstract void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @MainThread public abstract androidx.lifecycle.Lifecycle.State getCurrentState();
+    method @MainThread public abstract void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    property @MainThread public abstract androidx.lifecycle.Lifecycle.State currentState;
+  }
+
+  public enum Lifecycle.Event {
+    method public static final androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public final androidx.lifecycle.Lifecycle.State getTargetState();
+    method public static final androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.Event valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.Event[] values();
+    property public final androidx.lifecycle.Lifecycle.State targetState;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_ANY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_CREATE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_DESTROY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_PAUSE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_RESUME;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_START;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_STOP;
+    field public static final androidx.lifecycle.Lifecycle.Event.Companion Companion;
+  }
+
+  public static final class Lifecycle.Event.Companion {
+    method public androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+  }
+
+  public enum Lifecycle.State {
+    method public final boolean isAtLeast(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.State valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.State[] values();
+    enum_constant public static final androidx.lifecycle.Lifecycle.State CREATED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State DESTROYED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State INITIALIZED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State RESUMED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State STARTED;
+  }
+
+  public abstract class LifecycleCoroutineScope implements kotlinx.coroutines.CoroutineScope {
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenCreated(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenResumed(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenStarted(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public fun interface LifecycleEventObserver extends androidx.lifecycle.LifecycleObserver {
+    method public void onStateChanged(androidx.lifecycle.LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event);
+  }
+
+  public final class LifecycleKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getCoroutineScope(androidx.lifecycle.Lifecycle);
+  }
+
+  public interface LifecycleObserver {
+  }
+
+  public interface LifecycleOwner {
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public abstract androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public final class LifecycleOwnerKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getLifecycleScope(androidx.lifecycle.LifecycleOwner);
+  }
+
+  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface OnLifecycleEvent {
+    method @Deprecated public abstract androidx.lifecycle.Lifecycle.Event! value();
+  }
+
+  public final class PausingDispatcherKt {
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-common/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-common/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..f3dc4c9
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,99 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
+    method public default void onCreate(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onDestroy(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onPause(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onResume(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStart(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStop(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  public abstract class Lifecycle {
+    ctor public Lifecycle();
+    method @MainThread public abstract void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @MainThread public abstract androidx.lifecycle.Lifecycle.State getCurrentState();
+    method @MainThread public abstract void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    property @MainThread public abstract androidx.lifecycle.Lifecycle.State currentState;
+  }
+
+  public enum Lifecycle.Event {
+    method public static final androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public final androidx.lifecycle.Lifecycle.State getTargetState();
+    method public static final androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.Event valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.Event[] values();
+    property public final androidx.lifecycle.Lifecycle.State targetState;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_ANY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_CREATE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_DESTROY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_PAUSE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_RESUME;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_START;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_STOP;
+    field public static final androidx.lifecycle.Lifecycle.Event.Companion Companion;
+  }
+
+  public static final class Lifecycle.Event.Companion {
+    method public androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+  }
+
+  public enum Lifecycle.State {
+    method public final boolean isAtLeast(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.State valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.State[] values();
+    enum_constant public static final androidx.lifecycle.Lifecycle.State CREATED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State DESTROYED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State INITIALIZED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State RESUMED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State STARTED;
+  }
+
+  public abstract class LifecycleCoroutineScope implements kotlinx.coroutines.CoroutineScope {
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenCreated(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenResumed(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenStarted(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public fun interface LifecycleEventObserver extends androidx.lifecycle.LifecycleObserver {
+    method public void onStateChanged(androidx.lifecycle.LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event);
+  }
+
+  public final class LifecycleKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getCoroutineScope(androidx.lifecycle.Lifecycle);
+  }
+
+  public interface LifecycleObserver {
+  }
+
+  public interface LifecycleOwner {
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public abstract androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public final class LifecycleOwnerKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getLifecycleScope(androidx.lifecycle.LifecycleOwner);
+  }
+
+  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface OnLifecycleEvent {
+    method @Deprecated public abstract androidx.lifecycle.Lifecycle.Event! value();
+  }
+
+  public final class PausingDispatcherKt {
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-common/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-common/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..05b2709
--- /dev/null
+++ b/lifecycle/lifecycle-common/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,116 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
+    method public default void onCreate(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onDestroy(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onPause(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onResume(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStart(androidx.lifecycle.LifecycleOwner owner);
+    method public default void onStop(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface GeneratedAdapter {
+    method public void callMethods(androidx.lifecycle.LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event, boolean onAny, androidx.lifecycle.MethodCallsLogger? logger);
+  }
+
+  @Deprecated @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface GenericLifecycleObserver extends androidx.lifecycle.LifecycleEventObserver {
+  }
+
+  public abstract class Lifecycle {
+    ctor public Lifecycle();
+    method @MainThread public abstract void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @MainThread public abstract androidx.lifecycle.Lifecycle.State getCurrentState();
+    method @MainThread public abstract void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    property @MainThread public abstract androidx.lifecycle.Lifecycle.State currentState;
+  }
+
+  public enum Lifecycle.Event {
+    method public static final androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public final androidx.lifecycle.Lifecycle.State getTargetState();
+    method public static final androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public static final androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.Event valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.Event[] values();
+    property public final androidx.lifecycle.Lifecycle.State targetState;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_ANY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_CREATE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_DESTROY;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_PAUSE;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_RESUME;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_START;
+    enum_constant public static final androidx.lifecycle.Lifecycle.Event ON_STOP;
+    field public static final androidx.lifecycle.Lifecycle.Event.Companion Companion;
+  }
+
+  public static final class Lifecycle.Event.Companion {
+    method public androidx.lifecycle.Lifecycle.Event? downFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? downTo(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upFrom(androidx.lifecycle.Lifecycle.State state);
+    method public androidx.lifecycle.Lifecycle.Event? upTo(androidx.lifecycle.Lifecycle.State state);
+  }
+
+  public enum Lifecycle.State {
+    method public final boolean isAtLeast(androidx.lifecycle.Lifecycle.State state);
+    method public static androidx.lifecycle.Lifecycle.State valueOf(String name) throws java.lang.IllegalArgumentException;
+    method public static androidx.lifecycle.Lifecycle.State[] values();
+    enum_constant public static final androidx.lifecycle.Lifecycle.State CREATED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State DESTROYED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State INITIALIZED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State RESUMED;
+    enum_constant public static final androidx.lifecycle.Lifecycle.State STARTED;
+  }
+
+  public abstract class LifecycleCoroutineScope implements kotlinx.coroutines.CoroutineScope {
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenCreated(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenResumed(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @Deprecated public final kotlinx.coroutines.Job launchWhenStarted(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public fun interface LifecycleEventObserver extends androidx.lifecycle.LifecycleObserver {
+    method public void onStateChanged(androidx.lifecycle.LifecycleOwner source, androidx.lifecycle.Lifecycle.Event event);
+  }
+
+  public final class LifecycleKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getCoroutineScope(androidx.lifecycle.Lifecycle);
+  }
+
+  public interface LifecycleObserver {
+  }
+
+  public interface LifecycleOwner {
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public abstract androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public final class LifecycleOwnerKt {
+    method public static androidx.lifecycle.LifecycleCoroutineScope getLifecycleScope(androidx.lifecycle.LifecycleOwner);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public final class Lifecycling {
+    method public static String getAdapterName(String className);
+    method public static androidx.lifecycle.LifecycleEventObserver lifecycleEventObserver(Object object);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class MethodCallsLogger {
+    ctor public MethodCallsLogger();
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public boolean approveCall(String name, int type);
+  }
+
+  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface OnLifecycleEvent {
+    method @Deprecated public abstract androidx.lifecycle.Lifecycle.Event! value();
+  }
+
+  public final class PausingDispatcherKt {
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+    method @Deprecated public static suspend <T> Object? whenStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State minState, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super T>,?> block, kotlin.coroutines.Continuation<? super T>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/2.6.0-beta02.txt b/lifecycle/lifecycle-extensions/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..88798d8
--- /dev/null
+++ b/lifecycle/lifecycle-extensions/api/2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  @Deprecated public class ViewModelProviders {
+    ctor @Deprecated public ViewModelProviders();
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
+  }
+
+  @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
+    ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
+  }
+
+  @Deprecated public class ViewModelStores {
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..88798d8
--- /dev/null
+++ b/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  @Deprecated public class ViewModelProviders {
+    ctor @Deprecated public ViewModelProviders();
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
+  }
+
+  @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
+    ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
+  }
+
+  @Deprecated public class ViewModelStores {
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-extensions/api/res-2.6.0-beta02.txt
similarity index 100%
rename from webkit/webkit/api/res-1.6.0-beta02.txt
rename to lifecycle/lifecycle-extensions/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-extensions/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-extensions/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..88798d8
--- /dev/null
+++ b/lifecycle/lifecycle-extensions/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  @Deprecated public class ViewModelProviders {
+    ctor @Deprecated public ViewModelProviders();
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
+  }
+
+  @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
+    ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
+  }
+
+  @Deprecated public class ViewModelStores {
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
+    method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core-ktx/api/2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core-ktx/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..daac648
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core-ktx/api/2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataKt {
+    method @Deprecated @MainThread public static inline <T> androidx.lifecycle.Observer<T> observe(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner owner, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onChanged);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core-ktx/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core-ktx/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..daac648
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core-ktx/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataKt {
+    method @Deprecated @MainThread public static inline <T> androidx.lifecycle.Observer<T> observe(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner owner, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onChanged);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core-ktx/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-livedata-core-ktx/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..daac648
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core-ktx/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataKt {
+    method @Deprecated @MainThread public static inline <T> androidx.lifecycle.Observer<T> observe(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner owner, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> onChanged);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core/api/2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..f528b4e
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class LiveData<T> {
+    ctor public LiveData(T!);
+    ctor public LiveData();
+    method public T? getValue();
+    method public boolean hasActiveObservers();
+    method public boolean hasObservers();
+    method public boolean isInitialized();
+    method @MainThread public void observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void observeForever(androidx.lifecycle.Observer<? super T>);
+    method protected void onActive();
+    method protected void onInactive();
+    method protected void postValue(T!);
+    method @MainThread public void removeObserver(androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void removeObservers(androidx.lifecycle.LifecycleOwner);
+    method @MainThread protected void setValue(T!);
+  }
+
+  public class MutableLiveData<T> extends androidx.lifecycle.LiveData<T> {
+    ctor public MutableLiveData(T!);
+    ctor public MutableLiveData();
+    method public void postValue(T!);
+    method public void setValue(T!);
+  }
+
+  public fun interface Observer<T> {
+    method public void onChanged(T? value);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..f528b4e
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class LiveData<T> {
+    ctor public LiveData(T!);
+    ctor public LiveData();
+    method public T? getValue();
+    method public boolean hasActiveObservers();
+    method public boolean hasObservers();
+    method public boolean isInitialized();
+    method @MainThread public void observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void observeForever(androidx.lifecycle.Observer<? super T>);
+    method protected void onActive();
+    method protected void onInactive();
+    method protected void postValue(T!);
+    method @MainThread public void removeObserver(androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void removeObservers(androidx.lifecycle.LifecycleOwner);
+    method @MainThread protected void setValue(T!);
+  }
+
+  public class MutableLiveData<T> extends androidx.lifecycle.LiveData<T> {
+    ctor public MutableLiveData(T!);
+    ctor public MutableLiveData();
+    method public void postValue(T!);
+    method public void setValue(T!);
+  }
+
+  public fun interface Observer<T> {
+    method public void onChanged(T? value);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-livedata-core/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-livedata-core/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-core/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..f528b4e
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-core/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class LiveData<T> {
+    ctor public LiveData(T!);
+    ctor public LiveData();
+    method public T? getValue();
+    method public boolean hasActiveObservers();
+    method public boolean hasObservers();
+    method public boolean isInitialized();
+    method @MainThread public void observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void observeForever(androidx.lifecycle.Observer<? super T>);
+    method protected void onActive();
+    method protected void onInactive();
+    method protected void postValue(T!);
+    method @MainThread public void removeObserver(androidx.lifecycle.Observer<? super T>);
+    method @MainThread public void removeObservers(androidx.lifecycle.LifecycleOwner);
+    method @MainThread protected void setValue(T!);
+  }
+
+  public class MutableLiveData<T> extends androidx.lifecycle.LiveData<T> {
+    ctor public MutableLiveData(T!);
+    ctor public MutableLiveData();
+    method public void postValue(T!);
+    method public void setValue(T!);
+  }
+
+  public fun interface Observer<T> {
+    method public void onChanged(T? value);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-ktx/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..bae0928
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/2.6.0-beta02.txt
@@ -0,0 +1,25 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class CoroutineLiveDataKt {
+    method public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class FlowLiveDataConversions {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout);
+  }
+
+  public interface LiveDataScope<T> {
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public T? getLatestValue();
+    property public abstract T? latestValue;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..bae0928
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,25 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class CoroutineLiveDataKt {
+    method public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class FlowLiveDataConversions {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout);
+  }
+
+  public interface LiveDataScope<T> {
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public T? getLatestValue();
+    property public abstract T? latestValue;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-livedata-ktx/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-livedata-ktx/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..bae0928
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,25 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class CoroutineLiveDataKt {
+    method public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+  }
+
+  public final class FlowLiveDataConversions {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, optional long timeoutInMs);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
+    method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+    method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, optional kotlin.coroutines.CoroutineContext context, java.time.Duration timeout);
+  }
+
+  public interface LiveDataScope<T> {
+    method public suspend Object? emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle>);
+    method public T? getLatestValue();
+    property public abstract T? latestValue;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata/api/2.6.0-beta02.txt b/lifecycle/lifecycle-livedata/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..9b1bf6c
--- /dev/null
+++ b/lifecycle/lifecycle-livedata/api/2.6.0-beta02.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class MediatorLiveData<T> extends androidx.lifecycle.MutableLiveData<T> {
+    ctor public MediatorLiveData();
+    ctor public MediatorLiveData(T!);
+    method @MainThread public <S> void addSource(androidx.lifecycle.LiveData<S!>, androidx.lifecycle.Observer<? super S>);
+    method @MainThread public <S> void removeSource(androidx.lifecycle.LiveData<S!>);
+  }
+
+  public final class Transformations {
+    method @CheckResult @MainThread public static <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,Y> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,Y> mapFunction);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,androidx.lifecycle.LiveData<Y>> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,androidx.lifecycle.LiveData<Y>> switchMapFunction);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..9b1bf6c
--- /dev/null
+++ b/lifecycle/lifecycle-livedata/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,20 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class MediatorLiveData<T> extends androidx.lifecycle.MutableLiveData<T> {
+    ctor public MediatorLiveData();
+    ctor public MediatorLiveData(T!);
+    method @MainThread public <S> void addSource(androidx.lifecycle.LiveData<S!>, androidx.lifecycle.Observer<? super S>);
+    method @MainThread public <S> void removeSource(androidx.lifecycle.LiveData<S!>);
+  }
+
+  public final class Transformations {
+    method @CheckResult @MainThread public static <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,Y> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,Y> mapFunction);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,androidx.lifecycle.LiveData<Y>> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,androidx.lifecycle.LiveData<Y>> switchMapFunction);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-livedata/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-livedata/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-livedata/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-livedata/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..bb61b39
--- /dev/null
+++ b/lifecycle/lifecycle-livedata/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,29 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public abstract class ComputableLiveData<T> {
+    ctor public ComputableLiveData(optional java.util.concurrent.Executor executor);
+    ctor public ComputableLiveData();
+    method @WorkerThread protected abstract T! compute();
+    method public androidx.lifecycle.LiveData<T> getLiveData();
+    method public void invalidate();
+    property public androidx.lifecycle.LiveData<T> liveData;
+  }
+
+  public class MediatorLiveData<T> extends androidx.lifecycle.MutableLiveData<T> {
+    ctor public MediatorLiveData();
+    ctor public MediatorLiveData(T!);
+    method @MainThread public <S> void addSource(androidx.lifecycle.LiveData<S!>, androidx.lifecycle.Observer<? super S>);
+    method @MainThread public <S> void removeSource(androidx.lifecycle.LiveData<S!>);
+  }
+
+  public final class Transformations {
+    method @CheckResult @MainThread public static <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,Y> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,Y> mapFunction);
+    method @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<X,androidx.lifecycle.LiveData<Y>> transform);
+    method @Deprecated @CheckResult @MainThread public static <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, androidx.arch.core.util.Function<X,androidx.lifecycle.LiveData<Y>> switchMapFunction);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-process/api/2.6.0-beta02.txt b/lifecycle/lifecycle-process/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..891c9c6
--- /dev/null
+++ b/lifecycle/lifecycle-process/api/2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ProcessLifecycleInitializer implements androidx.startup.Initializer<androidx.lifecycle.LifecycleOwner> {
+    ctor public ProcessLifecycleInitializer();
+    method public androidx.lifecycle.LifecycleOwner create(android.content.Context context);
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>> dependencies();
+  }
+
+  public final class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner get();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+    field public static final androidx.lifecycle.ProcessLifecycleOwner.Companion Companion;
+  }
+
+  public static final class ProcessLifecycleOwner.Companion {
+    method public androidx.lifecycle.LifecycleOwner get();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-process/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-process/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..891c9c6
--- /dev/null
+++ b/lifecycle/lifecycle-process/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ProcessLifecycleInitializer implements androidx.startup.Initializer<androidx.lifecycle.LifecycleOwner> {
+    ctor public ProcessLifecycleInitializer();
+    method public androidx.lifecycle.LifecycleOwner create(android.content.Context context);
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>> dependencies();
+  }
+
+  public final class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner get();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+    field public static final androidx.lifecycle.ProcessLifecycleOwner.Companion Companion;
+  }
+
+  public static final class ProcessLifecycleOwner.Companion {
+    method public androidx.lifecycle.LifecycleOwner get();
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-process/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-process/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-process/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-process/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..891c9c6
--- /dev/null
+++ b/lifecycle/lifecycle-process/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ProcessLifecycleInitializer implements androidx.startup.Initializer<androidx.lifecycle.LifecycleOwner> {
+    ctor public ProcessLifecycleInitializer();
+    method public androidx.lifecycle.LifecycleOwner create(android.content.Context context);
+    method public java.util.List<java.lang.Class<? extends androidx.startup.Initializer<?>>> dependencies();
+  }
+
+  public final class ProcessLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner get();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+    field public static final androidx.lifecycle.ProcessLifecycleOwner.Companion Companion;
+  }
+
+  public static final class ProcessLifecycleOwner.Companion {
+    method public androidx.lifecycle.LifecycleOwner get();
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-reactivestreams-ktx/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/lifecycle/lifecycle-reactivestreams/api/2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..138dd3e
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/2.6.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveStreams {
+    method public static <T> androidx.lifecycle.LiveData<T> fromPublisher(org.reactivestreams.Publisher<T>);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LifecycleOwner lifecycle, androidx.lifecycle.LiveData<T> liveData);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..138dd3e
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveStreams {
+    method public static <T> androidx.lifecycle.LiveData<T> fromPublisher(org.reactivestreams.Publisher<T>);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LifecycleOwner lifecycle, androidx.lifecycle.LiveData<T> liveData);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-reactivestreams/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-reactivestreams/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-reactivestreams/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..138dd3e
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,11 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class LiveDataReactiveStreams {
+    method public static <T> androidx.lifecycle.LiveData<T> fromPublisher(org.reactivestreams.Publisher<T>);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LifecycleOwner lifecycle, androidx.lifecycle.LiveData<T> liveData);
+    method public static <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-compose/api/2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-compose/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..c80fa83
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/2.6.0-beta02.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+package androidx.lifecycle.compose {
+
+  public final class FlowExtKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..c80fa83
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+package androidx.lifecycle.compose {
+
+  public final class FlowExtKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-runtime-compose/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-runtime-compose/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-compose/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..c80fa83
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,12 @@
+// Signature format: 4.0
+package androidx.lifecycle.compose {
+
+  public final class FlowExtKt {
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.StateFlow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+    method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsStateWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, T? initialValue, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState, optional kotlin.coroutines.CoroutineContext context);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-ktx/api/2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-ktx/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..2ee0d85
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class FlowExtKt {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> flowWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState);
+  }
+
+  public final class LifecycleDestroyedException extends java.util.concurrent.CancellationException {
+    ctor public LifecycleDestroyedException();
+  }
+
+  public final class RepeatOnLifecycleKt {
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class ViewKt {
+    method @Deprecated public static androidx.lifecycle.LifecycleOwner? findViewTreeLifecycleOwner(android.view.View);
+  }
+
+  public final class WithLifecycleStateKt {
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..2ee0d85
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class FlowExtKt {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> flowWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState);
+  }
+
+  public final class LifecycleDestroyedException extends java.util.concurrent.CancellationException {
+    ctor public LifecycleDestroyedException();
+  }
+
+  public final class RepeatOnLifecycleKt {
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class ViewKt {
+    method @Deprecated public static androidx.lifecycle.LifecycleOwner? findViewTreeLifecycleOwner(android.view.View);
+  }
+
+  public final class WithLifecycleStateKt {
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-runtime-ktx/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-runtime-ktx/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-runtime-ktx/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..a998f6e
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-ktx/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,35 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class FlowExtKt {
+    method public static <T> kotlinx.coroutines.flow.Flow<T> flowWithLifecycle(kotlinx.coroutines.flow.Flow<? extends T>, androidx.lifecycle.Lifecycle lifecycle, optional androidx.lifecycle.Lifecycle.State minActiveState);
+  }
+
+  public final class LifecycleDestroyedException extends java.util.concurrent.CancellationException {
+    ctor public LifecycleDestroyedException();
+  }
+
+  public final class RepeatOnLifecycleKt {
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static suspend Object? repeatOnLifecycle(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+  }
+
+  public final class ViewKt {
+    method @Deprecated public static androidx.lifecycle.LifecycleOwner? findViewTreeLifecycleOwner(android.view.View);
+  }
+
+  public final class WithLifecycleStateKt {
+    method @kotlin.PublishedApi internal static suspend <R> Object? suspendWithStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, boolean dispatchNeeded, kotlinx.coroutines.CoroutineDispatcher lifecycleDispatcher, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withCreated(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withResumed(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.Lifecycle, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStarted(androidx.lifecycle.LifecycleOwner, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method public static suspend inline <R> Object? withStateAtLeast(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+    method @kotlin.PublishedApi internal static suspend inline <R> Object? withStateAtLeastUnchecked(androidx.lifecycle.Lifecycle, androidx.lifecycle.Lifecycle.State state, kotlin.jvm.functions.Function0<? extends R> block, kotlin.coroutines.Continuation<? super R>);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-testing/api/2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-testing/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..47a819e
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-testing/api/2.6.0-beta02.txt
@@ -0,0 +1,19 @@
+// Signature format: 4.0
+package androidx.lifecycle.testing {
+
+  public final class TestLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState);
+    ctor public TestLifecycleOwner();
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public androidx.lifecycle.LifecycleRegistry getLifecycle();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public final androidx.lifecycle.Lifecycle.State currentState;
+    property public androidx.lifecycle.LifecycleRegistry lifecycle;
+    property public final int observerCount;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..47a819e
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-testing/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,19 @@
+// Signature format: 4.0
+package androidx.lifecycle.testing {
+
+  public final class TestLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState);
+    ctor public TestLifecycleOwner();
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public androidx.lifecycle.LifecycleRegistry getLifecycle();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public final androidx.lifecycle.Lifecycle.State currentState;
+    property public androidx.lifecycle.LifecycleRegistry lifecycle;
+    property public final int observerCount;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-runtime-testing/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-runtime-testing/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-runtime-testing/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime-testing/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..47a819e
--- /dev/null
+++ b/lifecycle/lifecycle-runtime-testing/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,19 @@
+// Signature format: 4.0
+package androidx.lifecycle.testing {
+
+  public final class TestLifecycleOwner implements androidx.lifecycle.LifecycleOwner {
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    ctor public TestLifecycleOwner(optional androidx.lifecycle.Lifecycle.State initialState);
+    ctor public TestLifecycleOwner();
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public androidx.lifecycle.LifecycleRegistry getLifecycle();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public final androidx.lifecycle.Lifecycle.State currentState;
+    property public androidx.lifecycle.LifecycleRegistry lifecycle;
+    property public final int observerCount;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime/api/2.6.0-beta02.txt b/lifecycle/lifecycle-runtime/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..e72bd60
--- /dev/null
+++ b/lifecycle/lifecycle-runtime/api/2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
+    method @Deprecated public androidx.lifecycle.LifecycleRegistry getLifecycle();
+  }
+
+  public final class ViewTreeLifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.LifecycleOwner? lifecycleOwner);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-runtime/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..e72bd60
--- /dev/null
+++ b/lifecycle/lifecycle-runtime/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,33 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
+    method @Deprecated public androidx.lifecycle.LifecycleRegistry getLifecycle();
+  }
+
+  public final class ViewTreeLifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.LifecycleOwner? lifecycleOwner);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-runtime/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-runtime/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-runtime/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-runtime/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..704cdb4
--- /dev/null
+++ b/lifecycle/lifecycle-runtime/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,58 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleRegistry extends androidx.lifecycle.Lifecycle {
+    ctor public LifecycleRegistry(androidx.lifecycle.LifecycleOwner provider);
+    method public void addObserver(androidx.lifecycle.LifecycleObserver observer);
+    method @VisibleForTesting public static final androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+    method public androidx.lifecycle.Lifecycle.State getCurrentState();
+    method public int getObserverCount();
+    method public void handleLifecycleEvent(androidx.lifecycle.Lifecycle.Event event);
+    method @Deprecated @MainThread public void markState(androidx.lifecycle.Lifecycle.State state);
+    method public void removeObserver(androidx.lifecycle.LifecycleObserver observer);
+    method public void setCurrentState(androidx.lifecycle.Lifecycle.State);
+    property public androidx.lifecycle.Lifecycle.State currentState;
+    property public int observerCount;
+    field public static final androidx.lifecycle.LifecycleRegistry.Companion Companion;
+  }
+
+  public static final class LifecycleRegistry.Companion {
+    method @VisibleForTesting public androidx.lifecycle.LifecycleRegistry createUnsafe(androidx.lifecycle.LifecycleOwner owner);
+  }
+
+  @Deprecated public interface LifecycleRegistryOwner extends androidx.lifecycle.LifecycleOwner {
+    method @Deprecated public androidx.lifecycle.LifecycleRegistry getLifecycle();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ReportFragment extends android.app.Fragment {
+    ctor public ReportFragment();
+    method public static final androidx.lifecycle.ReportFragment get(android.app.Activity);
+    method public static final void injectIfNeededIn(android.app.Activity activity);
+    method public void onActivityCreated(android.os.Bundle? savedInstanceState);
+    method public void onDestroy();
+    method public void onPause();
+    method public void onResume();
+    method public void onStart();
+    method public void onStop();
+    method public final void setProcessListener(androidx.lifecycle.ReportFragment.ActivityInitializationListener? processListener);
+    field public static final androidx.lifecycle.ReportFragment.Companion Companion;
+  }
+
+  public static interface ReportFragment.ActivityInitializationListener {
+    method public void onCreate();
+    method public void onResume();
+    method public void onStart();
+  }
+
+  public static final class ReportFragment.Companion {
+    method public androidx.lifecycle.ReportFragment get(android.app.Activity);
+    method public void injectIfNeededIn(android.app.Activity activity);
+  }
+
+  public final class ViewTreeLifecycleOwner {
+    method public static androidx.lifecycle.LifecycleOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.LifecycleOwner? lifecycleOwner);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-service/api/2.6.0-beta02.txt b/lifecycle/lifecycle-service/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..bebcd93
--- /dev/null
+++ b/lifecycle/lifecycle-service/api/2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleService extends android.app.Service implements androidx.lifecycle.LifecycleOwner {
+    ctor public LifecycleService();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @CallSuper public android.os.IBinder? onBind(android.content.Intent intent);
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public class ServiceLifecycleDispatcher {
+    ctor public ServiceLifecycleDispatcher(androidx.lifecycle.LifecycleOwner provider);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public void onServicePreSuperOnBind();
+    method public void onServicePreSuperOnCreate();
+    method public void onServicePreSuperOnDestroy();
+    method public void onServicePreSuperOnStart();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-service/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-service/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..bebcd93
--- /dev/null
+++ b/lifecycle/lifecycle-service/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleService extends android.app.Service implements androidx.lifecycle.LifecycleOwner {
+    ctor public LifecycleService();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @CallSuper public android.os.IBinder? onBind(android.content.Intent intent);
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public class ServiceLifecycleDispatcher {
+    ctor public ServiceLifecycleDispatcher(androidx.lifecycle.LifecycleOwner provider);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public void onServicePreSuperOnBind();
+    method public void onServicePreSuperOnCreate();
+    method public void onServicePreSuperOnDestroy();
+    method public void onServicePreSuperOnStart();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-service/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-service/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-service/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-service/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..bebcd93
--- /dev/null
+++ b/lifecycle/lifecycle-service/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,22 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class LifecycleService extends android.app.Service implements androidx.lifecycle.LifecycleOwner {
+    ctor public LifecycleService();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method @CallSuper public android.os.IBinder? onBind(android.content.Intent intent);
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+  public class ServiceLifecycleDispatcher {
+    ctor public ServiceLifecycleDispatcher(androidx.lifecycle.LifecycleOwner provider);
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public void onServicePreSuperOnBind();
+    method public void onServicePreSuperOnCreate();
+    method public void onServicePreSuperOnDestroy();
+    method public void onServicePreSuperOnStart();
+    property public androidx.lifecycle.Lifecycle lifecycle;
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-compose/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..05b6910
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/api/2.6.0-beta02.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.lifecycle.viewmodel.compose {
+
+  public final class LocalViewModelStoreOwner {
+    method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner? getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
+    property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner? current;
+    field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
+  }
+
+  public final class SavedStateHandleSaverKt {
+  }
+
+  public final class ViewModelKt {
+    method @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/current.ignore b/lifecycle/lifecycle-viewmodel-compose/api/current.ignore
new file mode 100644
index 0000000..0a5b8ff
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/api/current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedClass: androidx.lifecycle.viewmodel.compose.SavedStateHandleSaverKt:
+    Removed class androidx.lifecycle.viewmodel.compose.SavedStateHandleSaverKt
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..188b922
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,30 @@
+// Signature format: 4.0
+package androidx.lifecycle.viewmodel.compose {
+
+  public final class LocalViewModelStoreOwner {
+    method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner? getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
+    property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner? current;
+    field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface SavedStateHandleSaveableApi {
+  }
+
+  public final class SavedStateHandleSaverKt {
+    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> T saveable(androidx.lifecycle.SavedStateHandle, String key, optional androidx.compose.runtime.saveable.Saver<T,?> saver, kotlin.jvm.functions.Function0<? extends T> init);
+    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> androidx.compose.runtime.MutableState<T> saveable(androidx.lifecycle.SavedStateHandle, String key, androidx.compose.runtime.saveable.Saver<T,?> stateSaver, kotlin.jvm.functions.Function0<? extends androidx.compose.runtime.MutableState<T>> init);
+    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T> kotlin.properties.PropertyDelegateProvider<java.lang.Object,kotlin.properties.ReadOnlyProperty<java.lang.Object,T>> saveable(androidx.lifecycle.SavedStateHandle, optional androidx.compose.runtime.saveable.Saver<T,?> saver, kotlin.jvm.functions.Function0<? extends T> init);
+    method @androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi public static <T, M extends androidx.compose.runtime.MutableState<T>> kotlin.properties.PropertyDelegateProvider<java.lang.Object,kotlin.properties.ReadWriteProperty<java.lang.Object,T>> saveableMutableState(androidx.lifecycle.SavedStateHandle, optional androidx.compose.runtime.saveable.Saver<T,?> stateSaver, kotlin.jvm.functions.Function0<? extends M> init);
+  }
+
+  public final class ViewModelKt {
+    method @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-compose/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-viewmodel-compose/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-compose/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..05b6910
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.lifecycle.viewmodel.compose {
+
+  public final class LocalViewModelStoreOwner {
+    method @androidx.compose.runtime.Composable public androidx.lifecycle.ViewModelStoreOwner? getCurrent();
+    method public infix androidx.compose.runtime.ProvidedValue<androidx.lifecycle.ViewModelStoreOwner> provides(androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner);
+    property @androidx.compose.runtime.Composable public final androidx.lifecycle.ViewModelStoreOwner? current;
+    field public static final androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner INSTANCE;
+  }
+
+  public final class SavedStateHandleSaverKt {
+  }
+
+  public final class ViewModelKt {
+    method @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory, optional androidx.lifecycle.viewmodel.CreationExtras extras);
+    method @Deprecated @androidx.compose.runtime.Composable public static <VM extends androidx.lifecycle.ViewModel> VM viewModel(Class<VM> modelClass, optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, optional androidx.lifecycle.ViewModelProvider.Factory? factory);
+    method @androidx.compose.runtime.Composable public static inline <reified VM extends androidx.lifecycle.ViewModel> VM viewModel(optional androidx.lifecycle.ViewModelStoreOwner viewModelStoreOwner, optional String? key, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.ignore b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.ignore
new file mode 100644
index 0000000..0a5b8ff
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-compose/api/restricted_current.ignore
@@ -0,0 +1,3 @@
+// Baseline format: 1.0
+RemovedClass: androidx.lifecycle.viewmodel.compose.SavedStateHandleSaverKt:
+    Removed class androidx.lifecycle.viewmodel.compose.SavedStateHandleSaverKt
diff --git a/lifecycle/lifecycle-viewmodel-ktx/api/2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-ktx/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..1d1d247
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-ktx/api/2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ViewModelKt {
+    method public static kotlinx.coroutines.CoroutineScope getViewModelScope(androidx.lifecycle.ViewModel);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-ktx/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-ktx/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..1d1d247
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-ktx/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ViewModelKt {
+    method public static kotlinx.coroutines.CoroutineScope getViewModelScope(androidx.lifecycle.ViewModel);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-ktx/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-viewmodel-ktx/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..1d1d247
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-ktx/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,9 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public final class ViewModelKt {
+    method public static kotlinx.coroutines.CoroutineScope getViewModelScope(androidx.lifecycle.ViewModel);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..c030c8a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/2.6.0-beta02.txt
@@ -0,0 +1,45 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public AbstractSavedStateViewModelFactory();
+    ctor public AbstractSavedStateViewModelFactory(androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method protected abstract <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass, androidx.lifecycle.SavedStateHandle handle);
+  }
+
+  public final class SavedStateHandle {
+    ctor public SavedStateHandle(java.util.Map<java.lang.String,?> initialState);
+    ctor public SavedStateHandle();
+    method @MainThread public void clearSavedStateProvider(String key);
+    method @MainThread public operator boolean contains(String key);
+    method @MainThread public operator <T> T? get(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
+    method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+    method @MainThread public java.util.Set<java.lang.String> keys();
+    method @MainThread public <T> T? remove(String key);
+    method @MainThread public operator <T> void set(String key, T? value);
+    method @MainThread public void setSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    field public static final androidx.lifecycle.SavedStateHandle.Companion Companion;
+  }
+
+  public static final class SavedStateHandle.Companion {
+  }
+
+  public final class SavedStateHandleSupport {
+    method @MainThread public static androidx.lifecycle.SavedStateHandle createSavedStateHandle(androidx.lifecycle.viewmodel.CreationExtras);
+    method @MainThread public static <T extends androidx.savedstate.SavedStateRegistryOwner & androidx.lifecycle.ViewModelStoreOwner> void enableSavedStateHandles(T);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.os.Bundle> DEFAULT_ARGS_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.savedstate.SavedStateRegistryOwner> SAVED_STATE_REGISTRY_OWNER_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.lifecycle.ViewModelStoreOwner> VIEW_MODEL_STORE_OWNER_KEY;
+  }
+
+  public final class SavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public SavedStateViewModelFactory();
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner);
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method public <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..c030c8a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,45 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public AbstractSavedStateViewModelFactory();
+    ctor public AbstractSavedStateViewModelFactory(androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method protected abstract <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass, androidx.lifecycle.SavedStateHandle handle);
+  }
+
+  public final class SavedStateHandle {
+    ctor public SavedStateHandle(java.util.Map<java.lang.String,?> initialState);
+    ctor public SavedStateHandle();
+    method @MainThread public void clearSavedStateProvider(String key);
+    method @MainThread public operator boolean contains(String key);
+    method @MainThread public operator <T> T? get(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
+    method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+    method @MainThread public java.util.Set<java.lang.String> keys();
+    method @MainThread public <T> T? remove(String key);
+    method @MainThread public operator <T> void set(String key, T? value);
+    method @MainThread public void setSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    field public static final androidx.lifecycle.SavedStateHandle.Companion Companion;
+  }
+
+  public static final class SavedStateHandle.Companion {
+  }
+
+  public final class SavedStateHandleSupport {
+    method @MainThread public static androidx.lifecycle.SavedStateHandle createSavedStateHandle(androidx.lifecycle.viewmodel.CreationExtras);
+    method @MainThread public static <T extends androidx.savedstate.SavedStateRegistryOwner & androidx.lifecycle.ViewModelStoreOwner> void enableSavedStateHandles(T);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.os.Bundle> DEFAULT_ARGS_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.savedstate.SavedStateRegistryOwner> SAVED_STATE_REGISTRY_OWNER_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.lifecycle.ViewModelStoreOwner> VIEW_MODEL_STORE_OWNER_KEY;
+  }
+
+  public final class SavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public SavedStateViewModelFactory();
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner);
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method public <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-viewmodel-savedstate/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..c030c8a
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel-savedstate/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,45 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public abstract class AbstractSavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public AbstractSavedStateViewModelFactory();
+    ctor public AbstractSavedStateViewModelFactory(androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method protected abstract <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass, androidx.lifecycle.SavedStateHandle handle);
+  }
+
+  public final class SavedStateHandle {
+    ctor public SavedStateHandle(java.util.Map<java.lang.String,?> initialState);
+    ctor public SavedStateHandle();
+    method @MainThread public void clearSavedStateProvider(String key);
+    method @MainThread public operator boolean contains(String key);
+    method @MainThread public operator <T> T? get(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key);
+    method @MainThread public <T> androidx.lifecycle.MutableLiveData<T> getLiveData(String key, T? initialValue);
+    method @MainThread public <T> kotlinx.coroutines.flow.StateFlow<T> getStateFlow(String key, T? initialValue);
+    method @MainThread public java.util.Set<java.lang.String> keys();
+    method @MainThread public <T> T? remove(String key);
+    method @MainThread public operator <T> void set(String key, T? value);
+    method @MainThread public void setSavedStateProvider(String key, androidx.savedstate.SavedStateRegistry.SavedStateProvider provider);
+    field public static final androidx.lifecycle.SavedStateHandle.Companion Companion;
+  }
+
+  public static final class SavedStateHandle.Companion {
+  }
+
+  public final class SavedStateHandleSupport {
+    method @MainThread public static androidx.lifecycle.SavedStateHandle createSavedStateHandle(androidx.lifecycle.viewmodel.CreationExtras);
+    method @MainThread public static <T extends androidx.savedstate.SavedStateRegistryOwner & androidx.lifecycle.ViewModelStoreOwner> void enableSavedStateHandles(T);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.os.Bundle> DEFAULT_ARGS_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.savedstate.SavedStateRegistryOwner> SAVED_STATE_REGISTRY_OWNER_KEY;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<androidx.lifecycle.ViewModelStoreOwner> VIEW_MODEL_STORE_OWNER_KEY;
+  }
+
+  public final class SavedStateViewModelFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public SavedStateViewModelFactory();
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner);
+    ctor public SavedStateViewModelFactory(android.app.Application? application, androidx.savedstate.SavedStateRegistryOwner owner, android.os.Bundle? defaultArgs);
+    method public <T extends androidx.lifecycle.ViewModel> T create(String key, Class<T> modelClass);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel/api/2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel/api/2.6.0-beta02.txt
new file mode 100644
index 0000000..f8457f6
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/2.6.0-beta02.txt
@@ -0,0 +1,136 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class AndroidViewModel extends androidx.lifecycle.ViewModel {
+    ctor public AndroidViewModel(android.app.Application application);
+    method public <T extends android.app.Application> T getApplication();
+  }
+
+  public interface HasDefaultViewModelProviderFactory {
+    method public default androidx.lifecycle.viewmodel.CreationExtras getDefaultViewModelCreationExtras();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    property public default androidx.lifecycle.viewmodel.CreationExtras defaultViewModelCreationExtras;
+    property public abstract androidx.lifecycle.ViewModelProvider.Factory defaultViewModelProviderFactory;
+  }
+
+  public abstract class ViewModel {
+    ctor public ViewModel();
+    ctor public ViewModel(java.io.Closeable!...);
+    method public void addCloseable(java.io.Closeable);
+    method protected void onCleared();
+  }
+
+  public final class ViewModelLazy<VM extends androidx.lifecycle.ViewModel> implements kotlin.Lazy<VM> {
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer);
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer);
+    method public VM getValue();
+    method public boolean isInitialized();
+    property public VM value;
+  }
+
+  public class ViewModelProvider {
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras defaultCreationExtras);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(Class<T> modelClass);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(String key, Class<T> modelClass);
+  }
+
+  public static class ViewModelProvider.AndroidViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory {
+    ctor public ViewModelProvider.AndroidViewModelFactory();
+    ctor public ViewModelProvider.AndroidViewModelFactory(android.app.Application application);
+    method public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.app.Application> APPLICATION_KEY;
+    field public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.AndroidViewModelFactory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+  }
+
+  public static interface ViewModelProvider.Factory {
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass);
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public default static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+    field public static final androidx.lifecycle.ViewModelProvider.Factory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.Factory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+  }
+
+  public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public ViewModelProvider.NewInstanceFactory();
+    field public static final androidx.lifecycle.ViewModelProvider.NewInstanceFactory.Companion Companion;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<java.lang.String> VIEW_MODEL_KEY;
+  }
+
+  public static final class ViewModelProvider.NewInstanceFactory.Companion {
+  }
+
+  public final class ViewModelProviderGetKt {
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> VM get(androidx.lifecycle.ViewModelProvider);
+  }
+
+  public class ViewModelStore {
+    ctor public ViewModelStore();
+    method public final void clear();
+  }
+
+  public interface ViewModelStoreOwner {
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    property public abstract androidx.lifecycle.ViewModelStore viewModelStore;
+  }
+
+  public final class ViewTreeViewModelKt {
+    method @Deprecated public static androidx.lifecycle.ViewModelStoreOwner? findViewTreeViewModelStoreOwner(android.view.View view);
+  }
+
+  public final class ViewTreeViewModelStoreOwner {
+    method public static androidx.lifecycle.ViewModelStoreOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.ViewModelStoreOwner? viewModelStoreOwner);
+  }
+
+}
+
+package androidx.lifecycle.viewmodel {
+
+  public abstract class CreationExtras {
+    method public abstract operator <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+  }
+
+  public static final class CreationExtras.Empty extends androidx.lifecycle.viewmodel.CreationExtras {
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Empty INSTANCE;
+  }
+
+  public static interface CreationExtras.Key<T> {
+  }
+
+  @androidx.lifecycle.viewmodel.ViewModelFactoryDsl public final class InitializerViewModelFactoryBuilder {
+    ctor public InitializerViewModelFactoryBuilder();
+    method public <T extends androidx.lifecycle.ViewModel> void addInitializer(kotlin.reflect.KClass<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+    method public androidx.lifecycle.ViewModelProvider.Factory build();
+  }
+
+  public final class InitializerViewModelFactoryKt {
+    method public static inline <reified VM extends androidx.lifecycle.ViewModel> void initializer(androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+    method public static inline androidx.lifecycle.ViewModelProvider.Factory viewModelFactory(kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder,kotlin.Unit> builder);
+  }
+
+  public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
+    ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+  }
+
+  @kotlin.DslMarker public @interface ViewModelFactoryDsl {
+  }
+
+  public final class ViewModelInitializer<T extends androidx.lifecycle.ViewModel> {
+    ctor public ViewModelInitializer(Class<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+  }
+
+}
+
diff --git a/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_2.6.0-beta02.txt
new file mode 100644
index 0000000..f8457f6
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/public_plus_experimental_2.6.0-beta02.txt
@@ -0,0 +1,136 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class AndroidViewModel extends androidx.lifecycle.ViewModel {
+    ctor public AndroidViewModel(android.app.Application application);
+    method public <T extends android.app.Application> T getApplication();
+  }
+
+  public interface HasDefaultViewModelProviderFactory {
+    method public default androidx.lifecycle.viewmodel.CreationExtras getDefaultViewModelCreationExtras();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    property public default androidx.lifecycle.viewmodel.CreationExtras defaultViewModelCreationExtras;
+    property public abstract androidx.lifecycle.ViewModelProvider.Factory defaultViewModelProviderFactory;
+  }
+
+  public abstract class ViewModel {
+    ctor public ViewModel();
+    ctor public ViewModel(java.io.Closeable!...);
+    method public void addCloseable(java.io.Closeable);
+    method protected void onCleared();
+  }
+
+  public final class ViewModelLazy<VM extends androidx.lifecycle.ViewModel> implements kotlin.Lazy<VM> {
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer);
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer);
+    method public VM getValue();
+    method public boolean isInitialized();
+    property public VM value;
+  }
+
+  public class ViewModelProvider {
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras defaultCreationExtras);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(Class<T> modelClass);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(String key, Class<T> modelClass);
+  }
+
+  public static class ViewModelProvider.AndroidViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory {
+    ctor public ViewModelProvider.AndroidViewModelFactory();
+    ctor public ViewModelProvider.AndroidViewModelFactory(android.app.Application application);
+    method public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.app.Application> APPLICATION_KEY;
+    field public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.AndroidViewModelFactory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+  }
+
+  public static interface ViewModelProvider.Factory {
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass);
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public default static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+    field public static final androidx.lifecycle.ViewModelProvider.Factory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.Factory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+  }
+
+  public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public ViewModelProvider.NewInstanceFactory();
+    field public static final androidx.lifecycle.ViewModelProvider.NewInstanceFactory.Companion Companion;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<java.lang.String> VIEW_MODEL_KEY;
+  }
+
+  public static final class ViewModelProvider.NewInstanceFactory.Companion {
+  }
+
+  public final class ViewModelProviderGetKt {
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> VM get(androidx.lifecycle.ViewModelProvider);
+  }
+
+  public class ViewModelStore {
+    ctor public ViewModelStore();
+    method public final void clear();
+  }
+
+  public interface ViewModelStoreOwner {
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    property public abstract androidx.lifecycle.ViewModelStore viewModelStore;
+  }
+
+  public final class ViewTreeViewModelKt {
+    method @Deprecated public static androidx.lifecycle.ViewModelStoreOwner? findViewTreeViewModelStoreOwner(android.view.View view);
+  }
+
+  public final class ViewTreeViewModelStoreOwner {
+    method public static androidx.lifecycle.ViewModelStoreOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.ViewModelStoreOwner? viewModelStoreOwner);
+  }
+
+}
+
+package androidx.lifecycle.viewmodel {
+
+  public abstract class CreationExtras {
+    method public abstract operator <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+  }
+
+  public static final class CreationExtras.Empty extends androidx.lifecycle.viewmodel.CreationExtras {
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Empty INSTANCE;
+  }
+
+  public static interface CreationExtras.Key<T> {
+  }
+
+  @androidx.lifecycle.viewmodel.ViewModelFactoryDsl public final class InitializerViewModelFactoryBuilder {
+    ctor public InitializerViewModelFactoryBuilder();
+    method public <T extends androidx.lifecycle.ViewModel> void addInitializer(kotlin.reflect.KClass<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+    method public androidx.lifecycle.ViewModelProvider.Factory build();
+  }
+
+  public final class InitializerViewModelFactoryKt {
+    method public static inline <reified VM extends androidx.lifecycle.ViewModel> void initializer(androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+    method public static inline androidx.lifecycle.ViewModelProvider.Factory viewModelFactory(kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder,kotlin.Unit> builder);
+  }
+
+  public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
+    ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+  }
+
+  @kotlin.DslMarker public @interface ViewModelFactoryDsl {
+  }
+
+  public final class ViewModelInitializer<T extends androidx.lifecycle.ViewModel> {
+    ctor public ViewModelInitializer(Class<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel/api/res-2.6.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to lifecycle/lifecycle-viewmodel/api/res-2.6.0-beta02.txt
diff --git a/lifecycle/lifecycle-viewmodel/api/restricted_2.6.0-beta02.txt b/lifecycle/lifecycle-viewmodel/api/restricted_2.6.0-beta02.txt
new file mode 100644
index 0000000..f8457f6
--- /dev/null
+++ b/lifecycle/lifecycle-viewmodel/api/restricted_2.6.0-beta02.txt
@@ -0,0 +1,136 @@
+// Signature format: 4.0
+package androidx.lifecycle {
+
+  public class AndroidViewModel extends androidx.lifecycle.ViewModel {
+    ctor public AndroidViewModel(android.app.Application application);
+    method public <T extends android.app.Application> T getApplication();
+  }
+
+  public interface HasDefaultViewModelProviderFactory {
+    method public default androidx.lifecycle.viewmodel.CreationExtras getDefaultViewModelCreationExtras();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    property public default androidx.lifecycle.viewmodel.CreationExtras defaultViewModelCreationExtras;
+    property public abstract androidx.lifecycle.ViewModelProvider.Factory defaultViewModelProviderFactory;
+  }
+
+  public abstract class ViewModel {
+    ctor public ViewModel();
+    ctor public ViewModel(java.io.Closeable!...);
+    method public void addCloseable(java.io.Closeable);
+    method protected void onCleared();
+  }
+
+  public final class ViewModelLazy<VM extends androidx.lifecycle.ViewModel> implements kotlin.Lazy<VM> {
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras> extrasProducer);
+    ctor public ViewModelLazy(kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory> factoryProducer);
+    method public VM getValue();
+    method public boolean isInitialized();
+    property public VM value;
+  }
+
+  public class ViewModelProvider {
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory, optional androidx.lifecycle.viewmodel.CreationExtras defaultCreationExtras);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStore store, androidx.lifecycle.ViewModelProvider.Factory factory);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner);
+    ctor public ViewModelProvider(androidx.lifecycle.ViewModelStoreOwner owner, androidx.lifecycle.ViewModelProvider.Factory factory);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(Class<T> modelClass);
+    method @MainThread public operator <T extends androidx.lifecycle.ViewModel> T get(String key, Class<T> modelClass);
+  }
+
+  public static class ViewModelProvider.AndroidViewModelFactory extends androidx.lifecycle.ViewModelProvider.NewInstanceFactory {
+    ctor public ViewModelProvider.AndroidViewModelFactory();
+    ctor public ViewModelProvider.AndroidViewModelFactory(android.app.Application application);
+    method public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<android.app.Application> APPLICATION_KEY;
+    field public static final androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.AndroidViewModelFactory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory getInstance(android.app.Application application);
+  }
+
+  public static interface ViewModelProvider.Factory {
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass);
+    method public default <T extends androidx.lifecycle.ViewModel> T create(Class<T> modelClass, androidx.lifecycle.viewmodel.CreationExtras extras);
+    method public default static androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+    field public static final androidx.lifecycle.ViewModelProvider.Factory.Companion Companion;
+  }
+
+  public static final class ViewModelProvider.Factory.Companion {
+    method public androidx.lifecycle.ViewModelProvider.Factory from(androidx.lifecycle.viewmodel.ViewModelInitializer<?>... initializers);
+  }
+
+  public static class ViewModelProvider.NewInstanceFactory implements androidx.lifecycle.ViewModelProvider.Factory {
+    ctor public ViewModelProvider.NewInstanceFactory();
+    field public static final androidx.lifecycle.ViewModelProvider.NewInstanceFactory.Companion Companion;
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Key<java.lang.String> VIEW_MODEL_KEY;
+  }
+
+  public static final class ViewModelProvider.NewInstanceFactory.Companion {
+  }
+
+  public final class ViewModelProviderGetKt {
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> VM get(androidx.lifecycle.ViewModelProvider);
+  }
+
+  public class ViewModelStore {
+    ctor public ViewModelStore();
+    method public final void clear();
+  }
+
+  public interface ViewModelStoreOwner {
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    property public abstract androidx.lifecycle.ViewModelStore viewModelStore;
+  }
+
+  public final class ViewTreeViewModelKt {
+    method @Deprecated public static androidx.lifecycle.ViewModelStoreOwner? findViewTreeViewModelStoreOwner(android.view.View view);
+  }
+
+  public final class ViewTreeViewModelStoreOwner {
+    method public static androidx.lifecycle.ViewModelStoreOwner? get(android.view.View);
+    method public static void set(android.view.View, androidx.lifecycle.ViewModelStoreOwner? viewModelStoreOwner);
+  }
+
+}
+
+package androidx.lifecycle.viewmodel {
+
+  public abstract class CreationExtras {
+    method public abstract operator <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+  }
+
+  public static final class CreationExtras.Empty extends androidx.lifecycle.viewmodel.CreationExtras {
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    field public static final androidx.lifecycle.viewmodel.CreationExtras.Empty INSTANCE;
+  }
+
+  public static interface CreationExtras.Key<T> {
+  }
+
+  @androidx.lifecycle.viewmodel.ViewModelFactoryDsl public final class InitializerViewModelFactoryBuilder {
+    ctor public InitializerViewModelFactoryBuilder();
+    method public <T extends androidx.lifecycle.ViewModel> void addInitializer(kotlin.reflect.KClass<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+    method public androidx.lifecycle.ViewModelProvider.Factory build();
+  }
+
+  public final class InitializerViewModelFactoryKt {
+    method public static inline <reified VM extends androidx.lifecycle.ViewModel> void initializer(androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends VM> initializer);
+    method public static inline androidx.lifecycle.ViewModelProvider.Factory viewModelFactory(kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.InitializerViewModelFactoryBuilder,kotlin.Unit> builder);
+  }
+
+  public final class MutableCreationExtras extends androidx.lifecycle.viewmodel.CreationExtras {
+    ctor public MutableCreationExtras(optional androidx.lifecycle.viewmodel.CreationExtras initialExtras);
+    method public <T> T? get(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key);
+    method public operator <T> void set(androidx.lifecycle.viewmodel.CreationExtras.Key<T> key, T? t);
+  }
+
+  @kotlin.DslMarker public @interface ViewModelFactoryDsl {
+  }
+
+  public final class ViewModelInitializer<T extends androidx.lifecycle.ViewModel> {
+    ctor public ViewModelInitializer(Class<T> clazz, kotlin.jvm.functions.Function1<? super androidx.lifecycle.viewmodel.CreationExtras,? extends T> initializer);
+  }
+
+}
+
diff --git a/media/media/api/current.txt b/media/media/api/current.txt
index 88dc4db3..2509d03 100644
--- a/media/media/api/current.txt
+++ b/media/media/api/current.txt
@@ -690,6 +690,7 @@
     method public static android.support.v4.media.session.MediaSessionCompat.Token! getMediaSession(android.app.Notification!);
     method public androidx.media.app.NotificationCompat.MediaStyle! setCancelButtonIntent(android.app.PendingIntent!);
     method public androidx.media.app.NotificationCompat.MediaStyle! setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token!);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public androidx.media.app.NotificationCompat.MediaStyle setRemotePlaybackInfo(CharSequence, @DrawableRes int, android.app.PendingIntent?);
     method public androidx.media.app.NotificationCompat.MediaStyle! setShowActionsInCompactView(int...);
     method public androidx.media.app.NotificationCompat.MediaStyle! setShowCancelButton(boolean);
   }
diff --git a/media/media/api/restricted_current.txt b/media/media/api/restricted_current.txt
index a40b59b..4f0864c 100644
--- a/media/media/api/restricted_current.txt
+++ b/media/media/api/restricted_current.txt
@@ -728,6 +728,7 @@
     method public static android.support.v4.media.session.MediaSessionCompat.Token! getMediaSession(android.app.Notification!);
     method public androidx.media.app.NotificationCompat.MediaStyle! setCancelButtonIntent(android.app.PendingIntent!);
     method public androidx.media.app.NotificationCompat.MediaStyle! setMediaSession(android.support.v4.media.session.MediaSessionCompat.Token!);
+    method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public androidx.media.app.NotificationCompat.MediaStyle setRemotePlaybackInfo(CharSequence, @DrawableRes int, android.app.PendingIntent?);
     method public androidx.media.app.NotificationCompat.MediaStyle! setShowActionsInCompactView(int...);
     method public androidx.media.app.NotificationCompat.MediaStyle! setShowCancelButton(boolean);
   }
diff --git a/media/media/build.gradle b/media/media/build.gradle
index 783d543..1523950 100644
--- a/media/media/build.gradle
+++ b/media/media/build.gradle
@@ -25,6 +25,7 @@
     api("androidx.core:core:1.6.0")
     implementation("androidx.annotation:annotation:1.2.0")
     implementation("androidx.collection:collection:1.1.0")
+    implementation("androidx.core:core:1.9.0")
 
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
diff --git a/media/media/lint-baseline.xml b/media/media/lint-baseline.xml
index 7760b0e..83d9e78 100644
--- a/media/media/lint-baseline.xml
+++ b/media/media/lint-baseline.xml
@@ -1,5 +1,23 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/media/app/NotificationCompat.java"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/media/app/NotificationCompat.java"/>
+    </issue>
 
     <issue
         id="RequireUnstableAidlAnnotation"
diff --git a/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java b/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
index 665ca9d..fbc41d9 100644
--- a/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
+++ b/media/media/src/main/java/androidx/media/MediaBrowserServiceCompat.java
@@ -79,7 +79,9 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.annotation.CallSuper;
 import androidx.annotation.IntDef;
+import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
@@ -93,7 +95,6 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -184,7 +185,7 @@
     final ArrayList<ConnectionRecord> mPendingConnections = new ArrayList<>();
     final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
     ConnectionRecord mCurConnection;
-    final ServiceHandler mHandler = new ServiceHandler(/* serviceRef= */ this);
+    final ServiceHandler mHandler = new ServiceHandler(/* service= */ this);
     MediaSessionCompat.Token mSession;
 
     interface MediaBrowserServiceImpl {
@@ -660,23 +661,30 @@
     }
 
     private static final class ServiceHandler extends Handler {
-        private final WeakReference<MediaBrowserServiceCompat> mServiceWeakRef;
 
-        ServiceHandler(MediaBrowserServiceCompat serviceRef) {
-            mServiceWeakRef = new WeakReference<>(serviceRef);
+        // Must only be accessed on the main thread.
+        @Nullable private MediaBrowserServiceCompat mService;
+
+        @MainThread
+        ServiceHandler(@NonNull MediaBrowserServiceCompat service) {
+            mService = service;
         }
 
         @Override
-        @SuppressWarnings("deprecation")
+        @MainThread
         public void handleMessage(@NonNull Message msg) {
-            MediaBrowserServiceCompat service = mServiceWeakRef.get();
-            if (service != null) {
-                service.handleMessageInternal(msg);
+            if (mService != null) {
+                mService.handleMessageInternal(msg);
             } else {
                 removeCallbacksAndMessages(/* token= */ null);
             }
         }
 
+        @MainThread
+        public void release() {
+            mService = null;
+        }
+
         @Override
         public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
             // Binder.getCallingUid() in handleMessage will return the uid of this process.
@@ -1249,6 +1257,13 @@
         mImpl.onCreate();
     }
 
+    @CallSuper
+    @MainThread
+    @Override
+    public void onDestroy() {
+        mHandler.release();
+    }
+
     @Override
     public IBinder onBind(Intent intent) {
         return mImpl.onBind(intent);
diff --git a/media/media/src/main/java/androidx/media/app/NotificationCompat.java b/media/media/src/main/java/androidx/media/app/NotificationCompat.java
index e5c36ad..be90897 100644
--- a/media/media/src/main/java/androidx/media/app/NotificationCompat.java
+++ b/media/media/src/main/java/androidx/media/app/NotificationCompat.java
@@ -16,9 +16,12 @@
 
 package androidx.media.app;
 
+import static android.Manifest.permission.MEDIA_CONTENT_CONTROL;
+
 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 import static androidx.core.app.NotificationCompat.COLOR_DEFAULT;
 
+import android.annotation.SuppressLint;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.media.session.MediaSession;
@@ -31,10 +34,16 @@
 import android.widget.RemoteViews;
 
 import androidx.annotation.DoNotInline;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
 import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresPermission;
 import androidx.annotation.RestrictTo;
 import androidx.core.app.BundleCompat;
 import androidx.core.app.NotificationBuilderWithBuilderAccessor;
+import androidx.core.os.BuildCompat;
 import androidx.media.R;
 
 /**
@@ -133,6 +142,10 @@
         MediaSessionCompat.Token mToken;
         boolean mShowCancelButton;
         PendingIntent mCancelButtonIntent;
+        CharSequence mDeviceName;
+        int mDeviceIcon;
+        PendingIntent mDeviceIntent;
+        boolean mShowRemotePlaybackInfo = false;
 
         public MediaStyle() {
         }
@@ -162,6 +175,36 @@
         }
 
         /**
+         * For media notifications associated with playback on a remote device, provide device
+         * information that will replace the default values for the output switcher chip on the
+         * media control, as well as an intent to use when the output switcher chip is tapped,
+         * on devices where this is supported.
+         * <p>
+         * This method is intended for system applications to provide information and/or
+         * functionality that would otherwise be unavailable to the default output switcher because
+         * the media originated on a remote device.
+         * <p>
+         * Also note that this method is a no-op when running on Tiramisu or less.
+         *
+         * @param deviceName The name of the remote device to display.
+         * @param iconResource Icon resource, of size 12, representing the device.
+         * @param chipIntent PendingIntent to send when the output switcher is tapped. May be
+         *                   {@code null}, in which case the output switcher will be disabled.
+         *                   This intent should open an Activity or it will be ignored.
+         * @return MediaStyle
+         */
+        @RequiresPermission(MEDIA_CONTENT_CONTROL)
+        @NonNull
+        public MediaStyle setRemotePlaybackInfo(@NonNull CharSequence deviceName,
+                @DrawableRes int iconResource, @Nullable PendingIntent chipIntent) {
+            mDeviceName = deviceName;
+            mDeviceIcon = iconResource;
+            mDeviceIntent = chipIntent;
+            mShowRemotePlaybackInfo = true;
+            return this;
+        }
+
+        /**
          * Sets whether a cancel button at the top right should be shown in the notification on
          * platforms before Lollipop.
          *
@@ -205,10 +248,17 @@
 
         /**
          */
+        @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
         @RestrictTo(LIBRARY)
         @Override
         public void apply(NotificationBuilderWithBuilderAccessor builder) {
-            if (Build.VERSION.SDK_INT >= 21) {
+            if (BuildCompat.isAtLeastU()) {
+                Api21Impl.setMediaStyle(builder.getBuilder(),
+                        Api21Impl.fillInMediaStyle(Api34Impl.setRemotePlaybackInfo(
+                                Api21Impl.createMediaStyle(), mDeviceName, mDeviceIcon,
+                                        mDeviceIntent, mShowRemotePlaybackInfo),
+                                mActionsToShowInCompact, mToken));
+            } else if (Build.VERSION.SDK_INT >= 21) {
                 Api21Impl.setMediaStyle(builder.getBuilder(),
                         Api21Impl.fillInMediaStyle(Api21Impl.createMediaStyle(),
                                 mActionsToShowInCompact, mToken));
@@ -370,10 +420,17 @@
 
         /**
          */
+        @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
         @RestrictTo(LIBRARY)
         @Override
         public void apply(NotificationBuilderWithBuilderAccessor builder) {
-            if (Build.VERSION.SDK_INT >= 24) {
+            if (BuildCompat.isAtLeastU()) {
+                Api21Impl.setMediaStyle(builder.getBuilder(), Api21Impl.fillInMediaStyle(
+                        Api34Impl.setRemotePlaybackInfo(
+                                Api24Impl.createDecoratedMediaCustomViewStyle(), mDeviceName,
+                                mDeviceIcon, mDeviceIntent, mShowRemotePlaybackInfo),
+                        mActionsToShowInCompact, mToken));
+            } else if (Build.VERSION.SDK_INT >= 24) {
                 Api21Impl.setMediaStyle(builder.getBuilder(),
                         Api21Impl.fillInMediaStyle(Api24Impl.createDecoratedMediaCustomViewStyle(),
                                 mActionsToShowInCompact, mToken));
@@ -544,4 +601,24 @@
             return new Notification.DecoratedMediaCustomViewStyle();
         }
     }
-}
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+
+        private Api34Impl() {}
+
+        @SuppressLint({"MissingPermission"})
+        @DoNotInline
+        static Notification.MediaStyle setRemotePlaybackInfo(Notification.MediaStyle style,
+                @NonNull CharSequence deviceName, @DrawableRes int iconResource,
+                @Nullable PendingIntent chipIntent, Boolean showRemotePlaybackInfo) {
+            // Suppress @RequiresPermission(MEDIA_CONTENT_CONTROL) because the API is only used
+            // if showRemotePlaybackInfo is set to true. This only happens for callers to
+            // NotificationCompat#setRemotePlaybackInfo.
+            if (showRemotePlaybackInfo) {
+                style.setRemotePlaybackInfo(deviceName, iconResource, chipIntent);
+            }
+            return style;
+        }
+    }
+}
\ No newline at end of file
diff --git a/mediarouter/mediarouter/api/current.txt b/mediarouter/mediarouter/api/current.txt
index 3fb8c40..00e0b0a 100644
--- a/mediarouter/mediarouter/api/current.txt
+++ b/mediarouter/mediarouter/api/current.txt
@@ -170,8 +170,10 @@
     method public android.os.Bundle asBundle();
     method public boolean canDisconnectAndKeepPlaying();
     method public static androidx.mediarouter.media.MediaRouteDescriptor? fromBundle(android.os.Bundle?);
+    method public java.util.Set<java.lang.String!> getAllowedPackages();
     method public int getConnectionState();
     method public java.util.List<android.content.IntentFilter!> getControlFilters();
+    method public java.util.Set<java.lang.String!> getDeduplicationIds();
     method public String? getDescription();
     method public int getDeviceType();
     method public android.os.Bundle? getExtras();
@@ -189,6 +191,7 @@
     method public boolean isDynamicGroupRoute();
     method public boolean isEnabled();
     method public boolean isValid();
+    method public boolean isVisibilityPublic();
   }
 
   public static final class MediaRouteDescriptor.Builder {
@@ -201,6 +204,7 @@
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
     method @Deprecated public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnecting(boolean);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnectionState(int);
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeduplicationIds(java.util.Set<java.lang.String!>);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDescription(String?);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeviceType(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setEnabled(boolean);
@@ -213,6 +217,8 @@
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackType(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender?);
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityPublic();
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityRestricted(java.util.Set<java.lang.String!>);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolume(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeMax(int);
@@ -346,7 +352,7 @@
     method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback);
     method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback, int);
     method @MainThread public void addProvider(androidx.mediarouter.media.MediaRouteProvider);
-    method @MainThread public void addRemoteControlClient(Object);
+    method @Deprecated @MainThread public void addRemoteControlClient(Object);
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo? getBluetoothRoute();
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getDefaultRoute();
     method @MainThread public static androidx.mediarouter.media.MediaRouter getInstance(android.content.Context);
@@ -363,6 +369,7 @@
     method @MainThread public void setMediaSession(Object?);
     method @MainThread public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat?);
     method @MainThread public void setOnPrepareTransferListener(androidx.mediarouter.media.MediaRouter.OnPrepareTransferListener?);
+    method @MainThread public void setRouteListingPreference(androidx.mediarouter.media.RouteListingPreference?);
     method @MainThread public void setRouterParams(androidx.mediarouter.media.MediaRouterParams?);
     method @MainThread public void unselect(int);
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo updateSelectedRoute(androidx.mediarouter.media.MediaRouteSelector);
@@ -562,5 +569,53 @@
     method public void onSessionStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?);
   }
 
+  public final class RouteListingPreference {
+    method public java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!> getItems();
+    method public android.content.ComponentName? getLinkedItemComponentName();
+    method public boolean getUseSystemOrdering();
+    field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA";
+    field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID";
+  }
+
+  public static final class RouteListingPreference.Builder {
+    ctor public RouteListingPreference.Builder();
+    method public androidx.mediarouter.media.RouteListingPreference build();
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setItems(java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!>);
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setLinkedItemComponentName(android.content.ComponentName?);
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setUseSystemOrdering(boolean);
+  }
+
+  public static final class RouteListingPreference.Item {
+    method public CharSequence? getCustomSubtextMessage();
+    method public int getFlags();
+    method public String getRouteId();
+    method public int getSelectionBehavior();
+    method public int getSubText();
+    field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
+    field public static final int FLAG_ONGOING_SESSION_MANAGED = 2; // 0x2
+    field public static final int FLAG_SUGGESTED = 4; // 0x4
+    field public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2; // 0x2
+    field public static final int SELECTION_BEHAVIOR_NONE = 0; // 0x0
+    field public static final int SELECTION_BEHAVIOR_TRANSFER = 1; // 0x1
+    field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4; // 0x4
+    field public static final int SUBTEXT_CUSTOM = 10000; // 0x2710
+    field public static final int SUBTEXT_DEVICE_LOW_POWER = 5; // 0x5
+    field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3; // 0x3
+    field public static final int SUBTEXT_ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUBTEXT_NONE = 0; // 0x0
+    field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2; // 0x2
+    field public static final int SUBTEXT_TRACK_UNSUPPORTED = 7; // 0x7
+    field public static final int SUBTEXT_UNAUTHORIZED = 6; // 0x6
+  }
+
+  public static final class RouteListingPreference.Item.Builder {
+    ctor public RouteListingPreference.Item.Builder(String);
+    method public androidx.mediarouter.media.RouteListingPreference.Item build();
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setCustomSubtextMessage(CharSequence?);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setFlags(int);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSelectionBehavior(int);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSubText(int);
+  }
+
 }
 
diff --git a/mediarouter/mediarouter/api/restricted_current.txt b/mediarouter/mediarouter/api/restricted_current.txt
index 3fb8c40..00e0b0a 100644
--- a/mediarouter/mediarouter/api/restricted_current.txt
+++ b/mediarouter/mediarouter/api/restricted_current.txt
@@ -170,8 +170,10 @@
     method public android.os.Bundle asBundle();
     method public boolean canDisconnectAndKeepPlaying();
     method public static androidx.mediarouter.media.MediaRouteDescriptor? fromBundle(android.os.Bundle?);
+    method public java.util.Set<java.lang.String!> getAllowedPackages();
     method public int getConnectionState();
     method public java.util.List<android.content.IntentFilter!> getControlFilters();
+    method public java.util.Set<java.lang.String!> getDeduplicationIds();
     method public String? getDescription();
     method public int getDeviceType();
     method public android.os.Bundle? getExtras();
@@ -189,6 +191,7 @@
     method public boolean isDynamicGroupRoute();
     method public boolean isEnabled();
     method public boolean isValid();
+    method public boolean isVisibilityPublic();
   }
 
   public static final class MediaRouteDescriptor.Builder {
@@ -201,6 +204,7 @@
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setCanDisconnect(boolean);
     method @Deprecated public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnecting(boolean);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setConnectionState(int);
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeduplicationIds(java.util.Set<java.lang.String!>);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDescription(String?);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setDeviceType(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setEnabled(boolean);
@@ -213,6 +217,8 @@
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPlaybackType(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setPresentationDisplayId(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setSettingsActivity(android.content.IntentSender?);
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityPublic();
+    method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVisibilityRestricted(java.util.Set<java.lang.String!>);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolume(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeHandling(int);
     method public androidx.mediarouter.media.MediaRouteDescriptor.Builder setVolumeMax(int);
@@ -346,7 +352,7 @@
     method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback);
     method @MainThread public void addCallback(androidx.mediarouter.media.MediaRouteSelector, androidx.mediarouter.media.MediaRouter.Callback, int);
     method @MainThread public void addProvider(androidx.mediarouter.media.MediaRouteProvider);
-    method @MainThread public void addRemoteControlClient(Object);
+    method @Deprecated @MainThread public void addRemoteControlClient(Object);
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo? getBluetoothRoute();
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo getDefaultRoute();
     method @MainThread public static androidx.mediarouter.media.MediaRouter getInstance(android.content.Context);
@@ -363,6 +369,7 @@
     method @MainThread public void setMediaSession(Object?);
     method @MainThread public void setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat?);
     method @MainThread public void setOnPrepareTransferListener(androidx.mediarouter.media.MediaRouter.OnPrepareTransferListener?);
+    method @MainThread public void setRouteListingPreference(androidx.mediarouter.media.RouteListingPreference?);
     method @MainThread public void setRouterParams(androidx.mediarouter.media.MediaRouterParams?);
     method @MainThread public void unselect(int);
     method @MainThread public androidx.mediarouter.media.MediaRouter.RouteInfo updateSelectedRoute(androidx.mediarouter.media.MediaRouteSelector);
@@ -562,5 +569,53 @@
     method public void onSessionStatusChanged(android.os.Bundle?, String, androidx.mediarouter.media.MediaSessionStatus?);
   }
 
+  public final class RouteListingPreference {
+    method public java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!> getItems();
+    method public android.content.ComponentName? getLinkedItemComponentName();
+    method public boolean getUseSystemOrdering();
+    field public static final String ACTION_TRANSFER_MEDIA = "android.media.action.TRANSFER_MEDIA";
+    field public static final String EXTRA_ROUTE_ID = "android.media.extra.ROUTE_ID";
+  }
+
+  public static final class RouteListingPreference.Builder {
+    ctor public RouteListingPreference.Builder();
+    method public androidx.mediarouter.media.RouteListingPreference build();
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setItems(java.util.List<androidx.mediarouter.media.RouteListingPreference.Item!>);
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setLinkedItemComponentName(android.content.ComponentName?);
+    method public androidx.mediarouter.media.RouteListingPreference.Builder setUseSystemOrdering(boolean);
+  }
+
+  public static final class RouteListingPreference.Item {
+    method public CharSequence? getCustomSubtextMessage();
+    method public int getFlags();
+    method public String getRouteId();
+    method public int getSelectionBehavior();
+    method public int getSubText();
+    field public static final int FLAG_ONGOING_SESSION = 1; // 0x1
+    field public static final int FLAG_ONGOING_SESSION_MANAGED = 2; // 0x2
+    field public static final int FLAG_SUGGESTED = 4; // 0x4
+    field public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2; // 0x2
+    field public static final int SELECTION_BEHAVIOR_NONE = 0; // 0x0
+    field public static final int SELECTION_BEHAVIOR_TRANSFER = 1; // 0x1
+    field public static final int SUBTEXT_AD_ROUTING_DISALLOWED = 4; // 0x4
+    field public static final int SUBTEXT_CUSTOM = 10000; // 0x2710
+    field public static final int SUBTEXT_DEVICE_LOW_POWER = 5; // 0x5
+    field public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED = 3; // 0x3
+    field public static final int SUBTEXT_ERROR_UNKNOWN = 1; // 0x1
+    field public static final int SUBTEXT_NONE = 0; // 0x0
+    field public static final int SUBTEXT_SUBSCRIPTION_REQUIRED = 2; // 0x2
+    field public static final int SUBTEXT_TRACK_UNSUPPORTED = 7; // 0x7
+    field public static final int SUBTEXT_UNAUTHORIZED = 6; // 0x6
+  }
+
+  public static final class RouteListingPreference.Item.Builder {
+    ctor public RouteListingPreference.Item.Builder(String);
+    method public androidx.mediarouter.media.RouteListingPreference.Item build();
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setCustomSubtextMessage(CharSequence?);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setFlags(int);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSelectionBehavior(int);
+    method public androidx.mediarouter.media.RouteListingPreference.Item.Builder setSubText(int);
+  }
+
 }
 
diff --git a/mediarouter/mediarouter/build.gradle b/mediarouter/mediarouter/build.gradle
index 100993c..2580725 100644
--- a/mediarouter/mediarouter/build.gradle
+++ b/mediarouter/mediarouter/build.gradle
@@ -25,13 +25,16 @@
     api("androidx.media:media:1.4.1")
     api(libs.guavaListenableFuture)
 
-    // We use a project dependency on androidx.core to keep an up-to-date BuildCompat dependency.
-    // See b/283315121 for context.
-    implementation(project(":core:core"))
+    // We should keep androidx.core up-to-date to keep an up-to-date BuildCompat dependency.
+    // See b/283315121 for context, However we cannot depend on tip of the tree dependency because
+    // it prevents our library releases, so we should update this dependency manually whenever
+    // there is a new stable release of it.
+    implementation("androidx.core:core:1.10.1")
     implementation("androidx.appcompat:appcompat:1.1.0")
     implementation("androidx.palette:palette:1.0.0")
     implementation("androidx.recyclerview:recyclerview:1.1.0")
     implementation("androidx.appcompat:appcompat-resources:1.2.0")
+    implementation "androidx.annotation:annotation-experimental:1.3.0"
 
     testImplementation(libs.junit)
     testImplementation(libs.testCore)
@@ -43,6 +46,7 @@
     androidTestImplementation(libs.testCore)
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.testRules)
+    androidTestImplementation(libs.truth)
     androidTestImplementation(libs.espressoCore, excludes.espresso)
     androidTestImplementation(project(":media:version-compat-tests:lib"))
     androidTestImplementation(project(":mediarouter:mediarouter-testing"))
diff --git a/mediarouter/mediarouter/lint-baseline.xml b/mediarouter/mediarouter/lint-baseline.xml
index fd567a4..8a9547e 100644
--- a/mediarouter/mediarouter/lint-baseline.xml
+++ b/mediarouter/mediarouter/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
 
     <issue
         id="NewApi"
@@ -20,6 +20,51 @@
     </issue>
 
     <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="        ProviderInfo(MediaRouteProvider provider, boolean treatRouteDescriptorIdsAsUnique) {"
+        errorLine2="        ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/MediaRouter.java"/>
+    </issue>
+
+    <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="    android.media.RouteListingPreference toPlatformRouteListingPreference() {"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/RouteListingPreference.java"/>
+    </issue>
+
+    <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="        public @interface SelectionBehavior {}"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/RouteListingPreference.java"/>
+    </issue>
+
+    <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="        public @interface Flags {}"
+        errorLine2="                          ~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/RouteListingPreference.java"/>
+    </issue>
+
+    <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="        public @interface SubText {}"
+        errorLine2="                          ~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/RouteListingPreference.java"/>
+    </issue>
+
+    <issue
         id="BanThreadSleep"
         message="Uses Thread.sleep()"
         errorLine1="        Thread.sleep(TIME_OUT_MS);"
@@ -91,4 +136,40 @@
             file="src/androidTest/java/androidx/mediarouter/media/MediaRouterTest.java"/>
     </issue>
 
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="        if (BuildCompat.isAtLeastU()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/MediaRoute2Provider.java"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            if (mMr2Provider != null &amp;&amp; BuildCompat.isAtLeastU()) {"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/MediaRouter.java"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="        if (BuildCompat.isAtLeastU()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java"/>
+    </issue>
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="        if (BuildCompat.isAtLeastU()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java"/>
+    </issue>
+
 </issues>
diff --git a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouteDescriptorTest.java b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouteDescriptorTest.java
index 504caff..0d3b08c 100644
--- a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouteDescriptorTest.java
+++ b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouteDescriptorTest.java
@@ -17,9 +17,12 @@
 package androidx.mediarouter.media;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 
 import android.content.IntentFilter;
+import android.os.Bundle;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -28,7 +31,9 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Test for {@link MediaRouteDescriptor}.
@@ -43,6 +48,7 @@
     private static final String FAKE_MEDIA_ROUTE_ID_4 = "fakeMediaRouteId4";
     private static final String FAKE_CONTROL_ACTION_1 = "fakeControlAction1";
     private static final String FAKE_CONTROL_ACTION_2 = "fakeControlAction2";
+    private static final String FAKE_PACKAGE_NAME = "com.sample.example";
 
     @Test
     @SmallTest
@@ -102,4 +108,114 @@
         final List<IntentFilter> controlFilters2 = routeDescriptor.getControlFilters();
         assertTrue(controlFilters2.isEmpty());
     }
+
+    @Test
+    @SmallTest
+    public void testDefaultVisibilityIsPublic() {
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
+                FAKE_MEDIA_ROUTE_ID_1, FAKE_MEDIA_ROUTE_NAME)
+                .build();
+
+        assertTrue(routeDescriptor.isVisibilityPublic());
+    }
+
+    @Test
+    @SmallTest
+    public void testIsVisibilityRestricted() {
+        Set<String> allowedPackages = new HashSet<>();
+        allowedPackages.add(FAKE_PACKAGE_NAME);
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
+                FAKE_MEDIA_ROUTE_ID_1, FAKE_MEDIA_ROUTE_NAME)
+                .setVisibilityRestricted(allowedPackages)
+                .build();
+
+        assertFalse(routeDescriptor.isVisibilityPublic());
+    }
+
+    @Test
+    @SmallTest
+    public void testGetAllowedPackagesReturnsNewInstance() {
+        Set<String> sampleAllowedPackages = new HashSet<>();
+        sampleAllowedPackages.add(FAKE_PACKAGE_NAME);
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
+                FAKE_MEDIA_ROUTE_ID_1, FAKE_MEDIA_ROUTE_NAME)
+                .setVisibilityRestricted(sampleAllowedPackages)
+                .build();
+
+        Set<String> allowedPackages = routeDescriptor.getAllowedPackages();
+
+        assertEquals(sampleAllowedPackages, allowedPackages);
+        assertNotSame(sampleAllowedPackages, allowedPackages);
+    }
+
+    @Test
+    @SmallTest
+    public void testGetControlFiltersReturnsNewInstance() {
+        IntentFilter f1 = new IntentFilter();
+        f1.addCategory("com.example.androidx.media.CATEGORY_SAMPLE_ROUTE");
+        f1.addAction("com.example.androidx.media.action.TAKE_SNAPSHOT");
+
+        IntentFilter f2 = new IntentFilter();
+        f2.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+        f2.addAction(MediaControlIntent.ACTION_PLAY);
+        f2.addDataScheme("http");
+        f2.addDataScheme("https");
+        f2.addDataScheme("rtsp");
+        f2.addDataScheme("file");
+
+        IntentFilter f3 = new IntentFilter();
+        f3.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+        f3.addAction(MediaControlIntent.ACTION_SEEK);
+        f3.addAction(MediaControlIntent.ACTION_GET_STATUS);
+        f3.addAction(MediaControlIntent.ACTION_PAUSE);
+        f3.addAction(MediaControlIntent.ACTION_RESUME);
+        f3.addAction(MediaControlIntent.ACTION_STOP);
+
+        List<IntentFilter> sampleControlFilters = new ArrayList<>();
+        sampleControlFilters.add(f1);
+        sampleControlFilters.add(f2);
+        sampleControlFilters.add(f3);
+
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
+                FAKE_MEDIA_ROUTE_ID_1, FAKE_MEDIA_ROUTE_NAME)
+                .addControlFilter(f1)
+                .addControlFilter(f2)
+                .addControlFilter(f3)
+                .build();
+
+        List<IntentFilter> controlFilters = routeDescriptor.getControlFilters();
+
+        assertEquals(sampleControlFilters, controlFilters);
+        assertNotSame(sampleControlFilters, controlFilters);
+    }
+
+    @Test
+    @SmallTest
+    public void testGetGroupMemberIdsReturnsNewInstance() {
+        List<String> sampleGroupMemberIds = new ArrayList<>();
+        sampleGroupMemberIds.add(FAKE_MEDIA_ROUTE_ID_2);
+        sampleGroupMemberIds.add(FAKE_MEDIA_ROUTE_ID_3);
+        sampleGroupMemberIds.add(FAKE_MEDIA_ROUTE_ID_4);
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor.Builder(
+                FAKE_MEDIA_ROUTE_ID_1, FAKE_MEDIA_ROUTE_NAME)
+                .addGroupMemberId(FAKE_MEDIA_ROUTE_ID_2)
+                .addGroupMemberId(FAKE_MEDIA_ROUTE_ID_3)
+                .addGroupMemberId(FAKE_MEDIA_ROUTE_ID_4)
+                .build();
+
+        List<String> groupMemberIds = routeDescriptor.getGroupMemberIds();
+
+        assertEquals(sampleGroupMemberIds, groupMemberIds);
+        assertNotSame(sampleGroupMemberIds, groupMemberIds);
+    }
+
+    @Test
+    @SmallTest
+    public void testConstructorUsingBundleReturnsEmptyCollections() {
+        MediaRouteDescriptor routeDescriptor = new MediaRouteDescriptor(new Bundle());
+
+        assertTrue(routeDescriptor.getAllowedPackages().isEmpty());
+        assertTrue(routeDescriptor.getControlFilters().isEmpty());
+        assertTrue(routeDescriptor.getGroupMemberIds().isEmpty());
+    }
 }
diff --git a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2UtilsTest.java b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2UtilsTest.java
index ae769ed..776a596 100644
--- a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2UtilsTest.java
+++ b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/MediaRouter2UtilsTest.java
@@ -16,11 +16,17 @@
 
 package androidx.mediarouter.media;
 
+import static androidx.mediarouter.media.MediaRouter2Utils.KEY_CONTROL_FILTERS;
+import static androidx.mediarouter.media.MediaRouter2Utils.KEY_DEVICE_TYPE;
+import static androidx.mediarouter.media.MediaRouter2Utils.KEY_EXTRAS;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.media.MediaRoute2Info;
 import android.os.Build;
+import android.os.Bundle;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SdkSuppress;
@@ -29,6 +35,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+
 /** Test for {@link MediaRouter2Utils}. */
 @SmallTest
 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.R)
@@ -37,6 +46,19 @@
 
     private static final String FAKE_MEDIA_ROUTE_DESCRIPTOR_ID = "fake_id";
     private static final String FAKE_MEDIA_ROUTE_DESCRIPTOR_NAME = "fake_name";
+    /**
+     * Placeholder bundle for {@link MediaRouter2Utils#toMediaRouteDescriptor} to accept passed
+     * {@link MediaRoute2Info} instances as valid.
+     */
+    private static final Bundle PLACEHOLDER_EXTRAS_BUNDLE;
+
+    static {
+        PLACEHOLDER_EXTRAS_BUNDLE = new Bundle();
+        PLACEHOLDER_EXTRAS_BUNDLE.putBundle(KEY_EXTRAS, new Bundle());
+        PLACEHOLDER_EXTRAS_BUNDLE.putInt(
+                KEY_DEVICE_TYPE, MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN);
+        PLACEHOLDER_EXTRAS_BUNDLE.putParcelableArrayList(KEY_CONTROL_FILTERS, new ArrayList<>());
+    }
 
     @Test
     public void toFwkMediaRoute2Info_withValidDescriptor_returnsInstance() {
@@ -60,4 +82,70 @@
                         .build();
         assertNull(MediaRouter2Utils.toFwkMediaRoute2Info(descriptorWithEmptyName));
     }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    @Test
+    public void toFwkMediaRoute2Info_withDeduplicationIds() {
+        HashSet<String> dedupIds = new HashSet<>();
+        dedupIds.add("dedup_id1");
+        dedupIds.add("dedup_id2");
+        MediaRouteDescriptor descriptor =
+                new MediaRouteDescriptor.Builder(
+                                FAKE_MEDIA_ROUTE_DESCRIPTOR_ID, FAKE_MEDIA_ROUTE_DESCRIPTOR_NAME)
+                        .setDeduplicationIds(dedupIds)
+                        .build();
+        assertTrue(
+                MediaRouter2Utils.toFwkMediaRoute2Info(descriptor)
+                        .getDeduplicationIds()
+                        .equals(dedupIds));
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    @Test
+    public void toMediaRouteDescriptor_withDeduplicationIds() {
+        HashSet<String> dedupIds = new HashSet<>();
+        dedupIds.add("dedup_id1");
+        dedupIds.add("dedup_id2");
+
+        MediaRoute2Info routeInfo =
+                new MediaRoute2Info.Builder(
+                                FAKE_MEDIA_ROUTE_DESCRIPTOR_ID, FAKE_MEDIA_ROUTE_DESCRIPTOR_NAME)
+                        .addFeature(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
+                        .setDeduplicationIds(dedupIds)
+                        .setExtras(PLACEHOLDER_EXTRAS_BUNDLE)
+                        .build();
+        assertTrue(
+                MediaRouter2Utils.toMediaRouteDescriptor(routeInfo)
+                        .getDeduplicationIds()
+                        .equals(dedupIds));
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    @Test
+    public void toMediaRouteDescriptor_withDeviceType_setsCorrectType() {
+        MediaRoute2Info routeInfo =
+                new MediaRoute2Info.Builder(
+                                FAKE_MEDIA_ROUTE_DESCRIPTOR_ID, FAKE_MEDIA_ROUTE_DESCRIPTOR_NAME)
+                        .addFeature(MediaRoute2Info.FEATURE_REMOTE_PLAYBACK)
+                        .setType(MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER)
+                        .setExtras(PLACEHOLDER_EXTRAS_BUNDLE)
+                        .build();
+
+        assertEquals(
+                MediaRouter.RouteInfo.DEVICE_TYPE_AUDIO_VIDEO_RECEIVER,
+                MediaRouter2Utils.toMediaRouteDescriptor(routeInfo).getDeviceType());
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    @Test
+    public void toFwkMediaRoute2Info_withType_setsCorrectDeviceType() {
+        MediaRouteDescriptor descriptor =
+                new MediaRouteDescriptor.Builder(
+                                FAKE_MEDIA_ROUTE_DESCRIPTOR_ID, FAKE_MEDIA_ROUTE_DESCRIPTOR_NAME)
+                        .setDeviceType(MediaRouter.RouteInfo.DEVICE_TYPE_TV)
+                        .build();
+        assertEquals(
+                MediaRoute2Info.TYPE_REMOTE_TV,
+                MediaRouter2Utils.toFwkMediaRoute2Info(descriptor).getType());
+    }
 }
diff --git a/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/RouteListingPreferenceTest.java b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/RouteListingPreferenceTest.java
new file mode 100644
index 0000000..e99c4e9
--- /dev/null
+++ b/mediarouter/mediarouter/src/androidTest/java/androidx/mediarouter/media/RouteListingPreferenceTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.mediarouter.media;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Build;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(AndroidJUnit4.class)
+public class RouteListingPreferenceTest {
+
+    private static final String FAKE_ROUTE_ID = "fake_id";
+    private static final String FAKE_CUSTOM_SUBTEXT = "a custom subtext";
+    private static final ComponentName FAKE_COMPONENT_NAME =
+            new ComponentName(
+                    ApplicationProvider.getApplicationContext(), RouteListingPreferenceTest.class);
+
+    private Context mContext;
+    private MediaRouter mMediaRouterUnderTest;
+
+    @Before
+    public void setUp() {
+        mContext = ApplicationProvider.getApplicationContext();
+        InstrumentationRegistry.getInstrumentation()
+                .runOnMainSync(() -> mMediaRouterUnderTest = MediaRouter.getInstance(mContext));
+    }
+
+    @After
+    public void tearDown() {
+        InstrumentationRegistry.getInstrumentation()
+                .runOnMainSync(
+                        () ->
+                                mMediaRouterUnderTest.setRouteListingPreference(
+                                        /* routeListingPreference= */ null));
+    }
+
+    @SmallTest
+    @Test
+    public void setRouteListingPreference_onAnyApiLevel_doesNotCrash() {
+        // AndroidX infra runs tests on all API levels with significant usage, hence this test
+        // checks this call does not crash regardless of whether route listing preference symbols
+        // are defined on the current platform level.
+        InstrumentationRegistry.getInstrumentation()
+                .runOnMainSync(
+                        () ->
+                                mMediaRouterUnderTest.setRouteListingPreference(
+                                        new RouteListingPreference.Builder().build()));
+    }
+
+    @SmallTest
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    public void routeListingPreference_yieldsExpectedPlatformEquivalent() {
+        RouteListingPreference.Item fakeRlpItem =
+                new RouteListingPreference.Item.Builder(FAKE_ROUTE_ID)
+                        .setFlags(RouteListingPreference.Item.FLAG_SUGGESTED)
+                        .setSubText(RouteListingPreference.Item.SUBTEXT_CUSTOM)
+                        .setCustomSubtextMessage(FAKE_CUSTOM_SUBTEXT)
+                        .setSelectionBehavior(
+                                RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP)
+                        .build();
+        RouteListingPreference fakeRouteListingPreference =
+                new RouteListingPreference.Builder()
+                        .setItems(Collections.singletonList(fakeRlpItem))
+                        .setLinkedItemComponentName(FAKE_COMPONENT_NAME)
+                        .setUseSystemOrdering(false)
+                        .build();
+        android.media.RouteListingPreference platformRlp =
+                fakeRouteListingPreference.toPlatformRouteListingPreference();
+
+        assertThat(platformRlp.getUseSystemOrdering()).isFalse();
+        assertThat(platformRlp.getLinkedItemComponentName()).isEqualTo(FAKE_COMPONENT_NAME);
+
+        List<android.media.RouteListingPreference.Item> platformRlpItems = platformRlp.getItems();
+        assertThat(platformRlpItems).hasSize(1);
+        android.media.RouteListingPreference.Item platformRlpItem = platformRlpItems.get(0);
+        assertThat(platformRlpItem.getRouteId()).isEqualTo(FAKE_ROUTE_ID);
+        assertThat(platformRlpItem.getFlags())
+                .isEqualTo(RouteListingPreference.Item.FLAG_SUGGESTED);
+        assertThat(platformRlpItem.getSelectionBehavior())
+                .isEqualTo(RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP);
+        assertThat(platformRlpItem.getSubText())
+                .isEqualTo(android.media.RouteListingPreference.Item.SUBTEXT_CUSTOM);
+        assertThat(platformRlpItem.getCustomSubtextMessage()).isEqualTo(FAKE_CUSTOM_SUBTEXT);
+    }
+}
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/SystemOutputSwitcherDialogController.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/SystemOutputSwitcherDialogController.java
index 9782159..3e74545 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/SystemOutputSwitcherDialogController.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/SystemOutputSwitcherDialogController.java
@@ -22,10 +22,13 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.media.MediaRouter2;
 import android.os.Build;
 import android.provider.Settings;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 
 import java.util.List;
 
@@ -77,8 +80,10 @@
     public static boolean showDialog(@NonNull Context context) {
         boolean result = false;
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
-            result = showDialogForAndroidSAndAbove(context)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            result = showDialogForAndroidUAndAbove(context);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            result = showDialogForAndroidSAndT(context)
                     // The intent action and related string constants are changed in S,
                     // however they are not public API yet. Try opening the output switcher with the
                     // old constants for devices that have prior version of the constants.
@@ -98,7 +103,18 @@
         return false;
     }
 
-    private static boolean showDialogForAndroidSAndAbove(@NonNull Context context) {
+    private static boolean showDialogForAndroidUAndAbove(@NonNull Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+            MediaRouter2 mediaRouter2 = Api30Impl.getInstance(context);
+            if (Build.VERSION.SDK_INT >= 34) {
+                return Api34Impl.showSystemOutputSwitcher(mediaRouter2);
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean showDialogForAndroidSAndT(@NonNull Context context) {
         Intent intent = new Intent()
                 .setAction(OUTPUT_SWITCHER_INTENT_ACTION_ANDROID_S)
                 .setPackage(PACKAGE_NAME_SYSTEM_UI)
@@ -182,4 +198,28 @@
         PackageManager packageManager = context.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH);
     }
+
+    @RequiresApi(30)
+    static class Api30Impl {
+        private Api30Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static MediaRouter2 getInstance(Context context) {
+            return MediaRouter2.getInstance(context);
+        }
+    }
+
+    @RequiresApi(34)
+    static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static boolean showSystemOutputSwitcher(MediaRouter2 mediaRouter2) {
+            return mediaRouter2.showSystemOutputSwitcher();
+        }
+    }
 }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRoute2Provider.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRoute2Provider.java
index e77626e..f41e069 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRoute2Provider.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRoute2Provider.java
@@ -44,9 +44,12 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
 import androidx.annotation.RequiresApi;
+import androidx.core.os.BuildCompat;
 import androidx.mediarouter.R;
 import androidx.mediarouter.media.MediaRouteProvider.DynamicGroupRouteController.DynamicRouteDescriptor;
 import androidx.mediarouter.media.MediaRouter.ControlRequestCallback;
@@ -72,7 +75,7 @@
     final Callback mCallback;
     final Map<MediaRouter2.RoutingController, GroupRouteController> mControllerMap =
             new ArrayMap<>();
-    private final MediaRouter2.RouteCallback mRouteCallback = new RouteCallback();
+    private final MediaRouter2.RouteCallback mRouteCallback;
     private final MediaRouter2.TransferCallback mTransferCallback = new TransferCallback();
     private final MediaRouter2.ControllerCallback mControllerCallback = new ControllerCallback();
     private final Handler mHandler;
@@ -81,6 +84,8 @@
     private List<MediaRoute2Info> mRoutes = new ArrayList<>();
     private Map<String, String> mRouteIdToOriginalRouteIdMap = new ArrayMap<>();
 
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @SuppressWarnings({"SyntheticAccessor"})
     MediaRoute2Provider(@NonNull Context context, @NonNull Callback callback) {
         super(context);
         mMediaRouter2 = MediaRouter2.getInstance(context);
@@ -88,6 +93,12 @@
 
         mHandler = new Handler(Looper.getMainLooper());
         mHandlerExecutor = mHandler::post;
+
+        if (BuildCompat.isAtLeastU()) {
+            mRouteCallback = new RouteCallbackUpsideDownCake();
+        } else {
+            mRouteCallback = new RouteCallback();
+        }
     }
 
     @Override
@@ -353,6 +364,16 @@
         return new MediaRouteDiscoveryRequest(selector, request.isActiveScan());
     }
 
+    @RequiresApi(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    /* package */ void setRouteListingPreference(
+            @Nullable RouteListingPreference routeListingPreference) {
+        Api34Impl.setPlatformRouteListingPreference(
+                mMediaRouter2,
+                routeListingPreference != null
+                        ? routeListingPreference.toPlatformRouteListingPreference()
+                        : null);
+    }
+
     abstract static class Callback {
         public abstract void onSelectRoute(@NonNull String routeDescriptorId,
                 @MediaRouter.UnselectReason int reason);
@@ -380,6 +401,14 @@
         }
     }
 
+    private class RouteCallbackUpsideDownCake extends MediaRouter2.RouteCallback {
+
+        @Override
+        public void onRoutesUpdated(@NonNull List<MediaRoute2Info> routes) {
+            refreshRoutes();
+        }
+    }
+
     private class TransferCallback extends MediaRouter2.TransferCallback {
         TransferCallback() {}
 
@@ -695,4 +724,18 @@
             }
         }
     }
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static void setPlatformRouteListingPreference(
+                @NonNull MediaRouter2 mediaRouter2,
+                @Nullable android.media.RouteListingPreference routeListingPreference) {
+            mediaRouter2.setRouteListingPreference(routeListingPreference);
+        }
+    }
 }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouteDescriptor.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouteDescriptor.java
index a202f44..e053d4f 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouteDescriptor.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouteDescriptor.java
@@ -17,8 +17,10 @@
 
 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 
+import android.annotation.SuppressLint;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.media.RouteDiscoveryPreference;
 import android.net.Uri;
 import android.os.Bundle;
 import android.text.TextUtils;
@@ -31,7 +33,9 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Describes the properties of a route.
@@ -65,10 +69,11 @@
     static final String KEY_SETTINGS_INTENT = "settingsIntent";
     static final String KEY_MIN_CLIENT_VERSION = "minClientVersion";
     static final String KEY_MAX_CLIENT_VERSION = "maxClientVersion";
+    static final String KEY_DEDUPLICATION_IDS = "deduplicationIds";
+    static final String KEY_IS_VISIBILITY_PUBLIC = "isVisibilityPublic";
+    static final String KEY_ALLOWED_PACKAGES = "allowedPackages";
 
     final Bundle mBundle;
-    List<String> mGroupMemberIds;
-    List<IntentFilter> mControlFilters;
 
     MediaRouteDescriptor(Bundle bundle) {
         mBundle = bundle;
@@ -97,17 +102,10 @@
     @RestrictTo(LIBRARY)
     @NonNull
     public List<String> getGroupMemberIds() {
-        ensureGroupMemberIds();
-        return mGroupMemberIds;
-    }
-
-    void ensureGroupMemberIds() {
-        if (mGroupMemberIds == null) {
-            mGroupMemberIds = mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS);
-            if (mGroupMemberIds == null) {
-                mGroupMemberIds = Collections.emptyList();
-            }
+        if (!mBundle.containsKey(KEY_GROUP_MEMBER_IDS)) {
+            return new ArrayList<>();
         }
+        return new ArrayList<>(mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS));
     }
 
     /**
@@ -229,17 +227,10 @@
      */
     @NonNull
     public List<IntentFilter> getControlFilters() {
-        ensureControlFilters();
-        return mControlFilters;
-    }
-
-    void ensureControlFilters() {
-        if (mControlFilters == null) {
-            mControlFilters = mBundle.getParcelableArrayList(KEY_CONTROL_FILTERS);
-            if (mControlFilters == null) {
-                mControlFilters = Collections.emptyList();
-            }
+        if (!mBundle.containsKey(KEY_CONTROL_FILTERS)) {
+            return new ArrayList<>();
         }
+        return new ArrayList<>(mBundle.getParcelableArrayList(KEY_CONTROL_FILTERS));
     }
 
     /**
@@ -297,6 +288,20 @@
     }
 
     /**
+     * Gets the route's deduplication ids.
+     *
+     * <p>Two routes are considered to come from the same receiver device if any of their respective
+     * deduplication ids match.
+     */
+    @NonNull
+    public Set<String> getDeduplicationIds() {
+        ArrayList<String> deduplicationIds = mBundle.getStringArrayList(KEY_DEDUPLICATION_IDS);
+        return deduplicationIds != null
+                ? Collections.unmodifiableSet(new HashSet<>(deduplicationIds))
+                : Collections.emptySet();
+    }
+
+    /**
      * Gets the route's presentation display id, or -1 if none.
      */
     public int getPresentationDisplayId() {
@@ -332,13 +337,32 @@
     }
 
     /**
+     * Gets whether the route visibility is public or not.
+     */
+    public boolean isVisibilityPublic() {
+        return mBundle.getBoolean(KEY_IS_VISIBILITY_PUBLIC, /* defaultValue= */ true);
+    }
+
+    /**
+     * Gets the set of allowed packages which are able to see the route or an empty set if only
+     * the route provider's package is allowed to see this route. This applies only when
+     * {@link #isVisibilityPublic} returns {@code false}.
+     */
+    @NonNull
+    public Set<String> getAllowedPackages() {
+        if (!mBundle.containsKey(KEY_ALLOWED_PACKAGES)) {
+            return new HashSet<>();
+        }
+        return new HashSet<>(mBundle.getStringArrayList(KEY_ALLOWED_PACKAGES));
+    }
+
+    /**
      * Returns true if the route descriptor has all of the required fields.
      */
     public boolean isValid() {
-        ensureControlFilters();
         if (TextUtils.isEmpty(getId())
                 || TextUtils.isEmpty(getName())
-                || mControlFilters.contains(null)) {
+                || getControlFilters().contains(null)) {
             return false;
         }
         return true;
@@ -367,6 +391,8 @@
                 + ", isValid=" + isValid()
                 + ", minClientVersion=" + getMinClientVersion()
                 + ", maxClientVersion=" + getMaxClientVersion()
+                + ", isVisibilityPublic=" + isVisibilityPublic()
+                + ", allowedPackages=" + Arrays.toString(getAllowedPackages().toArray())
                 + " }";
     }
 
@@ -396,8 +422,10 @@
      */
     public static final class Builder {
         private final Bundle mBundle;
-        private ArrayList<String> mGroupMemberIds;
-        private ArrayList<IntentFilter> mControlFilters;
+
+        private List<String> mGroupMemberIds = new ArrayList<>();
+        private List<IntentFilter> mControlFilters = new ArrayList<>();
+        private Set<String> mAllowedPackages = new HashSet<>();
 
         /**
          * Creates a media route descriptor builder.
@@ -422,13 +450,9 @@
 
             mBundle = new Bundle(descriptor.mBundle);
 
-            if (!descriptor.getGroupMemberIds().isEmpty()) {
-                mGroupMemberIds = new ArrayList<String>(descriptor.getGroupMemberIds());
-            }
-
-            if (!descriptor.getControlFilters().isEmpty()) {
-                mControlFilters = new ArrayList<IntentFilter>(descriptor.mControlFilters);
-            }
+            mGroupMemberIds = descriptor.getGroupMemberIds();
+            mControlFilters = descriptor.getControlFilters();
+            mAllowedPackages = descriptor.getAllowedPackages();
         }
 
         /**
@@ -454,9 +478,7 @@
         @RestrictTo(LIBRARY)
         @NonNull
         public Builder clearGroupMemberIds() {
-            if (mGroupMemberIds != null) {
-                mGroupMemberIds.clear();
-            }
+            mGroupMemberIds.clear();
             return this;
         }
 
@@ -474,9 +496,6 @@
                 throw new IllegalArgumentException("groupMemberId must not be empty");
             }
 
-            if (mGroupMemberIds == null) {
-                mGroupMemberIds = new ArrayList<>();
-            }
             if (!mGroupMemberIds.contains(groupMemberId)) {
                 mGroupMemberIds.add(groupMemberId);
             }
@@ -518,10 +537,7 @@
             if (TextUtils.isEmpty(memberRouteId)) {
                 throw new IllegalArgumentException("memberRouteId must not be empty");
             }
-
-            if (mGroupMemberIds != null) {
-                mGroupMemberIds.remove(memberRouteId);
-            }
+            mGroupMemberIds.remove(memberRouteId);
             return this;
         }
 
@@ -599,6 +615,7 @@
             mBundle.putBoolean(IS_DYNAMIC_GROUP_ROUTE, isDynamicGroupRoute);
             return this;
         }
+
         /**
          * Sets whether the route is in the process of connecting and is not yet
          * ready for use.
@@ -649,9 +666,7 @@
          */
         @NonNull
         public Builder clearControlFilters() {
-            if (mControlFilters != null) {
-                mControlFilters.clear();
-            }
+            mControlFilters.clear();
             return this;
         }
 
@@ -664,9 +679,6 @@
                 throw new IllegalArgumentException("filter must not be null");
             }
 
-            if (mControlFilters == null) {
-                mControlFilters = new ArrayList<IntentFilter>();
-            }
             if (!mControlFilters.contains(filter)) {
                 mControlFilters.add(filter);
             }
@@ -757,6 +769,21 @@
         }
 
         /**
+         * Sets the route's deduplication ids.
+         *
+         * <p>Two routes are considered to come from the same receiver device if any of their
+         * respective deduplication ids match.
+         *
+         * @param deduplicationIds A set of strings that uniquely identify the receiver device that
+         *     backs this route.
+         */
+        @NonNull
+        public Builder setDeduplicationIds(@NonNull Set<String> deduplicationIds) {
+            mBundle.putStringArrayList(KEY_DEDUPLICATION_IDS, new ArrayList<>(deduplicationIds));
+            return this;
+        }
+
+        /**
          * Sets the route's presentation display id, or -1 if none.
          */
         @NonNull
@@ -803,16 +830,54 @@
         }
 
         /**
+         * Sets the visibility of this route to public.
+         *
+         * <p>By default, unless you call {@link #setVisibilityRestricted}, the new route will be
+         * public.
+         *
+         * <p>Public routes are visible to any application with a matching {@link
+         * RouteDiscoveryPreference#getPreferredFeatures feature}.
+         *
+         * <p>Calls to this method override previous calls to {@link #setVisibilityPublic} and
+         * {@link #setVisibilityRestricted}.
+         */
+        @NonNull
+        @SuppressLint({"MissingGetterMatchingBuilder"})
+        public Builder setVisibilityPublic() {
+            mBundle.putBoolean(KEY_IS_VISIBILITY_PUBLIC, true);
+            mAllowedPackages.clear();
+            return this;
+        }
+
+        /**
+         * Sets the visibility of this route to restricted.
+         *
+         * <p>Routes with restricted visibility are only visible to its publisher application and
+         * applications whose package name is included in the provided {@code allowedPackages} set
+         * with a matching {@link RouteDiscoveryPreference#getPreferredFeatures feature}.
+         *
+         * <p>Calls to this method override previous calls to {@link #setVisibilityPublic} and
+         * {@link #setVisibilityRestricted}.
+         *
+         * @see #setVisibilityPublic
+         * @param allowedPackages set of package names which are allowed to see this route.
+         */
+        @NonNull
+        @SuppressLint({"MissingGetterMatchingBuilder"})
+        public Builder setVisibilityRestricted(@NonNull Set<String> allowedPackages) {
+            mBundle.putBoolean(KEY_IS_VISIBILITY_PUBLIC, false);
+            mAllowedPackages = new HashSet<>(allowedPackages);
+            return this;
+        }
+
+        /**
          * Builds the {@link MediaRouteDescriptor media route descriptor}.
          */
         @NonNull
         public MediaRouteDescriptor build() {
-            if (mControlFilters != null) {
-                mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, mControlFilters);
-            }
-            if (mGroupMemberIds != null) {
-                mBundle.putStringArrayList(KEY_GROUP_MEMBER_IDS, mGroupMemberIds);
-            }
+            mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, new ArrayList<>(mControlFilters));
+            mBundle.putStringArrayList(KEY_GROUP_MEMBER_IDS, new ArrayList<>(mGroupMemberIds));
+            mBundle.putStringArrayList(KEY_ALLOWED_PACKAGES, new ArrayList<>(mAllowedPackages));
             return new MediaRouteDescriptor(mBundle);
         }
     }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
index dd04930..76f4fba 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter.java
@@ -899,19 +899,19 @@
     }
 
     /**
-     * Adds a remote control client to enable remote control of the volume
-     * of the selected route.
-     * <p>
-     * The remote control client must have previously been registered with
-     * the audio manager using the {@link android.media.AudioManager#registerRemoteControlClient
+     * Adds a remote control client to enable remote control of the volume of the selected route.
+     *
+     * <p>The remote control client must have previously been registered with the audio manager
+     * using the {@link android.media.AudioManager#registerRemoteControlClient
      * AudioManager.registerRemoteControlClient} method.
-     * </p>
      *
      * <p>Must be called on the main thread.
      *
      * @param remoteControlClient The {@link android.media.RemoteControlClient} to register.
+     * @deprecated Use {@link #setMediaSessionCompat} instead.
      */
     @MainThread
+    @Deprecated
     public void addRemoteControlClient(@NonNull Object remoteControlClient) {
         if (remoteControlClient == null) {
             throw new IllegalArgumentException("remoteControlClient must not be null");
@@ -946,14 +946,8 @@
     }
 
     /**
-     * Sets the media session to enable remote control of the volume of the
-     * selected route. This should be used instead of
-     * {@link #addRemoteControlClient} when using media sessions. Set the
-     * session to null to clear it.
-     *
-     * <p>Must be called on the main thread.
-     *
-     * @param mediaSession The {@link android.media.session.MediaSession} to use.
+     * Equivalent to {@link #setMediaSessionCompat}, except it takes an {@link
+     * android.media.session.MediaSession}.
      */
     @MainThread
     public void setMediaSession(@Nullable Object mediaSession) {
@@ -965,14 +959,16 @@
     }
 
     /**
-     * Sets a compat media session to enable remote control of the volume of the
-     * selected route. This should be used instead of
-     * {@link #addRemoteControlClient} when using {@link MediaSessionCompat}.
-     * Set the session to null to clear it.
+     * Associates the provided {@link MediaSessionCompat} to this router.
+     *
+     * <p>Maintains the internal state of the provided session to signal it's linked to the
+     * currently selected route at any given time. This guarantees that the system UI shows the
+     * correct route name when applicable.
      *
      * <p>Must be called on the main thread.
      *
-     * @param mediaSession The {@link MediaSessionCompat} to use.
+     * @param mediaSession The {@link MediaSessionCompat} to associate to this media router, or null
+     *     to clear the existing association.
      */
     @MainThread
     public void setMediaSessionCompat(@Nullable MediaSessionCompat mediaSession) {
@@ -1018,6 +1014,41 @@
     }
 
     /**
+     * Sets the {@link RouteListingPreference} of the app associated to this media router.
+     *
+     * <p>This method does nothing on devices running API 33 or older.
+     *
+     * <p>Use this method to inform the system UI of the routes that you would like to list for
+     * media routing, via the Output Switcher.
+     *
+     * <p>You should call this method immediately after creating an instance and immediately after
+     * receiving any {@link Callback route list changes} in order to keep the system UI in a
+     * consistent state. You can also call this method at any other point to update the listing
+     * preference dynamically (which reflect in the system's Output Switcher).
+     *
+     * <p>Notes:
+     *
+     * <ul>
+     *   <li>You should not include the ids of two or more routes with a match in their {@link
+     *       MediaRouteDescriptor#getDeduplicationIds() deduplication ids}. If you do, the system
+     *       will deduplicate them using its own criteria.
+     *   <li>You can use this method to rank routes in the output switcher, placing the more
+     *       important routes first. The system might override the proposed ranking.
+     *   <li>You can use this method to change how routes are listed using dynamic criteria. For
+     *       example, you can disable routing while an {@link
+     *       RouteListingPreference.Item#SUBTEXT_AD_ROUTING_DISALLOWED ad is playing}).
+     * </ul>
+     *
+     * @param routeListingPreference The {@link RouteListingPreference} for the system to use for
+     *     route listing. When null, the system uses its default listing criteria.
+     */
+    @MainThread
+    public void setRouteListingPreference(@Nullable RouteListingPreference routeListingPreference) {
+        checkCallingThread();
+        getGlobalRouter().setRouteListingPreference(routeListingPreference);
+    }
+
+    /**
      * Throws an {@link IllegalStateException} if the calling thread is not the main thread.
      */
     static void checkCallingThread() {
@@ -2194,15 +2225,23 @@
      * </p>
      */
     public static final class ProviderInfo {
+        // Package private fields to avoid use of a synthetic accessor.
         final MediaRouteProvider mProviderInstance;
         final List<RouteInfo> mRoutes = new ArrayList<>();
+        final boolean mTreatRouteDescriptorIdsAsUnique;
 
         private final ProviderMetadata mMetadata;
         private MediaRouteProviderDescriptor mDescriptor;
 
         ProviderInfo(MediaRouteProvider provider) {
+            this(provider, /* treatRouteDescriptorIdsAsUnique= */ false);
+        }
+
+        /** @hide */
+        ProviderInfo(MediaRouteProvider provider, boolean treatRouteDescriptorIdsAsUnique) {
             mProviderInstance = provider;
             mMetadata = provider.getMetadata();
+            mTreatRouteDescriptorIdsAsUnique = treatRouteDescriptorIdsAsUnique;
         }
 
         /**
@@ -2675,9 +2714,9 @@
                             updateDiscoveryRequest();
                         }
                     });
-            addProvider(mSystemProvider);
+            addProvider(mSystemProvider, /* treatRouteDescriptorIdsAsUnique= */ true);
             if (mMr2Provider != null) {
-                addProvider(mMr2Provider);
+                addProvider(mMr2Provider, /* treatRouteDescriptorIdsAsUnique= */ true);
             }
 
             // Start watching for routes published by registered media route
@@ -2694,6 +2733,8 @@
             mRegisteredProviderWatcher.stop();
             mActiveScanThrottlingHelper.reset();
 
+            setRouteListingPreference(null);
+
             setMediaSessionCompat(null);
             for (RemoteControlClientRecord record : mRemoteControlClients) {
                 record.disconnect();
@@ -2812,7 +2853,7 @@
                 if (mMr2Provider == null) {
                     mMr2Provider = new MediaRoute2Provider(
                             mApplicationContext, new Mr2ProviderCallback());
-                    addProvider(mMr2Provider);
+                    addProvider(mMr2Provider, /* treatRouteDescriptorIdsAsUnique= */ true);
                     // Make sure mDiscoveryRequestForMr2Provider is updated
                     updateDiscoveryRequest();
                     mRegisteredProviderWatcher.rescan();
@@ -2838,6 +2879,14 @@
             mCallbackHandler.post(CallbackHandler.MSG_ROUTER_PARAMS_CHANGED, params);
         }
 
+        public void setRouteListingPreference(
+                @Nullable RouteListingPreference routeListingPreference) {
+            if (mMr2Provider != null
+                    && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                mMr2Provider.setRouteListingPreference(routeListingPreference);
+            }
+        }
+
         @Nullable
         List<ProviderInfo> getProviders() {
             return mProviders;
@@ -3120,12 +3169,18 @@
                             MediaRouterParams.ENABLE_GROUP_VOLUME_UX, true);
         }
 
-
         @Override
         public void addProvider(@NonNull MediaRouteProvider providerInstance) {
+            addProvider(providerInstance, /* treatRouteDescriptorIdsAsUnique= */ false);
+        }
+
+        private void addProvider(
+                @NonNull MediaRouteProvider providerInstance,
+                boolean treatRouteDescriptorIdsAsUnique) {
             if (findProviderInfo(providerInstance) == null) {
                 // 1. Add the provider to the list.
-                ProviderInfo provider = new ProviderInfo(providerInstance);
+                ProviderInfo provider =
+                        new ProviderInfo(providerInstance, treatRouteDescriptorIdsAsUnique);
                 mProviders.add(provider);
                 if (DEBUG) {
                     Log.d(TAG, "Provider added: " + provider);
@@ -3339,8 +3394,11 @@
             // possible for there to be two providers with the same package name.
             // Therefore we must dedupe the composite id.
             String componentName = provider.getComponentName().flattenToShortString();
-            String uniqueId = componentName + ":" + routeDescriptorId;
-            if (findRouteByUniqueId(uniqueId) < 0) {
+            String uniqueId =
+                    provider.mTreatRouteDescriptorIdsAsUnique
+                            ? routeDescriptorId
+                            : (componentName + ":" + routeDescriptorId);
+            if (provider.mTreatRouteDescriptorIdsAsUnique || findRouteByUniqueId(uniqueId) < 0) {
                 mUniqueIdMap.put(new Pair<>(componentName, routeDescriptorId), uniqueId);
                 return uniqueId;
             }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java
index 5514799..8cdbb96 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/MediaRouter2Utils.java
@@ -21,8 +21,21 @@
 import static android.media.MediaRoute2Info.FEATURE_REMOTE_AUDIO_PLAYBACK;
 import static android.media.MediaRoute2Info.FEATURE_REMOTE_PLAYBACK;
 import static android.media.MediaRoute2Info.FEATURE_REMOTE_VIDEO_PLAYBACK;
+import static android.media.MediaRoute2Info.TYPE_GROUP;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_AUDIO_VIDEO_RECEIVER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
+import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
+import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
 
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_AUDIO_VIDEO_RECEIVER;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_CAR;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_COMPUTER;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_GAME_CONSOLE;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_GROUP;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_SMARTWATCH;
 import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_SPEAKER;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_TABLET;
+import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_TABLET_DOCKED;
 import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_TV;
 import static androidx.mediarouter.media.MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN;
 
@@ -35,9 +48,12 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
 import androidx.annotation.RequiresApi;
+import androidx.mediarouter.media.MediaRouter.RouteInfo;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -63,8 +79,20 @@
     static final String KEY_SESSION_NAME = "androidx.mediarouter.media.KEY_SESSION_NAME";
     static final String KEY_GROUP_ROUTE = "androidx.mediarouter.media.KEY_GROUP_ROUTE";
 
+    // TODO(b/282263784): Remove the following constants in favor of using instead SDK constants,
+    // once the SDK constants become available.
+    private static final int TYPE_REMOTE_AUDIO_VIDEO_RECEIVER = 1003;
+    private static final int TYPE_REMOTE_TABLET = 1004;
+    private static final int TYPE_REMOTE_TABLET_DOCKED = 1005;
+    private static final int TYPE_REMOTE_COMPUTER = 1006;
+    private static final int TYPE_REMOTE_GAME_CONSOLE = 1007;
+    private static final int TYPE_REMOTE_CAR = 1008;
+    private static final int TYPE_REMOTE_SMARTWATCH = 1009;
+    private static final int TYPE_GROUP = 2000;
+
     private MediaRouter2Utils() {}
 
+    @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
     @Nullable
     public static MediaRoute2Info toFwkMediaRoute2Info(@Nullable MediaRouteDescriptor descriptor) {
         if (descriptor == null) {
@@ -88,6 +116,13 @@
                 //.setClientPackageName(clientMap.get(device.getDeviceId()))
                 ;
 
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            Api34Impl.setDeduplicationIds(builder, descriptor.getDeduplicationIds());
+            Api34Impl.copyDescriptorVisibilityToBuilder(builder, descriptor);
+            Api34Impl.setDeviceType(
+                    builder, androidXDeviceTypeToFwkDeviceType(descriptor.getDeviceType()));
+        }
+
         switch (descriptor.getDeviceType()) {
             case DEVICE_TYPE_TV:
                 builder.addFeature(FEATURE_REMOTE_VIDEO_PLAYBACK);
@@ -118,6 +153,7 @@
         return builder.build();
     }
 
+    @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class)
     @Nullable
     public static MediaRouteDescriptor toMediaRouteDescriptor(
             @Nullable MediaRoute2Info fwkMediaRoute2Info) {
@@ -135,6 +171,13 @@
                 .setEnabled(true)
                 .setCanDisconnect(false);
 
+        @RouteInfo.DeviceType int deviceTypeInRouteInfo = DEVICE_TYPE_UNKNOWN;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            builder.setDeduplicationIds(Api34Impl.getDeduplicationIds(fwkMediaRoute2Info));
+            deviceTypeInRouteInfo =
+                    fwkDeviceTypeToAndroidXDeviceType(Api34Impl.getType(fwkMediaRoute2Info));
+        }
+
         CharSequence description = fwkMediaRoute2Info.getDescription();
         if (description != null) {
             builder.setDescription(description.toString());
@@ -154,9 +197,11 @@
         }
 
         builder.setExtras(extras.getBundle(KEY_EXTRAS));
-        builder.setDeviceType(extras.getInt(KEY_DEVICE_TYPE, DEVICE_TYPE_UNKNOWN));
-        builder.setPlaybackType(extras.getInt(KEY_PLAYBACK_TYPE,
-                MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE));
+        builder.setDeviceType(
+                deviceTypeInRouteInfo != DEVICE_TYPE_UNKNOWN
+                        ? deviceTypeInRouteInfo
+                        : extras.getInt(KEY_DEVICE_TYPE, DEVICE_TYPE_UNKNOWN));
+        builder.setPlaybackType(extras.getInt(KEY_PLAYBACK_TYPE, RouteInfo.PLAYBACK_TYPE_REMOTE));
 
         List<IntentFilter> controlFilters = extras.getParcelableArrayList(KEY_CONTROL_FILTERS);
         if (controlFilters != null) {
@@ -276,4 +321,95 @@
         }
         return routeFeature;
     }
+
+    @RouteInfo.DeviceType
+    private static int fwkDeviceTypeToAndroidXDeviceType(int fwkDeviceType) {
+        switch (fwkDeviceType) {
+            case TYPE_REMOTE_TV:
+                return DEVICE_TYPE_TV;
+            case TYPE_REMOTE_SPEAKER:
+                return DEVICE_TYPE_SPEAKER;
+            case TYPE_REMOTE_AUDIO_VIDEO_RECEIVER:
+                return DEVICE_TYPE_AUDIO_VIDEO_RECEIVER;
+            case TYPE_REMOTE_TABLET:
+                return DEVICE_TYPE_TABLET;
+            case TYPE_REMOTE_TABLET_DOCKED:
+                return DEVICE_TYPE_TABLET_DOCKED;
+            case TYPE_REMOTE_COMPUTER:
+                return DEVICE_TYPE_COMPUTER;
+            case TYPE_REMOTE_GAME_CONSOLE:
+                return DEVICE_TYPE_GAME_CONSOLE;
+            case TYPE_REMOTE_CAR:
+                return DEVICE_TYPE_CAR;
+            case TYPE_REMOTE_SMARTWATCH:
+                return DEVICE_TYPE_SMARTWATCH;
+            case TYPE_GROUP:
+                return DEVICE_TYPE_GROUP;
+            default:
+                return DEVICE_TYPE_UNKNOWN;
+        }
+    }
+
+    private static int androidXDeviceTypeToFwkDeviceType(
+            @RouteInfo.DeviceType int androidXDeviceType) {
+        switch (androidXDeviceType) {
+            case DEVICE_TYPE_TV:
+                return TYPE_REMOTE_TV;
+            case DEVICE_TYPE_SPEAKER:
+                return TYPE_REMOTE_SPEAKER;
+            case DEVICE_TYPE_AUDIO_VIDEO_RECEIVER:
+                return TYPE_REMOTE_AUDIO_VIDEO_RECEIVER;
+            case DEVICE_TYPE_TABLET:
+                return TYPE_REMOTE_TABLET;
+            case DEVICE_TYPE_TABLET_DOCKED:
+                return TYPE_REMOTE_TABLET_DOCKED;
+            case DEVICE_TYPE_COMPUTER:
+                return TYPE_REMOTE_COMPUTER;
+            case DEVICE_TYPE_GAME_CONSOLE:
+                return TYPE_REMOTE_GAME_CONSOLE;
+            case DEVICE_TYPE_CAR:
+                return TYPE_REMOTE_CAR;
+            case DEVICE_TYPE_SMARTWATCH:
+                return TYPE_REMOTE_SMARTWATCH;
+            case DEVICE_TYPE_GROUP:
+                return TYPE_GROUP;
+            default:
+                return TYPE_UNKNOWN;
+        }
+    }
+
+    @RequiresApi(api = 34)
+    private static final class Api34Impl {
+
+        @DoNotInline
+        public static void setDeduplicationIds(
+                MediaRoute2Info.Builder builder, Set<String> deduplicationIds) {
+            builder.setDeduplicationIds(deduplicationIds);
+        }
+
+        @DoNotInline
+        public static Set<String> getDeduplicationIds(MediaRoute2Info fwkMediaRoute2Info) {
+            return fwkMediaRoute2Info.getDeduplicationIds();
+        }
+
+        @DoNotInline
+        public static void copyDescriptorVisibilityToBuilder(MediaRoute2Info.Builder builder,
+                MediaRouteDescriptor descriptor) {
+            if (descriptor.isVisibilityPublic()) {
+                builder.setVisibilityPublic();
+            } else {
+                builder.setVisibilityRestricted(descriptor.getAllowedPackages());
+            }
+        }
+
+        @DoNotInline
+        public static void setDeviceType(MediaRoute2Info.Builder builder, int deviceType) {
+            builder.setType(deviceType);
+        }
+
+        @DoNotInline
+        public static int getType(MediaRoute2Info fwkMediaRoute2Info) {
+            return fwkMediaRoute2Info.getType();
+        }
+    }
 }
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RouteListingPreference.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RouteListingPreference.java
new file mode 100644
index 0000000..3be72e6
--- /dev/null
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/media/RouteListingPreference.java
@@ -0,0 +1,594 @@
+/*
+ * 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.mediarouter.media;
+
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.text.TextUtils;
+
+import androidx.annotation.DoNotInline;
+import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * Allows applications to customize the list of routes used for media routing (for example, in the
+ * System UI Output Switcher).
+ *
+ * @see MediaRouter#setRouteListingPreference
+ * @see RouteListingPreference.Item
+ */
+public final class RouteListingPreference {
+
+    /**
+     * {@link Intent} action that the system uses to take the user the app when the user selects an
+     * {@link RouteListingPreference.Item} whose {@link
+     * RouteListingPreference.Item#getSelectionBehavior() selection behavior} is {@link
+     * RouteListingPreference.Item#SELECTION_BEHAVIOR_GO_TO_APP}.
+     *
+     * <p>The launched intent will identify the selected item using the extra identified by {@link
+     * #EXTRA_ROUTE_ID}.
+     *
+     * @see #getLinkedItemComponentName()
+     * @see RouteListingPreference.Item#SELECTION_BEHAVIOR_GO_TO_APP
+     */
+    @SuppressLint("ActionValue") // Field & value copied from android.media.RouteListingPreference.
+    public static final String ACTION_TRANSFER_MEDIA =
+            android.media.RouteListingPreference.ACTION_TRANSFER_MEDIA;
+
+    /**
+     * {@link Intent} string extra key that contains the {@link
+     * RouteListingPreference.Item#getRouteId() id} of the route to transfer to, as part of an
+     * {@link #ACTION_TRANSFER_MEDIA} intent.
+     *
+     * @see #getLinkedItemComponentName()
+     * @see RouteListingPreference.Item#SELECTION_BEHAVIOR_GO_TO_APP
+     */
+    @SuppressLint("ActionValue") // Field & value copied from android.media.RouteListingPreference.
+    public static final String EXTRA_ROUTE_ID = android.media.RouteListingPreference.EXTRA_ROUTE_ID;
+
+    @NonNull private final List<RouteListingPreference.Item> mItems;
+    private final boolean mUseSystemOrdering;
+    @Nullable private final ComponentName mLinkedItemComponentName;
+
+    // Must be package private to avoid a synthetic accessor for the builder.
+    /* package */ RouteListingPreference(RouteListingPreference.Builder builder) {
+        mItems = builder.mItems;
+        mUseSystemOrdering = builder.mUseSystemOrdering;
+        mLinkedItemComponentName = builder.mLinkedItemComponentName;
+    }
+
+    /**
+     * Returns an unmodifiable list containing the {@link RouteListingPreference.Item items} that
+     * the app wants to be listed for media routing.
+     */
+    @NonNull
+    public List<RouteListingPreference.Item> getItems() {
+        return mItems;
+    }
+
+    /**
+     * Returns true if the application would like media route listing to use the system's ordering
+     * strategy, or false if the application would like route listing to respect the ordering
+     * obtained from {@link #getItems()}.
+     *
+     * <p>The system's ordering strategy is implementation-dependent, but may take into account each
+     * route's recency or frequency of use in order to rank them.
+     */
+    public boolean getUseSystemOrdering() {
+        return mUseSystemOrdering;
+    }
+
+    /**
+     * Returns a {@link ComponentName} for navigating to the application.
+     *
+     * <p>Must not be null if any of the {@link #getItems() items} of this route listing preference
+     * has {@link RouteListingPreference.Item#getSelectionBehavior() selection behavior} {@link
+     * RouteListingPreference.Item#SELECTION_BEHAVIOR_GO_TO_APP}.
+     *
+     * <p>The system navigates to the application when the user selects {@link
+     * RouteListingPreference.Item} with {@link
+     * RouteListingPreference.Item#SELECTION_BEHAVIOR_GO_TO_APP} by launching an intent to the
+     * returned {@link ComponentName}, using action {@link #ACTION_TRANSFER_MEDIA}, with the extra
+     * {@link #EXTRA_ROUTE_ID}.
+     */
+    @Nullable
+    public ComponentName getLinkedItemComponentName() {
+        return mLinkedItemComponentName;
+    }
+
+    // Equals and hashCode.
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        }
+        if (!(other instanceof RouteListingPreference)) {
+            return false;
+        }
+        RouteListingPreference that = (RouteListingPreference) other;
+        return mItems.equals(that.mItems)
+                && mUseSystemOrdering == that.mUseSystemOrdering
+                && Objects.equals(mLinkedItemComponentName, that.mLinkedItemComponentName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mItems, mUseSystemOrdering, mLinkedItemComponentName);
+    }
+
+    // Internal methods.
+
+    /** @hide */
+    @RequiresApi(api = 34)
+    @NonNull /* package */
+    android.media.RouteListingPreference toPlatformRouteListingPreference() {
+        return Api34Impl.toPlatformRouteListingPreference(this);
+    }
+
+    // Inner classes.
+
+    /** Builder for {@link RouteListingPreference}. */
+    public static final class Builder {
+
+        // The builder fields must be package private to avoid synthetic accessors.
+        /* package */ List<RouteListingPreference.Item> mItems;
+        /* package */ boolean mUseSystemOrdering;
+        /* package */ ComponentName mLinkedItemComponentName;
+
+        /** Creates a new instance with default values (documented in the setters). */
+        public Builder() {
+            mItems = Collections.emptyList();
+            mUseSystemOrdering = true;
+        }
+
+        /**
+         * See {@link #getItems()}
+         *
+         * <p>The default value is an empty list.
+         */
+        @NonNull
+        public RouteListingPreference.Builder setItems(
+                @NonNull List<RouteListingPreference.Item> items) {
+            mItems = Collections.unmodifiableList(new ArrayList<>(Objects.requireNonNull(items)));
+            return this;
+        }
+
+        /**
+         * See {@link #getUseSystemOrdering()}
+         *
+         * <p>The default value is {@code true}.
+         */
+        // Lint requires "isUseSystemOrdering", but "getUseSystemOrdering" is a better name.
+        @SuppressWarnings("MissingGetterMatchingBuilder")
+        @NonNull
+        public RouteListingPreference.Builder setUseSystemOrdering(boolean useSystemOrdering) {
+            mUseSystemOrdering = useSystemOrdering;
+            return this;
+        }
+
+        /**
+         * See {@link #getLinkedItemComponentName()}.
+         *
+         * <p>The default value is {@code null}.
+         */
+        @NonNull
+        public RouteListingPreference.Builder setLinkedItemComponentName(
+                @Nullable ComponentName linkedItemComponentName) {
+            mLinkedItemComponentName = linkedItemComponentName;
+            return this;
+        }
+
+        /**
+         * Creates and returns a new {@link RouteListingPreference} instance with the given
+         * parameters.
+         */
+        @NonNull
+        public RouteListingPreference build() {
+            return new RouteListingPreference(this);
+        }
+    }
+
+    /** Holds preference information for a specific route in a {@link RouteListingPreference}. */
+    public static final class Item {
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(
+                value = {
+                    SELECTION_BEHAVIOR_NONE,
+                    SELECTION_BEHAVIOR_TRANSFER,
+                    SELECTION_BEHAVIOR_GO_TO_APP
+                })
+        public @interface SelectionBehavior {}
+
+        /** The corresponding route is not selectable by the user. */
+        public static final int SELECTION_BEHAVIOR_NONE = 0;
+        /** If the user selects the corresponding route, the media transfers to the said route. */
+        public static final int SELECTION_BEHAVIOR_TRANSFER = 1;
+        /**
+         * If the user selects the corresponding route, the system takes the user to the
+         * application.
+         *
+         * <p>The system uses {@link #getLinkedItemComponentName()} in order to navigate to the app.
+         */
+        public static final int SELECTION_BEHAVIOR_GO_TO_APP = 2;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(
+                flag = true,
+                value = {FLAG_ONGOING_SESSION, FLAG_ONGOING_SESSION_MANAGED, FLAG_SUGGESTED})
+        public @interface Flags {}
+
+        /**
+         * The corresponding route is already hosting a session with the app that owns this listing
+         * preference.
+         */
+        public static final int FLAG_ONGOING_SESSION = 1;
+
+        /**
+         * Signals that the ongoing session on the corresponding route is managed by the current
+         * user of the app.
+         *
+         * <p>The system can use this flag to provide visual indication that the route is not only
+         * hosting a session, but also that the user has ownership over said session.
+         *
+         * <p>This flag is ignored if {@link #FLAG_ONGOING_SESSION} is not set, or if the
+         * corresponding route is not currently selected.
+         *
+         * <p>This flag does not affect volume adjustment (see {@link
+         * androidx.media.VolumeProviderCompat}, and {@link
+         * MediaRouteDescriptor#getVolumeHandling()}), or any aspect other than the visual
+         * representation of the corresponding item.
+         */
+        public static final int FLAG_ONGOING_SESSION_MANAGED = 1 << 1;
+
+        /**
+         * The corresponding route is specially likely to be selected by the user.
+         *
+         * <p>A UI reflecting this preference may reserve a specific space for suggested routes,
+         * making it more accessible to the user. If the number of suggested routes exceeds the
+         * number supported by the UI, the routes listed first in {@link
+         * RouteListingPreference#getItems()} will take priority.
+         */
+        public static final int FLAG_SUGGESTED = 1 << 2;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(
+                value = {
+                    SUBTEXT_NONE,
+                    SUBTEXT_ERROR_UNKNOWN,
+                    SUBTEXT_SUBSCRIPTION_REQUIRED,
+                    SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED,
+                    SUBTEXT_AD_ROUTING_DISALLOWED,
+                    SUBTEXT_DEVICE_LOW_POWER,
+                    SUBTEXT_UNAUTHORIZED,
+                    SUBTEXT_TRACK_UNSUPPORTED,
+                    SUBTEXT_CUSTOM
+                })
+        public @interface SubText {}
+
+        /** The corresponding route has no associated subtext. */
+        public static final int SUBTEXT_NONE =
+                android.media.RouteListingPreference.Item.SUBTEXT_NONE;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because of an
+         * unknown error.
+         */
+        public static final int SUBTEXT_ERROR_UNKNOWN =
+                android.media.RouteListingPreference.Item.SUBTEXT_ERROR_UNKNOWN;
+        /**
+         * The corresponding route's subtext must indicate that it requires a special subscription
+         * in order to be available for routing.
+         */
+        public static final int SUBTEXT_SUBSCRIPTION_REQUIRED =
+                android.media.RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED;
+        /**
+         * The corresponding route's subtext must indicate that downloaded content cannot be routed
+         * to it.
+         */
+        public static final int SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED =
+                android.media.RouteListingPreference.Item
+                        .SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because an ad is
+         * in progress.
+         */
+        public static final int SUBTEXT_AD_ROUTING_DISALLOWED =
+                android.media.RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the
+         * device is in low-power mode.
+         */
+        public static final int SUBTEXT_DEVICE_LOW_POWER =
+                android.media.RouteListingPreference.Item.SUBTEXT_DEVICE_LOW_POWER;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the user
+         * is not authorized to route to it.
+         */
+        public static final int SUBTEXT_UNAUTHORIZED =
+                android.media.RouteListingPreference.Item.SUBTEXT_UNAUTHORIZED;
+        /**
+         * The corresponding route's subtext must indicate that it is not available because the
+         * device does not support the current media track.
+         */
+        public static final int SUBTEXT_TRACK_UNSUPPORTED =
+                android.media.RouteListingPreference.Item.SUBTEXT_TRACK_UNSUPPORTED;
+        /**
+         * The corresponding route's subtext must be obtained from {@link
+         * #getCustomSubtextMessage()}.
+         *
+         * <p>Applications should strongly prefer one of the other disable reasons (for the full
+         * list, see {@link #getSubText()}) in order to guarantee correct localization and rendering
+         * across all form factors.
+         */
+        public static final int SUBTEXT_CUSTOM =
+                android.media.RouteListingPreference.Item.SUBTEXT_CUSTOM;
+
+        @NonNull private final String mRouteId;
+        @SelectionBehavior private final int mSelectionBehavior;
+        @Flags private final int mFlags;
+        @SubText private final int mSubText;
+
+        @Nullable private final CharSequence mCustomSubtextMessage;
+
+        // Must be package private to avoid a synthetic accessor for the builder.
+        /* package */ Item(@NonNull RouteListingPreference.Item.Builder builder) {
+            mRouteId = builder.mRouteId;
+            mSelectionBehavior = builder.mSelectionBehavior;
+            mFlags = builder.mFlags;
+            mSubText = builder.mSubText;
+            mCustomSubtextMessage = builder.mCustomSubtextMessage;
+            validateCustomMessageSubtext();
+        }
+
+        /**
+         * Returns the id of the route that corresponds to this route listing preference item.
+         *
+         * @see MediaRouter.RouteInfo#getId()
+         */
+        @NonNull
+        public String getRouteId() {
+            return mRouteId;
+        }
+
+        /**
+         * Returns the behavior that the corresponding route has if the user selects it.
+         *
+         * @see #SELECTION_BEHAVIOR_NONE
+         * @see #SELECTION_BEHAVIOR_TRANSFER
+         * @see #SELECTION_BEHAVIOR_GO_TO_APP
+         */
+        public int getSelectionBehavior() {
+            return mSelectionBehavior;
+        }
+
+        /**
+         * Returns the flags associated to the route that corresponds to this item.
+         *
+         * @see #FLAG_ONGOING_SESSION
+         * @see #FLAG_ONGOING_SESSION_MANAGED
+         * @see #FLAG_SUGGESTED
+         */
+        @Flags
+        public int getFlags() {
+            return mFlags;
+        }
+
+        /**
+         * Returns the type of subtext associated to this route.
+         *
+         * <p>Subtext types other than {@link #SUBTEXT_NONE} and {@link #SUBTEXT_CUSTOM} must not
+         * have {@link #SELECTION_BEHAVIOR_TRANSFER}.
+         *
+         * <p>If this method returns {@link #SUBTEXT_CUSTOM}, then the subtext is obtained form
+         * {@link #getCustomSubtextMessage()}.
+         *
+         * @see #SUBTEXT_NONE
+         * @see #SUBTEXT_ERROR_UNKNOWN
+         * @see #SUBTEXT_SUBSCRIPTION_REQUIRED
+         * @see #SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED
+         * @see #SUBTEXT_AD_ROUTING_DISALLOWED
+         * @see #SUBTEXT_DEVICE_LOW_POWER
+         * @see #SUBTEXT_UNAUTHORIZED
+         * @see #SUBTEXT_TRACK_UNSUPPORTED
+         * @see #SUBTEXT_CUSTOM
+         */
+        @SubText
+        public int getSubText() {
+            return mSubText;
+        }
+
+        /**
+         * Returns a human-readable {@link CharSequence} providing the subtext for the corresponding
+         * route.
+         *
+         * <p>This value is ignored if the {@link #getSubText() subtext} for this item is not {@link
+         * #SUBTEXT_CUSTOM}..
+         *
+         * <p>Applications must provide a localized message that matches the system's locale. See
+         * {@link Locale#getDefault()}.
+         *
+         * <p>Applications should avoid using custom messages (and instead use one of non-custom
+         * subtexts listed in {@link #getSubText()} in order to guarantee correct visual
+         * representation and localization on all form factors.
+         */
+        @Nullable
+        public CharSequence getCustomSubtextMessage() {
+            return mCustomSubtextMessage;
+        }
+
+        // Equals and hashCode.
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) {
+                return true;
+            }
+            if (!(other instanceof RouteListingPreference.Item)) {
+                return false;
+            }
+            RouteListingPreference.Item item = (RouteListingPreference.Item) other;
+            return mRouteId.equals(item.mRouteId)
+                    && mSelectionBehavior == item.mSelectionBehavior
+                    && mFlags == item.mFlags
+                    && mSubText == item.mSubText
+                    && TextUtils.equals(mCustomSubtextMessage, item.mCustomSubtextMessage);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(
+                    mRouteId, mSelectionBehavior, mFlags, mSubText, mCustomSubtextMessage);
+        }
+
+        // Internal methods.
+
+        private void validateCustomMessageSubtext() {
+            Preconditions.checkArgument(
+                    mSubText != SUBTEXT_CUSTOM || mCustomSubtextMessage != null,
+                    "The custom subtext message cannot be null if subtext is SUBTEXT_CUSTOM.");
+        }
+
+        // Internal classes.
+
+        /** Builder for {@link RouteListingPreference.Item}. */
+        public static final class Builder {
+
+            // The builder fields must be package private to avoid synthetic accessors.
+            /* package */ final String mRouteId;
+            /* package */ int mSelectionBehavior;
+            /* package */ int mFlags;
+            /* package */ int mSubText;
+            /* package */ CharSequence mCustomSubtextMessage;
+
+            /**
+             * Constructor.
+             *
+             * @param routeId See {@link RouteListingPreference.Item#getRouteId()}.
+             */
+            public Builder(@NonNull String routeId) {
+                Preconditions.checkArgument(!TextUtils.isEmpty(routeId));
+                mRouteId = routeId;
+                mSelectionBehavior = SELECTION_BEHAVIOR_TRANSFER;
+                mSubText = SUBTEXT_NONE;
+            }
+
+            /**
+             * See {@link RouteListingPreference.Item#getSelectionBehavior()}.
+             *
+             * <p>The default value is {@link #ACTION_TRANSFER_MEDIA}.
+             */
+            @NonNull
+            public RouteListingPreference.Item.Builder setSelectionBehavior(int selectionBehavior) {
+                mSelectionBehavior = selectionBehavior;
+                return this;
+            }
+
+            /**
+             * See {@link RouteListingPreference.Item#getFlags()}.
+             *
+             * <p>The default value is zero (no flags).
+             */
+            @NonNull
+            public RouteListingPreference.Item.Builder setFlags(int flags) {
+                mFlags = flags;
+                return this;
+            }
+
+            /**
+             * See {@link RouteListingPreference.Item#getSubText()}.
+             *
+             * <p>The default value is {@link #SUBTEXT_NONE}.
+             */
+            @NonNull
+            public RouteListingPreference.Item.Builder setSubText(int subText) {
+                mSubText = subText;
+                return this;
+            }
+
+            /**
+             * See {@link RouteListingPreference.Item#getCustomSubtextMessage()}.
+             *
+             * <p>The default value is {@code null}.
+             */
+            @NonNull
+            public RouteListingPreference.Item.Builder setCustomSubtextMessage(
+                    @Nullable CharSequence customSubtextMessage) {
+                mCustomSubtextMessage = customSubtextMessage;
+                return this;
+            }
+
+            /**
+             * Creates and returns a new {@link RouteListingPreference.Item} with the given
+             * parameters.
+             */
+            @NonNull
+            public RouteListingPreference.Item build() {
+                return new RouteListingPreference.Item(this);
+            }
+        }
+    }
+
+    @RequiresApi(34)
+    private static class Api34Impl {
+        private Api34Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        @NonNull
+        public static android.media.RouteListingPreference toPlatformRouteListingPreference(
+                RouteListingPreference routeListingPreference) {
+            ArrayList<android.media.RouteListingPreference.Item> platformRlpItems =
+                    new ArrayList<>();
+            for (Item item : routeListingPreference.getItems()) {
+                platformRlpItems.add(toPlatformItem(item));
+            }
+
+            return new android.media.RouteListingPreference.Builder()
+                    .setItems(platformRlpItems)
+                    .setLinkedItemComponentName(routeListingPreference.getLinkedItemComponentName())
+                    .setUseSystemOrdering(routeListingPreference.getUseSystemOrdering())
+                    .build();
+        }
+
+        @DoNotInline
+        @NonNull
+        public static android.media.RouteListingPreference.Item toPlatformItem(Item item) {
+            return new android.media.RouteListingPreference.Item.Builder(item.getRouteId())
+                    .setFlags(item.getFlags())
+                    .setSubText(item.getSubText())
+                    .setCustomSubtextMessage(item.getCustomSubtextMessage())
+                    .setSelectionBehavior(item.getSelectionBehavior())
+                    .build();
+        }
+    }
+}
diff --git a/navigation/navigation-common-ktx/api/2.7.0-beta02.txt b/navigation/navigation-common-ktx/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-common-ktx/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-common-ktx/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-common-ktx/api/restricted_2.7.0-beta02.txt b/navigation/navigation-common-ktx/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/navigation/navigation-common/api/2.7.0-beta02.txt b/navigation/navigation-common/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..51a77a6
--- /dev/null
+++ b/navigation/navigation-common/api/2.7.0-beta02.txt
@@ -0,0 +1,530 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
+    ctor public ActionOnlyNavDirections(int actionId);
+    method public int component1();
+    method public androidx.navigation.ActionOnlyNavDirections copy(int actionId);
+    method public int getActionId();
+    method public android.os.Bundle getArguments();
+    property public int actionId;
+    property public android.os.Bundle arguments;
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
+    ctor public AnimBuilder();
+    method public int getEnter();
+    method public int getExit();
+    method public int getPopEnter();
+    method public int getPopExit();
+    method public void setEnter(int);
+    method public void setExit(int);
+    method public void setPopEnter(int);
+    method public void setPopExit(int);
+    property public final int enter;
+    property public final int exit;
+    property public final int popEnter;
+    property public final int popExit;
+  }
+
+  public interface FloatingWindow {
+  }
+
+  public final class NamedNavArgument {
+    method public operator String component1();
+    method public operator androidx.navigation.NavArgument component2();
+    method public androidx.navigation.NavArgument getArgument();
+    method public String getName();
+    property public final androidx.navigation.NavArgument argument;
+    property public final String name;
+  }
+
+  public final class NamedNavArgumentKt {
+    method public static androidx.navigation.NamedNavArgument navArgument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavAction {
+    ctor public NavAction(@IdRes int destinationId);
+    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions);
+    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions, optional android.os.Bundle? defaultArguments);
+    method public android.os.Bundle? getDefaultArguments();
+    method public int getDestinationId();
+    method public androidx.navigation.NavOptions? getNavOptions();
+    method public void setDefaultArguments(android.os.Bundle?);
+    method public void setNavOptions(androidx.navigation.NavOptions?);
+    property public final android.os.Bundle? defaultArguments;
+    property public final int destinationId;
+    property public final androidx.navigation.NavOptions? navOptions;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+    ctor public NavActionBuilder();
+    method public java.util.Map<java.lang.String,java.lang.Object> getDefaultArguments();
+    method public int getDestinationId();
+    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+    method public void setDestinationId(int);
+    property public final java.util.Map<java.lang.String,java.lang.Object> defaultArguments;
+    property public final int destinationId;
+  }
+
+  public interface NavArgs {
+  }
+
+  public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
+    ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
+    method public Args getValue();
+    method public boolean isInitialized();
+    property public Args value;
+  }
+
+  public final class NavArgument {
+    method public Object? getDefaultValue();
+    method public androidx.navigation.NavType<java.lang.Object> getType();
+    method public boolean isDefaultValuePresent();
+    method public boolean isNullable();
+    property public final Object? defaultValue;
+    property public final boolean isDefaultValuePresent;
+    property public final boolean isNullable;
+    property public final androidx.navigation.NavType<java.lang.Object> type;
+  }
+
+  public static final class NavArgument.Builder {
+    ctor public NavArgument.Builder();
+    method public androidx.navigation.NavArgument build();
+    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object? defaultValue);
+    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean isNullable);
+    method public <T> androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<T> type);
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+    ctor public NavArgumentBuilder();
+    method public androidx.navigation.NavArgument build();
+    method public Object? getDefaultValue();
+    method public boolean getNullable();
+    method public androidx.navigation.NavType<?> getType();
+    method public void setDefaultValue(Object?);
+    method public void setNullable(boolean);
+    method public void setType(androidx.navigation.NavType<?>);
+    property public final Object? defaultValue;
+    property public final boolean nullable;
+    property public final androidx.navigation.NavType<?> type;
+  }
+
+  public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    method public android.os.Bundle? getArguments();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method public androidx.navigation.NavDestination getDestination();
+    method public String getId();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    property public final android.os.Bundle? arguments;
+    property public androidx.lifecycle.viewmodel.CreationExtras defaultViewModelCreationExtras;
+    property public androidx.lifecycle.ViewModelProvider.Factory defaultViewModelProviderFactory;
+    property public final androidx.navigation.NavDestination destination;
+    property public final String id;
+    property public androidx.lifecycle.Lifecycle lifecycle;
+    property public final androidx.lifecycle.SavedStateHandle savedStateHandle;
+    property public androidx.savedstate.SavedStateRegistry savedStateRegistry;
+    property public androidx.lifecycle.ViewModelStore viewModelStore;
+  }
+
+  public final class NavDeepLink {
+    method public String? getAction();
+    method public String? getMimeType();
+    method public String? getUriPattern();
+    property public final String? action;
+    property public final String? mimeType;
+    property public final String? uriPattern;
+  }
+
+  public static final class NavDeepLink.Builder {
+    method public androidx.navigation.NavDeepLink build();
+    method public static androidx.navigation.NavDeepLink.Builder fromAction(String action);
+    method public static androidx.navigation.NavDeepLink.Builder fromMimeType(String mimeType);
+    method public static androidx.navigation.NavDeepLink.Builder fromUriPattern(String uriPattern);
+    method public androidx.navigation.NavDeepLink.Builder setAction(String action);
+    method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
+  }
+
+  @kotlin.DslMarker public @interface NavDeepLinkDsl {
+  }
+
+  @androidx.navigation.NavDeepLinkDsl public final class NavDeepLinkDslBuilder {
+    ctor public NavDeepLinkDslBuilder();
+    method public String? getAction();
+    method public String? getMimeType();
+    method public String? getUriPattern();
+    method public void setAction(String?);
+    method public void setMimeType(String?);
+    method public void setUriPattern(String?);
+    property public final String? action;
+    property public final String? mimeType;
+    property public final String? uriPattern;
+  }
+
+  public final class NavDeepLinkDslBuilderKt {
+    method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+  }
+
+  public class NavDeepLinkRequest {
+    method public String? getAction();
+    method public String? getMimeType();
+    method public android.net.Uri? getUri();
+    property public String? action;
+    property public String? mimeType;
+    property public android.net.Uri? uri;
+  }
+
+  public static final class NavDeepLinkRequest.Builder {
+    method public androidx.navigation.NavDeepLinkRequest build();
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setAction(String action);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setUri(android.net.Uri uri);
+    field public static final androidx.navigation.NavDeepLinkRequest.Builder.Companion Companion;
+  }
+
+  public static final class NavDeepLinkRequest.Builder.Companion {
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
+  }
+
+  public class NavDestination {
+    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    ctor public NavDestination(String navigatorName);
+    method public final void addArgument(String argumentName, androidx.navigation.NavArgument argument);
+    method public final void addDeepLink(androidx.navigation.NavDeepLink navDeepLink);
+    method public final void addDeepLink(String uriPattern);
+    method public final String? fillInLabel(android.content.Context context, android.os.Bundle? bundle);
+    method public final androidx.navigation.NavAction? getAction(@IdRes int id);
+    method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
+    method public static final kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
+    method @IdRes public final int getId();
+    method public final CharSequence? getLabel();
+    method public final String getNavigatorName();
+    method public final androidx.navigation.NavGraph? getParent();
+    method public final String? getRoute();
+    method public boolean hasDeepLink(android.net.Uri deepLink);
+    method public boolean hasDeepLink(androidx.navigation.NavDeepLinkRequest deepLinkRequest);
+    method @CallSuper public void onInflate(android.content.Context context, android.util.AttributeSet attrs);
+    method protected static final <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
+    method public final void putAction(@IdRes int actionId, androidx.navigation.NavAction action);
+    method public final void putAction(@IdRes int actionId, @IdRes int destId);
+    method public final void removeAction(@IdRes int actionId);
+    method public final void removeArgument(String argumentName);
+    method public final void setId(@IdRes int);
+    method public final void setLabel(CharSequence?);
+    method public final void setRoute(String?);
+    property public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> arguments;
+    property @IdRes public final int id;
+    property public final CharSequence? label;
+    property public final String navigatorName;
+    property public final androidx.navigation.NavGraph? parent;
+    property public final String? route;
+    field public static final androidx.navigation.NavDestination.Companion Companion;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
+    method public abstract kotlin.reflect.KClass<?> value();
+    property public abstract kotlin.reflect.KClass<?> value;
+  }
+
+  public static final class NavDestination.Companion {
+    method public kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
+    method protected <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
+    method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+    method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
+    method public D build();
+    method public final void deepLink(String uriPattern);
+    method public final void deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> navDeepLink);
+    method public final int getId();
+    method public final CharSequence? getLabel();
+    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+    method public final String? getRoute();
+    method public final void setLabel(CharSequence?);
+    property public final int id;
+    property public final CharSequence? label;
+    property protected final androidx.navigation.Navigator<? extends D> navigator;
+    property public final String? route;
+  }
+
+  @kotlin.DslMarker public @interface NavDestinationDsl {
+  }
+
+  public interface NavDirections {
+    method @IdRes public int getActionId();
+    method public android.os.Bundle getArguments();
+    property @IdRes public abstract int actionId;
+    property public abstract android.os.Bundle arguments;
+  }
+
+  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> kotlin.jvm.internal.markers.KMappedMarker {
+    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph> navGraphNavigator);
+    method public final void addAll(androidx.navigation.NavGraph other);
+    method public final void addDestination(androidx.navigation.NavDestination node);
+    method public final void addDestinations(androidx.navigation.NavDestination... nodes);
+    method public final void addDestinations(java.util.Collection<? extends androidx.navigation.NavDestination> nodes);
+    method public final void clear();
+    method public final androidx.navigation.NavDestination? findNode(@IdRes int resId);
+    method public final androidx.navigation.NavDestination? findNode(String? route);
+    method public static final androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
+    method @Deprecated @IdRes public final int getStartDestination();
+    method @IdRes public final int getStartDestinationId();
+    method public final String? getStartDestinationRoute();
+    method public final java.util.Iterator<androidx.navigation.NavDestination> iterator();
+    method public final void remove(androidx.navigation.NavDestination node);
+    method public final void setStartDestination(int startDestId);
+    method public final void setStartDestination(String startDestRoute);
+    property @IdRes public final int startDestinationId;
+    property public final String? startDestinationRoute;
+    field public static final androidx.navigation.NavGraph.Companion Companion;
+  }
+
+  public static final class NavGraph.Companion {
+    method public androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
+    method public final void addDestination(androidx.navigation.NavDestination destination);
+    method public androidx.navigation.NavGraph build();
+    method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+    method public final androidx.navigation.NavigatorProvider getProvider();
+    method public final operator void unaryPlus(androidx.navigation.NavDestination);
+    property public final androidx.navigation.NavigatorProvider provider;
+  }
+
+  public final class NavGraphBuilderKt {
+    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavGraphKt {
+    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+    method public static operator boolean contains(androidx.navigation.NavGraph, String route);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, String route);
+    method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
+    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public androidx.navigation.NavGraph createDestination();
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+  }
+
+  public final class NavOptions {
+    method @AnimRes @AnimatorRes public int getEnterAnim();
+    method @AnimRes @AnimatorRes public int getExitAnim();
+    method @AnimRes @AnimatorRes public int getPopEnterAnim();
+    method @AnimRes @AnimatorRes public int getPopExitAnim();
+    method @Deprecated @IdRes public int getPopUpTo();
+    method @IdRes public int getPopUpToId();
+    method public String? getPopUpToRoute();
+    method public boolean isPopUpToInclusive();
+    method public boolean shouldLaunchSingleTop();
+    method public boolean shouldPopUpToSaveState();
+    method public boolean shouldRestoreState();
+    property @AnimRes @AnimatorRes public final int enterAnim;
+    property @AnimRes @AnimatorRes public final int exitAnim;
+    property @AnimRes @AnimatorRes public final int popEnterAnim;
+    property @AnimRes @AnimatorRes public final int popExitAnim;
+    property @IdRes public final int popUpToId;
+    property public final String? popUpToRoute;
+  }
+
+  public static final class NavOptions.Builder {
+    ctor public NavOptions.Builder();
+    method public androidx.navigation.NavOptions build();
+    method public androidx.navigation.NavOptions.Builder setEnterAnim(@AnimRes @AnimatorRes int enterAnim);
+    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int exitAnim);
+    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean singleTop);
+    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int popEnterAnim);
+    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int popExitAnim);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive, optional boolean saveState);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive, optional boolean saveState);
+    method public androidx.navigation.NavOptions.Builder setRestoreState(boolean restoreState);
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
+    ctor public NavOptionsBuilder();
+    method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
+    method public boolean getLaunchSingleTop();
+    method @Deprecated public int getPopUpTo();
+    method public int getPopUpToId();
+    method public String? getPopUpToRoute();
+    method public boolean getRestoreState();
+    method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void popUpTo(String route, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void setLaunchSingleTop(boolean);
+    method @Deprecated public void setPopUpTo(int);
+    method public void setRestoreState(boolean);
+    property public final boolean launchSingleTop;
+    property @Deprecated public final int popUpTo;
+    property public final int popUpToId;
+    property public final String? popUpToRoute;
+    property public final boolean restoreState;
+  }
+
+  public final class NavOptionsBuilderKt {
+    method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+  }
+
+  @kotlin.DslMarker public @interface NavOptionsDsl {
+  }
+
+  public abstract class NavType<T> {
+    ctor public NavType(boolean isNullableAllowed);
+    method public static androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
+    method public abstract operator T? get(android.os.Bundle bundle, String key);
+    method public String getName();
+    method public boolean isNullableAllowed();
+    method public abstract T parseValue(String value);
+    method public T parseValue(String value, T previousValue);
+    method public abstract void put(android.os.Bundle bundle, String key, T value);
+    method public String serializeAsValue(T value);
+    property public boolean isNullableAllowed;
+    property public String name;
+    field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
+    field public static final androidx.navigation.NavType.Companion Companion;
+    field public static final androidx.navigation.NavType<float[]> FloatArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
+    field public static final androidx.navigation.NavType<int[]> IntArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
+    field public static final androidx.navigation.NavType<long[]> LongArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Long> LongType;
+    field public static final androidx.navigation.NavType<java.lang.Integer> ReferenceType;
+    field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
+    field public static final androidx.navigation.NavType<java.lang.String> StringType;
+  }
+
+  public static final class NavType.Companion {
+    method public androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
+  }
+
+  public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
+    ctor public NavType.EnumType(Class<D> type);
+    property public String name;
+  }
+
+  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.ParcelableArrayType(Class<D> type);
+    method public D![]? get(android.os.Bundle bundle, String key);
+    method public D![] parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D![]? value);
+    property public String name;
+  }
+
+  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+    ctor public NavType.ParcelableType(Class<D> type);
+    method public D? get(android.os.Bundle bundle, String key);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
+    property public String name;
+  }
+
+  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.SerializableArrayType(Class<D> type);
+    method public D![]? get(android.os.Bundle bundle, String key);
+    method public D![] parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D![]? value);
+    property public String name;
+  }
+
+  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+    ctor public NavType.SerializableType(Class<D> type);
+    method public D? get(android.os.Bundle bundle, String key);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
+    property public String name;
+  }
+
+  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
+    ctor public Navigator();
+    method public abstract D createDestination();
+    method protected final androidx.navigation.NavigatorState getState();
+    method public final boolean isAttached();
+    method public androidx.navigation.NavDestination? navigate(D destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method public void navigate(java.util.List<androidx.navigation.NavBackStackEntry> entries, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @CallSuper public void onAttach(androidx.navigation.NavigatorState state);
+    method public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void onRestoreState(android.os.Bundle savedState);
+    method public android.os.Bundle? onSaveState();
+    method public boolean popBackStack();
+    method public void popBackStack(androidx.navigation.NavBackStackEntry popUpTo, boolean savedState);
+    property public final boolean isAttached;
+    property protected final androidx.navigation.NavigatorState state;
+  }
+
+  public static interface Navigator.Extras {
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface Navigator.Name {
+    method public abstract String value();
+    property public abstract String value;
+  }
+
+  public class NavigatorProvider {
+    ctor public NavigatorProvider();
+    method public final androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T> navigatorClass);
+    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String name);
+  }
+
+  public final class NavigatorProviderKt {
+    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
+    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
+    method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+  }
+
+  public abstract class NavigatorState {
+    ctor public NavigatorState();
+    method public abstract androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> getTransitionsInProgress();
+    method public void markTransitionComplete(androidx.navigation.NavBackStackEntry entry);
+    method @CallSuper public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
+    method @CallSuper public void onLaunchSingleTopWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void pop(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
+    method public void popWithTransition(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
+    method @CallSuper public void prepareForTransition(androidx.navigation.NavBackStackEntry entry);
+    method public void push(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void pushWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> transitionsInProgress;
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+    ctor public PopUpToBuilder();
+    method public boolean getInclusive();
+    method public boolean getSaveState();
+    method public void setInclusive(boolean);
+    method public void setSaveState(boolean);
+    property public final boolean inclusive;
+    property public final boolean saveState;
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-common/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-common/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-common/api/restricted_2.7.0-beta02.txt b/navigation/navigation-common/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..51a77a6
--- /dev/null
+++ b/navigation/navigation-common/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,530 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class ActionOnlyNavDirections implements androidx.navigation.NavDirections {
+    ctor public ActionOnlyNavDirections(int actionId);
+    method public int component1();
+    method public androidx.navigation.ActionOnlyNavDirections copy(int actionId);
+    method public int getActionId();
+    method public android.os.Bundle getArguments();
+    property public int actionId;
+    property public android.os.Bundle arguments;
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
+    ctor public AnimBuilder();
+    method public int getEnter();
+    method public int getExit();
+    method public int getPopEnter();
+    method public int getPopExit();
+    method public void setEnter(int);
+    method public void setExit(int);
+    method public void setPopEnter(int);
+    method public void setPopExit(int);
+    property public final int enter;
+    property public final int exit;
+    property public final int popEnter;
+    property public final int popExit;
+  }
+
+  public interface FloatingWindow {
+  }
+
+  public final class NamedNavArgument {
+    method public operator String component1();
+    method public operator androidx.navigation.NavArgument component2();
+    method public androidx.navigation.NavArgument getArgument();
+    method public String getName();
+    property public final androidx.navigation.NavArgument argument;
+    property public final String name;
+  }
+
+  public final class NamedNavArgumentKt {
+    method public static androidx.navigation.NamedNavArgument navArgument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavAction {
+    ctor public NavAction(@IdRes int destinationId);
+    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions);
+    ctor public NavAction(@IdRes int destinationId, optional androidx.navigation.NavOptions? navOptions, optional android.os.Bundle? defaultArguments);
+    method public android.os.Bundle? getDefaultArguments();
+    method public int getDestinationId();
+    method public androidx.navigation.NavOptions? getNavOptions();
+    method public void setDefaultArguments(android.os.Bundle?);
+    method public void setNavOptions(androidx.navigation.NavOptions?);
+    property public final android.os.Bundle? defaultArguments;
+    property public final int destinationId;
+    property public final androidx.navigation.NavOptions? navOptions;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+    ctor public NavActionBuilder();
+    method public java.util.Map<java.lang.String,java.lang.Object> getDefaultArguments();
+    method public int getDestinationId();
+    method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+    method public void setDestinationId(int);
+    property public final java.util.Map<java.lang.String,java.lang.Object> defaultArguments;
+    property public final int destinationId;
+  }
+
+  public interface NavArgs {
+  }
+
+  public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
+    ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
+    method public Args getValue();
+    method public boolean isInitialized();
+    property public Args value;
+  }
+
+  public final class NavArgument {
+    method public Object? getDefaultValue();
+    method public androidx.navigation.NavType<java.lang.Object> getType();
+    method public boolean isDefaultValuePresent();
+    method public boolean isNullable();
+    property public final Object? defaultValue;
+    property public final boolean isDefaultValuePresent;
+    property public final boolean isNullable;
+    property public final androidx.navigation.NavType<java.lang.Object> type;
+  }
+
+  public static final class NavArgument.Builder {
+    ctor public NavArgument.Builder();
+    method public androidx.navigation.NavArgument build();
+    method public androidx.navigation.NavArgument.Builder setDefaultValue(Object? defaultValue);
+    method public androidx.navigation.NavArgument.Builder setIsNullable(boolean isNullable);
+    method public <T> androidx.navigation.NavArgument.Builder setType(androidx.navigation.NavType<T> type);
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+    ctor public NavArgumentBuilder();
+    method public androidx.navigation.NavArgument build();
+    method public Object? getDefaultValue();
+    method public boolean getNullable();
+    method public androidx.navigation.NavType<?> getType();
+    method public void setDefaultValue(Object?);
+    method public void setNullable(boolean);
+    method public void setType(androidx.navigation.NavType<?>);
+    property public final Object? defaultValue;
+    property public final boolean nullable;
+    property public final androidx.navigation.NavType<?> type;
+  }
+
+  public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+    method public android.os.Bundle? getArguments();
+    method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+    method public androidx.navigation.NavDestination getDestination();
+    method public String getId();
+    method public androidx.lifecycle.Lifecycle getLifecycle();
+    method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
+    method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+    method public androidx.lifecycle.ViewModelStore getViewModelStore();
+    property public final android.os.Bundle? arguments;
+    property public androidx.lifecycle.viewmodel.CreationExtras defaultViewModelCreationExtras;
+    property public androidx.lifecycle.ViewModelProvider.Factory defaultViewModelProviderFactory;
+    property public final androidx.navigation.NavDestination destination;
+    property public final String id;
+    property public androidx.lifecycle.Lifecycle lifecycle;
+    property public final androidx.lifecycle.SavedStateHandle savedStateHandle;
+    property public androidx.savedstate.SavedStateRegistry savedStateRegistry;
+    property public androidx.lifecycle.ViewModelStore viewModelStore;
+  }
+
+  public final class NavDeepLink {
+    method public String? getAction();
+    method public String? getMimeType();
+    method public String? getUriPattern();
+    property public final String? action;
+    property public final String? mimeType;
+    property public final String? uriPattern;
+  }
+
+  public static final class NavDeepLink.Builder {
+    method public androidx.navigation.NavDeepLink build();
+    method public static androidx.navigation.NavDeepLink.Builder fromAction(String action);
+    method public static androidx.navigation.NavDeepLink.Builder fromMimeType(String mimeType);
+    method public static androidx.navigation.NavDeepLink.Builder fromUriPattern(String uriPattern);
+    method public androidx.navigation.NavDeepLink.Builder setAction(String action);
+    method public androidx.navigation.NavDeepLink.Builder setMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLink.Builder setUriPattern(String uriPattern);
+  }
+
+  @kotlin.DslMarker public @interface NavDeepLinkDsl {
+  }
+
+  @androidx.navigation.NavDeepLinkDsl public final class NavDeepLinkDslBuilder {
+    ctor public NavDeepLinkDslBuilder();
+    method public String? getAction();
+    method public String? getMimeType();
+    method public String? getUriPattern();
+    method public void setAction(String?);
+    method public void setMimeType(String?);
+    method public void setUriPattern(String?);
+    property public final String? action;
+    property public final String? mimeType;
+    property public final String? uriPattern;
+  }
+
+  public final class NavDeepLinkDslBuilderKt {
+    method public static androidx.navigation.NavDeepLink navDeepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> deepLinkBuilder);
+  }
+
+  public class NavDeepLinkRequest {
+    method public String? getAction();
+    method public String? getMimeType();
+    method public android.net.Uri? getUri();
+    property public String? action;
+    property public String? mimeType;
+    property public android.net.Uri? uri;
+  }
+
+  public static final class NavDeepLinkRequest.Builder {
+    method public androidx.navigation.NavDeepLinkRequest build();
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
+    method public static androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setAction(String action);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLinkRequest.Builder setUri(android.net.Uri uri);
+    field public static final androidx.navigation.NavDeepLinkRequest.Builder.Companion Companion;
+  }
+
+  public static final class NavDeepLinkRequest.Builder.Companion {
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromAction(String action);
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromMimeType(String mimeType);
+    method public androidx.navigation.NavDeepLinkRequest.Builder fromUri(android.net.Uri uri);
+  }
+
+  public class NavDestination {
+    ctor public NavDestination(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    ctor public NavDestination(String navigatorName);
+    method public final void addArgument(String argumentName, androidx.navigation.NavArgument argument);
+    method public final void addDeepLink(androidx.navigation.NavDeepLink navDeepLink);
+    method public final void addDeepLink(String uriPattern);
+    method public final String? fillInLabel(android.content.Context context, android.os.Bundle? bundle);
+    method public final androidx.navigation.NavAction? getAction(@IdRes int id);
+    method public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> getArguments();
+    method public static final kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
+    method @IdRes public final int getId();
+    method public final CharSequence? getLabel();
+    method public final String getNavigatorName();
+    method public final androidx.navigation.NavGraph? getParent();
+    method public final String? getRoute();
+    method public boolean hasDeepLink(android.net.Uri deepLink);
+    method public boolean hasDeepLink(androidx.navigation.NavDeepLinkRequest deepLinkRequest);
+    method @CallSuper public void onInflate(android.content.Context context, android.util.AttributeSet attrs);
+    method protected static final <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
+    method public final void putAction(@IdRes int actionId, androidx.navigation.NavAction action);
+    method public final void putAction(@IdRes int actionId, @IdRes int destId);
+    method public final void removeAction(@IdRes int actionId);
+    method public final void removeArgument(String argumentName);
+    method public final void setId(@IdRes int);
+    method public final void setLabel(CharSequence?);
+    method public final void setRoute(String?);
+    property public final java.util.Map<java.lang.String,androidx.navigation.NavArgument> arguments;
+    property @IdRes public final int id;
+    property public final CharSequence? label;
+    property public final String navigatorName;
+    property public final androidx.navigation.NavGraph? parent;
+    property public final String? route;
+    field public static final androidx.navigation.NavDestination.Companion Companion;
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface NavDestination.ClassType {
+    method public abstract kotlin.reflect.KClass<?> value();
+    property public abstract kotlin.reflect.KClass<?> value;
+  }
+
+  public static final class NavDestination.Companion {
+    method public kotlin.sequences.Sequence<androidx.navigation.NavDestination> getHierarchy(androidx.navigation.NavDestination);
+    method protected <C> Class<? extends C> parseClassFromName(android.content.Context context, String name, Class<? extends C> expectedClassType);
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+    ctor @Deprecated public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+    ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, String? route);
+    method @Deprecated public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+    method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
+    method public D build();
+    method public final void deepLink(String uriPattern);
+    method public final void deepLink(kotlin.jvm.functions.Function1<? super androidx.navigation.NavDeepLinkDslBuilder,kotlin.Unit> navDeepLink);
+    method public final int getId();
+    method public final CharSequence? getLabel();
+    method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+    method public final String? getRoute();
+    method public final void setLabel(CharSequence?);
+    property public final int id;
+    property public final CharSequence? label;
+    property protected final androidx.navigation.Navigator<? extends D> navigator;
+    property public final String? route;
+  }
+
+  @kotlin.DslMarker public @interface NavDestinationDsl {
+  }
+
+  public interface NavDirections {
+    method @IdRes public int getActionId();
+    method public android.os.Bundle getArguments();
+    property @IdRes public abstract int actionId;
+    property public abstract android.os.Bundle arguments;
+  }
+
+  public class NavGraph extends androidx.navigation.NavDestination implements java.lang.Iterable<androidx.navigation.NavDestination> kotlin.jvm.internal.markers.KMappedMarker {
+    ctor public NavGraph(androidx.navigation.Navigator<? extends androidx.navigation.NavGraph> navGraphNavigator);
+    method public final void addAll(androidx.navigation.NavGraph other);
+    method public final void addDestination(androidx.navigation.NavDestination node);
+    method public final void addDestinations(androidx.navigation.NavDestination... nodes);
+    method public final void addDestinations(java.util.Collection<? extends androidx.navigation.NavDestination> nodes);
+    method public final void clear();
+    method public final androidx.navigation.NavDestination? findNode(@IdRes int resId);
+    method public final androidx.navigation.NavDestination? findNode(String? route);
+    method public static final androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
+    method @Deprecated @IdRes public final int getStartDestination();
+    method @IdRes public final int getStartDestinationId();
+    method public final String? getStartDestinationRoute();
+    method public final java.util.Iterator<androidx.navigation.NavDestination> iterator();
+    method public final void remove(androidx.navigation.NavDestination node);
+    method public final void setStartDestination(int startDestId);
+    method public final void setStartDestination(String startDestRoute);
+    property @IdRes public final int startDestinationId;
+    property public final String? startDestinationRoute;
+    field public static final androidx.navigation.NavGraph.Companion Companion;
+  }
+
+  public static final class NavGraph.Companion {
+    method public androidx.navigation.NavDestination findStartDestination(androidx.navigation.NavGraph);
+  }
+
+  @androidx.navigation.NavDestinationDsl public class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+    ctor @Deprecated public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, String? route);
+    method public final void addDestination(androidx.navigation.NavDestination destination);
+    method public androidx.navigation.NavGraph build();
+    method public final <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+    method public final androidx.navigation.NavigatorProvider getProvider();
+    method public final operator void unaryPlus(androidx.navigation.NavDestination);
+    property public final androidx.navigation.NavigatorProvider provider;
+  }
+
+  public final class NavGraphBuilderKt {
+    method @Deprecated public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavGraphKt {
+    method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+    method public static operator boolean contains(androidx.navigation.NavGraph, String route);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+    method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, String route);
+    method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+    method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public class NavGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.NavGraph> {
+    ctor public NavGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public androidx.navigation.NavGraph createDestination();
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+  }
+
+  public final class NavOptions {
+    method @AnimRes @AnimatorRes public int getEnterAnim();
+    method @AnimRes @AnimatorRes public int getExitAnim();
+    method @AnimRes @AnimatorRes public int getPopEnterAnim();
+    method @AnimRes @AnimatorRes public int getPopExitAnim();
+    method @Deprecated @IdRes public int getPopUpTo();
+    method @IdRes public int getPopUpToId();
+    method public String? getPopUpToRoute();
+    method public boolean isPopUpToInclusive();
+    method public boolean shouldLaunchSingleTop();
+    method public boolean shouldPopUpToSaveState();
+    method public boolean shouldRestoreState();
+    property @AnimRes @AnimatorRes public final int enterAnim;
+    property @AnimRes @AnimatorRes public final int exitAnim;
+    property @AnimRes @AnimatorRes public final int popEnterAnim;
+    property @AnimRes @AnimatorRes public final int popExitAnim;
+    property @IdRes public final int popUpToId;
+    property public final String? popUpToRoute;
+  }
+
+  public static final class NavOptions.Builder {
+    ctor public NavOptions.Builder();
+    method public androidx.navigation.NavOptions build();
+    method public androidx.navigation.NavOptions.Builder setEnterAnim(@AnimRes @AnimatorRes int enterAnim);
+    method public androidx.navigation.NavOptions.Builder setExitAnim(@AnimRes @AnimatorRes int exitAnim);
+    method public androidx.navigation.NavOptions.Builder setLaunchSingleTop(boolean singleTop);
+    method public androidx.navigation.NavOptions.Builder setPopEnterAnim(@AnimRes @AnimatorRes int popEnterAnim);
+    method public androidx.navigation.NavOptions.Builder setPopExitAnim(@AnimRes @AnimatorRes int popExitAnim);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(@IdRes int destinationId, boolean inclusive, optional boolean saveState);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive);
+    method public androidx.navigation.NavOptions.Builder setPopUpTo(String? route, boolean inclusive, optional boolean saveState);
+    method public androidx.navigation.NavOptions.Builder setRestoreState(boolean restoreState);
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
+    ctor public NavOptionsBuilder();
+    method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
+    method public boolean getLaunchSingleTop();
+    method @Deprecated public int getPopUpTo();
+    method public int getPopUpToId();
+    method public String? getPopUpToRoute();
+    method public boolean getRestoreState();
+    method public void popUpTo(@IdRes int id, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void popUpTo(String route, optional kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+    method public void setLaunchSingleTop(boolean);
+    method @Deprecated public void setPopUpTo(int);
+    method public void setRestoreState(boolean);
+    property public final boolean launchSingleTop;
+    property @Deprecated public final int popUpTo;
+    property public final int popUpToId;
+    property public final String? popUpToRoute;
+    property public final boolean restoreState;
+  }
+
+  public final class NavOptionsBuilderKt {
+    method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+  }
+
+  @kotlin.DslMarker public @interface NavOptionsDsl {
+  }
+
+  public abstract class NavType<T> {
+    ctor public NavType(boolean isNullableAllowed);
+    method public static androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
+    method public abstract operator T? get(android.os.Bundle bundle, String key);
+    method public String getName();
+    method public boolean isNullableAllowed();
+    method public abstract T parseValue(String value);
+    method public T parseValue(String value, T previousValue);
+    method public abstract void put(android.os.Bundle bundle, String key, T value);
+    method public String serializeAsValue(T value);
+    property public boolean isNullableAllowed;
+    property public String name;
+    field public static final androidx.navigation.NavType<boolean[]> BoolArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Boolean> BoolType;
+    field public static final androidx.navigation.NavType.Companion Companion;
+    field public static final androidx.navigation.NavType<float[]> FloatArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Float> FloatType;
+    field public static final androidx.navigation.NavType<int[]> IntArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Integer> IntType;
+    field public static final androidx.navigation.NavType<long[]> LongArrayType;
+    field public static final androidx.navigation.NavType<java.lang.Long> LongType;
+    field public static final androidx.navigation.NavType<java.lang.Integer> ReferenceType;
+    field public static final androidx.navigation.NavType<java.lang.String[]> StringArrayType;
+    field public static final androidx.navigation.NavType<java.lang.String> StringType;
+  }
+
+  public static final class NavType.Companion {
+    method public androidx.navigation.NavType<?> fromArgType(String? type, String? packageName);
+  }
+
+  public static final class NavType.EnumType<D extends java.lang.Enum<?>> extends androidx.navigation.NavType.SerializableType<D> {
+    ctor public NavType.EnumType(Class<D> type);
+    property public String name;
+  }
+
+  public static final class NavType.ParcelableArrayType<D extends android.os.Parcelable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.ParcelableArrayType(Class<D> type);
+    method public D![]? get(android.os.Bundle bundle, String key);
+    method public D![] parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D![]? value);
+    property public String name;
+  }
+
+  public static final class NavType.ParcelableType<D> extends androidx.navigation.NavType<D> {
+    ctor public NavType.ParcelableType(Class<D> type);
+    method public D? get(android.os.Bundle bundle, String key);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
+    property public String name;
+  }
+
+  public static final class NavType.SerializableArrayType<D extends java.io.Serializable> extends androidx.navigation.NavType<D[]> {
+    ctor public NavType.SerializableArrayType(Class<D> type);
+    method public D![]? get(android.os.Bundle bundle, String key);
+    method public D![] parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D![]? value);
+    property public String name;
+  }
+
+  public static class NavType.SerializableType<D extends java.io.Serializable> extends androidx.navigation.NavType<D> {
+    ctor public NavType.SerializableType(Class<D> type);
+    method public D? get(android.os.Bundle bundle, String key);
+    method public D parseValue(String value);
+    method public void put(android.os.Bundle bundle, String key, D value);
+    property public String name;
+  }
+
+  public abstract class Navigator<D extends androidx.navigation.NavDestination> {
+    ctor public Navigator();
+    method public abstract D createDestination();
+    method protected final androidx.navigation.NavigatorState getState();
+    method public final boolean isAttached();
+    method public androidx.navigation.NavDestination? navigate(D destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method public void navigate(java.util.List<androidx.navigation.NavBackStackEntry> entries, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @CallSuper public void onAttach(androidx.navigation.NavigatorState state);
+    method public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void onRestoreState(android.os.Bundle savedState);
+    method public android.os.Bundle? onSaveState();
+    method public boolean popBackStack();
+    method public void popBackStack(androidx.navigation.NavBackStackEntry popUpTo, boolean savedState);
+    property public final boolean isAttached;
+    property protected final androidx.navigation.NavigatorState state;
+  }
+
+  public static interface Navigator.Extras {
+  }
+
+  @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.CLASS}) public static @interface Navigator.Name {
+    method public abstract String value();
+    property public abstract String value;
+  }
+
+  public class NavigatorProvider {
+    ctor public NavigatorProvider();
+    method public final androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method @CallSuper public androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? addNavigator(String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method public final <T extends androidx.navigation.Navigator<?>> T getNavigator(Class<T> navigatorClass);
+    method @CallSuper public <T extends androidx.navigation.Navigator<?>> T getNavigator(String name);
+  }
+
+  public final class NavigatorProviderKt {
+    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
+    method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
+    method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+    method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+  }
+
+  public abstract class NavigatorState {
+    ctor public NavigatorState();
+    method public abstract androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getBackStack();
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> getTransitionsInProgress();
+    method public void markTransitionComplete(androidx.navigation.NavBackStackEntry entry);
+    method @CallSuper public void onLaunchSingleTop(androidx.navigation.NavBackStackEntry backStackEntry);
+    method @CallSuper public void onLaunchSingleTopWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void pop(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
+    method public void popWithTransition(androidx.navigation.NavBackStackEntry popUpTo, boolean saveState);
+    method @CallSuper public void prepareForTransition(androidx.navigation.NavBackStackEntry entry);
+    method public void push(androidx.navigation.NavBackStackEntry backStackEntry);
+    method public void pushWithTransition(androidx.navigation.NavBackStackEntry backStackEntry);
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.Set<androidx.navigation.NavBackStackEntry>> transitionsInProgress;
+  }
+
+  @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+    ctor public PopUpToBuilder();
+    method public boolean getInclusive();
+    method public boolean getSaveState();
+    method public void setInclusive(boolean);
+    method public void setSaveState(boolean);
+    property public final boolean inclusive;
+    property public final boolean saveState;
+  }
+
+}
+
diff --git a/navigation/navigation-compose/api/2.7.0-beta02.txt b/navigation/navigation-compose/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..6794d3e
--- /dev/null
+++ b/navigation/navigation-compose/api/2.7.0-beta02.txt
@@ -0,0 +1,55 @@
+// Signature format: 4.0
+package androidx.navigation.compose {
+
+  @androidx.navigation.Navigator.Name("composable") public final class ComposeNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.ComposeNavigator.Destination> {
+    ctor public ComposeNavigator();
+    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);
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class ComposeNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor @Deprecated public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+  }
+
+  public final class DialogHostKt {
+    method @androidx.compose.runtime.Composable public static void DialogHost(androidx.navigation.compose.DialogNavigator dialogNavigator);
+  }
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.DialogNavigator.Destination> {
+    ctor public DialogNavigator();
+    method public androidx.navigation.compose.DialogNavigator.Destination createDestination();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class DialogNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
+    ctor public DialogNavigator.Destination(androidx.navigation.compose.DialogNavigator navigator, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+  }
+
+  public final class NavBackStackEntryProviderKt {
+    method @androidx.compose.runtime.Composable public static void LocalOwnersProvider(androidx.navigation.NavBackStackEntry, androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class NavGraphBuilderKt {
+    method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostControllerKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.navigation.NavBackStackEntry> currentBackStackEntryAsState(androidx.navigation.NavController);
+    method @androidx.compose.runtime.Composable public static androidx.navigation.NavHostController rememberNavController(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>... navigators);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-compose/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-compose/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-compose/api/restricted_2.7.0-beta02.txt b/navigation/navigation-compose/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..6794d3e
--- /dev/null
+++ b/navigation/navigation-compose/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,55 @@
+// Signature format: 4.0
+package androidx.navigation.compose {
+
+  @androidx.navigation.Navigator.Name("composable") public final class ComposeNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.ComposeNavigator.Destination> {
+    ctor public ComposeNavigator();
+    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);
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> backStack;
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class ComposeNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor @Deprecated public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    ctor public ComposeNavigator.Destination(androidx.navigation.compose.ComposeNavigator navigator, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+  }
+
+  public final class DialogHostKt {
+    method @androidx.compose.runtime.Composable public static void DialogHost(androidx.navigation.compose.DialogNavigator dialogNavigator);
+  }
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogNavigator extends androidx.navigation.Navigator<androidx.navigation.compose.DialogNavigator.Destination> {
+    ctor public DialogNavigator();
+    method public androidx.navigation.compose.DialogNavigator.Destination createDestination();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class DialogNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
+    ctor public DialogNavigator.Destination(androidx.navigation.compose.DialogNavigator navigator, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+  }
+
+  public final class NavBackStackEntryProviderKt {
+    method @androidx.compose.runtime.Composable public static void LocalOwnersProvider(androidx.navigation.NavBackStackEntry, androidx.compose.runtime.saveable.SaveableStateHolder saveableStateHolder, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+  }
+
+  public final class NavGraphBuilderKt {
+    method @Deprecated public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void composable(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition>? enterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition>? exitTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.EnterTransition>? popEnterTransition, optional kotlin.jvm.functions.Function1<androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,androidx.compose.animation.ExitTransition>? popExitTransition, kotlin.jvm.functions.Function2<? super androidx.compose.animation.AnimatedContentScope,? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void dialog(androidx.navigation.NavGraphBuilder, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional androidx.compose.ui.window.DialogProperties dialogProperties, kotlin.jvm.functions.Function1<? super androidx.navigation.NavBackStackEntry,kotlin.Unit> content);
+    method public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition>? enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition>? exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition>? popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition>? popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static void navigation(androidx.navigation.NavGraphBuilder, String startDestination, String route, optional java.util.List<androidx.navigation.NamedNavArgument> arguments, optional java.util.List<androidx.navigation.NavDeepLink> deepLinks, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostControllerKt {
+    method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.navigation.NavBackStackEntry> currentBackStackEntryAsState(androidx.navigation.NavController);
+    method @androidx.compose.runtime.Composable public static androidx.navigation.NavHostController rememberNavController(androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>... navigators);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, androidx.navigation.NavGraph graph, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition);
+    method @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.Alignment contentAlignment, optional String? route, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> enterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> exitTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.EnterTransition> popEnterTransition, optional kotlin.jvm.functions.Function1<? super androidx.compose.animation.AnimatedContentTransitionScope<androidx.navigation.NavBackStackEntry>,? extends androidx.compose.animation.ExitTransition> popExitTransition, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated @androidx.compose.runtime.Composable public static void NavHost(androidx.navigation.NavHostController navController, String startDestination, optional androidx.compose.ui.Modifier modifier, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+}
+
diff --git a/navigation/navigation-compose/build.gradle b/navigation/navigation-compose/build.gradle
index 8135fd5..e78d66f 100644
--- a/navigation/navigation-compose/build.gradle
+++ b/navigation/navigation-compose/build.gradle
@@ -27,12 +27,12 @@
 dependencies {
 
     implementation(libs.kotlinStdlib)
-    implementation("androidx.compose.foundation:foundation-layout:1.5.0-beta02")
+    implementation("androidx.compose.foundation:foundation-layout:1.5.0-beta03")
     api("androidx.activity:activity-compose:1.7.0")
-    api("androidx.compose.animation:animation:1.5.0-beta02")
-    api("androidx.compose.runtime:runtime:1.5.0-beta02")
-    api("androidx.compose.runtime:runtime-saveable:1.5.0-beta02")
-    api("androidx.compose.ui:ui:1.5.0-beta02")
+    api("androidx.compose.animation:animation:1.5.0-beta03")
+    api("androidx.compose.runtime:runtime:1.5.0-beta03")
+    api("androidx.compose.runtime:runtime-saveable:1.5.0-beta03")
+    api("androidx.compose.ui:ui:1.5.0-beta03")
     api("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
     api(projectOrArtifact(":navigation:navigation-runtime-ktx"))
 
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 8ffef75..47687128 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
@@ -244,6 +244,8 @@
         visibleEntries.lastOrNull()
     }
 
+    val zIndices = remember { mutableMapOf<String, Float>() }
+
     if (backStackEntry != null) {
         val finalEnter: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {
             val targetDestination = targetState.destination as ComposeNavigator.Destination
@@ -277,12 +279,19 @@
         transition.AnimatedContent(
             modifier,
             transitionSpec = {
-                val zIndex = composeNavigator.backStack.value.size.toFloat()
                 // If the initialState of the AnimatedContent is not in visibleEntries, we are in
                 // a case where visible has cleared the old state for some reason, so instead of
                 // attempting to animate away from the initialState, we skip the animation.
                 if (initialState in visibleEntries) {
-                    ContentTransform(finalEnter(this), finalExit(this), zIndex)
+                    val initialZIndex = zIndices[initialState.id]
+                        ?: 0f.also { zIndices[initialState.id] = 0f }
+                    val targetZIndex = when {
+                        targetState.id == initialState.id -> initialZIndex
+                        composeNavigator.isPop.value -> initialZIndex - 1f
+                        else -> initialZIndex + 1f
+                    }.also { zIndices[targetState.id] = it }
+
+                    ContentTransform(finalEnter(this), finalExit(this), targetZIndex)
                 } else {
                     EnterTransition.None togetherWith ExitTransition.None
                 }
@@ -314,6 +323,9 @@
             visibleEntries.forEach { entry ->
                 composeNavigator.onTransitionComplete(entry)
             }
+            zIndices
+                .filter { it.key != transition.targetState.id }
+                .forEach { zIndices.remove(it.key) }
         }
     }
 
diff --git a/navigation/navigation-dynamic-features-fragment/api/2.7.0-beta02.txt b/navigation/navigation-dynamic-features-fragment/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..adb3dae
--- /dev/null
+++ b/navigation/navigation-dynamic-features-fragment/api/2.7.0-beta02.txt
@@ -0,0 +1,69 @@
+// Signature format: 4.0
+package androidx.navigation.dynamicfeatures.fragment {
+
+  @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
+    ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
+  }
+
+  public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
+    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  public final class DynamicFragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
+    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
+    ctor public DynamicNavHostFragment();
+    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
+    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
+    field public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment.Companion Companion;
+  }
+
+  public static final class DynamicNavHostFragment.Companion {
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+  }
+
+}
+
+package androidx.navigation.dynamicfeatures.fragment.ui {
+
+  public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
+    ctor public AbstractProgressFragment();
+    ctor public AbstractProgressFragment(int contentLayoutId);
+    method protected abstract void onCancelled();
+    method protected abstract void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
+    method protected void onInstalled();
+    method protected abstract void onProgress(@com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus int status, long bytesDownloaded, long bytesTotal);
+  }
+
+  public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
+    ctor public DefaultProgressFragment();
+    method protected void onCancelled();
+    method protected void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
+    method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-dynamic-features-fragment/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-dynamic-features-fragment/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_2.7.0-beta02.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..adb3dae
--- /dev/null
+++ b/navigation/navigation-dynamic-features-fragment/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,69 @@
+// Signature format: 4.0
+package androidx.navigation.dynamicfeatures.fragment {
+
+  @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
+    ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
+  }
+
+  public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
+    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+    ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor @Deprecated public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, @IdRes int id, String fragmentClassName);
+    ctor public DynamicFragmentNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator navigator, String route, String fragmentClassName);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination build();
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  public final class DynamicFragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route);
+    method public static inline void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String fragmentClassName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
+    ctor public DynamicNavHostFragment();
+    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
+    method public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
+    field public static final androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment.Companion Companion;
+  }
+
+  public static final class DynamicNavHostFragment.Companion {
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId);
+    method public androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+  }
+
+}
+
+package androidx.navigation.dynamicfeatures.fragment.ui {
+
+  public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
+    ctor public AbstractProgressFragment();
+    ctor public AbstractProgressFragment(int contentLayoutId);
+    method protected abstract void onCancelled();
+    method protected abstract void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
+    method protected void onInstalled();
+    method protected abstract void onProgress(@com.google.android.play.core.splitinstall.model.SplitInstallSessionStatus int status, long bytesDownloaded, long bytesTotal);
+  }
+
+  public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
+    ctor public DefaultProgressFragment();
+    method protected void onCancelled();
+    method protected void onFailed(@com.google.android.play.core.splitinstall.model.SplitInstallErrorCode int errorCode);
+    method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
+  }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-runtime/api/2.7.0-beta02.txt b/navigation/navigation-dynamic-features-runtime/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..ff4252b
--- /dev/null
+++ b/navigation/navigation-dynamic-features-runtime/api/2.7.0-beta02.txt
@@ -0,0 +1,154 @@
+// Signature format: 4.0
+package androidx.navigation.dynamicfeatures {
+
+  @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
+    ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
+  }
+
+  public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
+    ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+    ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
+    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
+    method public String? getAction();
+    method public String? getActivityClassName();
+    method public android.net.Uri? getData();
+    method public String? getDataPattern();
+    method public String? getModuleName();
+    method public String? getTargetPackage();
+    method public void setAction(String?);
+    method public void setActivityClassName(String?);
+    method public void setData(android.net.Uri?);
+    method public void setDataPattern(String?);
+    method public void setModuleName(String?);
+    method public void setTargetPackage(String?);
+    property public final String? action;
+    property public final String? activityClassName;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final String? moduleName;
+    property public final String? targetPackage;
+  }
+
+  public final class DynamicActivityNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
+    ctor public DynamicExtras();
+    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor);
+    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor, optional androidx.navigation.Navigator.Extras? destinationExtras);
+    method public androidx.navigation.Navigator.Extras? getDestinationExtras();
+    method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
+    property public final androidx.navigation.Navigator.Extras? destinationExtras;
+    property public final androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor;
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
+    ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
+    method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
+  }
+
+  public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
+    ctor public DynamicGraphNavigator.DynamicNavGraph(androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public int getProgressDestination();
+    method public void setModuleName(String?);
+    method public void setProgressDestination(int);
+    property public final String? moduleName;
+    property public final int progressDestination;
+  }
+
+  @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+    ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
+  }
+
+  public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
+    method public String? getGraphPackage();
+    method public String? getGraphResourceName();
+    method public String? getModuleName();
+    method public void setGraphPackage(String?);
+    method public void setGraphResourceName(String?);
+    method public void setModuleName(String?);
+    property public final String? graphPackage;
+    property public final String? graphResourceName;
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
+    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
+    method public String? getGraphPackage();
+    method public void setGraphPackage(String?);
+    property public final String? graphPackage;
+  }
+
+  public final class DynamicIncludeNavGraphBuilderKt {
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
+    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public class DynamicInstallManager {
+    ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
+  }
+
+  public final class DynamicInstallMonitor {
+    ctor public DynamicInstallMonitor();
+    method public void cancelInstall();
+    method public Exception? getException();
+    method public int getSessionId();
+    method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
+    method public boolean isInstallRequired();
+    property public final Exception? exception;
+    property public final boolean isInstallRequired;
+    property public final int sessionId;
+    property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
+    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
+    method public String? getModuleName();
+    method public int getProgressDestination();
+    method public String? getProgressDestinationRoute();
+    method public void setModuleName(String?);
+    method public void setProgressDestination(int);
+    method public void setProgressDestinationRoute(String?);
+    property public final String? moduleName;
+    property public final int progressDestination;
+    property public final String? progressDestinationRoute;
+  }
+
+  public final class DynamicNavGraphBuilderKt {
+    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavControllerKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-dynamic-features-runtime/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-dynamic-features-runtime/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_2.7.0-beta02.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..ff4252b
--- /dev/null
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,154 @@
+// Signature format: 4.0
+package androidx.navigation.dynamicfeatures {
+
+  @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
+    ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
+  }
+
+  public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
+    ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+    ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public void setModuleName(String?);
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor @Deprecated public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, @IdRes int id);
+    ctor public DynamicActivityNavigatorDestinationBuilder(androidx.navigation.dynamicfeatures.DynamicActivityNavigator activityNavigator, String route);
+    method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination build();
+    method public String? getAction();
+    method public String? getActivityClassName();
+    method public android.net.Uri? getData();
+    method public String? getDataPattern();
+    method public String? getModuleName();
+    method public String? getTargetPackage();
+    method public void setAction(String?);
+    method public void setActivityClassName(String?);
+    method public void setData(android.net.Uri?);
+    method public void setDataPattern(String?);
+    method public void setModuleName(String?);
+    method public void setTargetPackage(String?);
+    property public final String? action;
+    property public final String? activityClassName;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final String? moduleName;
+    property public final String? targetPackage;
+  }
+
+  public final class DynamicActivityNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline void activity(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
+    ctor public DynamicExtras();
+    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor);
+    ctor public DynamicExtras(optional androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor, optional androidx.navigation.Navigator.Extras? destinationExtras);
+    method public androidx.navigation.Navigator.Extras? getDestinationExtras();
+    method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
+    property public final androidx.navigation.Navigator.Extras? destinationExtras;
+    property public final androidx.navigation.dynamicfeatures.DynamicInstallMonitor? installMonitor;
+  }
+
+  @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
+    ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
+    method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
+  }
+
+  public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
+    ctor public DynamicGraphNavigator.DynamicNavGraph(androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, androidx.navigation.NavigatorProvider navigatorProvider);
+    method public String? getModuleName();
+    method public int getProgressDestination();
+    method public void setModuleName(String?);
+    method public void setProgressDestination(int);
+    property public final String? moduleName;
+    property public final int progressDestination;
+  }
+
+  @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+    ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
+  }
+
+  public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
+    method public String? getGraphPackage();
+    method public String? getGraphResourceName();
+    method public String? getModuleName();
+    method public void setGraphPackage(String?);
+    method public void setGraphResourceName(String?);
+    method public void setModuleName(String?);
+    property public final String? graphPackage;
+    property public final String? graphResourceName;
+    property public final String? moduleName;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicIncludeNavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+    ctor @Deprecated public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, @IdRes int id, String moduleName, String graphResourceName);
+    ctor public DynamicIncludeNavGraphBuilder(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator dynamicIncludeGraphNavigator, String route, String moduleName, String graphResourceName);
+    method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph build();
+    method public String? getGraphPackage();
+    method public void setGraphPackage(String?);
+    property public final String? graphPackage;
+  }
+
+  public final class DynamicIncludeNavGraphBuilderKt {
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName);
+    method @Deprecated public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName);
+    method public static inline void includeDynamic(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String route, String moduleName, String graphResourceName, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicIncludeNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public class DynamicInstallManager {
+    ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
+  }
+
+  public final class DynamicInstallMonitor {
+    ctor public DynamicInstallMonitor();
+    method public void cancelInstall();
+    method public Exception? getException();
+    method public int getSessionId();
+    method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
+    method public boolean isInstallRequired();
+    property public final Exception? exception;
+    property public final boolean isInstallRequired;
+    property public final int sessionId;
+    property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DynamicNavGraphBuilder extends androidx.navigation.NavGraphBuilder {
+    ctor @Deprecated public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+    ctor public DynamicNavGraphBuilder(androidx.navigation.NavigatorProvider provider, String startDestination, optional String? route);
+    method public String? getModuleName();
+    method public int getProgressDestination();
+    method public String? getProgressDestinationRoute();
+    method public void setModuleName(String?);
+    method public void setProgressDestination(int);
+    method public void setProgressDestinationRoute(String?);
+    property public final String? moduleName;
+    property public final int progressDestination;
+    property public final String? progressDestinationRoute;
+  }
+
+  public final class DynamicNavGraphBuilderKt {
+    method @Deprecated public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline void navigation(androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder, String startDestination, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method @Deprecated public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavControllerKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.dynamicfeatures.DynamicNavGraphBuilder,kotlin.Unit> builder);
+  }
+
+}
+
diff --git a/navigation/navigation-fragment-ktx/api/2.7.0-beta02.txt b/navigation/navigation-fragment-ktx/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-fragment-ktx/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-fragment-ktx/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-fragment-ktx/api/restricted_2.7.0-beta02.txt b/navigation/navigation-fragment-ktx/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/navigation/navigation-fragment/api/2.7.0-beta02.txt b/navigation/navigation-fragment/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..e9cbc61
--- /dev/null
+++ b/navigation/navigation-fragment/api/2.7.0-beta02.txt
@@ -0,0 +1,125 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class NavGraphViewModelLazyKt {
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+  }
+
+}
+
+package androidx.navigation.fragment {
+
+  public abstract class AbstractListDetailFragment extends androidx.fragment.app.Fragment {
+    ctor public AbstractListDetailFragment();
+    method public final androidx.navigation.fragment.NavHostFragment getDetailPaneNavHostFragment();
+    method public final androidx.slidingpanelayout.widget.SlidingPaneLayout getSlidingPaneLayout();
+    method public androidx.navigation.fragment.NavHostFragment onCreateDetailPaneNavHostFragment();
+    method public abstract android.view.View onCreateListPaneView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
+    method @CallSuper public final android.view.View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
+    method public void onListPaneViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
+    method @CallSuper public final void onViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
+    property public final androidx.navigation.fragment.NavHostFragment detailPaneNavHostFragment;
+    property public final androidx.slidingpanelayout.widget.SlidingPaneLayout slidingPaneLayout;
+  }
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(DialogFragment::class) public static class DialogFragmentNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination> fragmentNavigator);
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String className);
+    property public final String className;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+  }
+
+  public final class DialogFragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class FragmentKt {
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavArgsLazyKt {
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+  }
+
+  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
+    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String className);
+    property public final String className;
+  }
+
+  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public java.util.Map<android.view.View,java.lang.String> getSharedElements();
+    property public final java.util.Map<android.view.View,java.lang.String> sharedElements;
+  }
+
+  public static final class FragmentNavigator.Extras.Builder {
+    ctor public FragmentNavigator.Extras.Builder();
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View sharedElement, String name);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View,java.lang.String> sharedElements);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+  }
+
+  public final class FragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class FragmentNavigatorExtrasKt {
+    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+  }
+
+  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
+    ctor public NavHostFragment();
+    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
+    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
+    method public static final androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
+    method public final androidx.navigation.NavController getNavController();
+    method @Deprecated @CallSuper protected void onCreateNavController(androidx.navigation.NavController navController);
+    method @CallSuper protected void onCreateNavHostController(androidx.navigation.NavHostController navHostController);
+    property public final androidx.navigation.NavController navController;
+    field public static final androidx.navigation.fragment.NavHostFragment.Companion Companion;
+  }
+
+  public static final class NavHostFragment.Companion {
+    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
+    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method public androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-fragment/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-fragment/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-fragment/api/restricted_2.7.0-beta02.txt b/navigation/navigation-fragment/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..e9cbc61
--- /dev/null
+++ b/navigation/navigation-fragment/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,125 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class NavGraphViewModelLazyKt {
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.viewmodel.CreationExtras>? extrasProducer, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+    method @Deprecated @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, String navGraphRoute, optional kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer);
+  }
+
+}
+
+package androidx.navigation.fragment {
+
+  public abstract class AbstractListDetailFragment extends androidx.fragment.app.Fragment {
+    ctor public AbstractListDetailFragment();
+    method public final androidx.navigation.fragment.NavHostFragment getDetailPaneNavHostFragment();
+    method public final androidx.slidingpanelayout.widget.SlidingPaneLayout getSlidingPaneLayout();
+    method public androidx.navigation.fragment.NavHostFragment onCreateDetailPaneNavHostFragment();
+    method public abstract android.view.View onCreateListPaneView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
+    method @CallSuper public final android.view.View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup? container, android.os.Bundle? savedInstanceState);
+    method public void onListPaneViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
+    method @CallSuper public final void onViewCreated(android.view.View view, android.os.Bundle? savedInstanceState);
+    property public final androidx.navigation.fragment.NavHostFragment detailPaneNavHostFragment;
+    property public final androidx.slidingpanelayout.widget.SlidingPaneLayout slidingPaneLayout;
+  }
+
+  @androidx.navigation.Navigator.Name("dialog") public final class DialogFragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor public DialogFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination createDestination();
+  }
+
+  @androidx.navigation.NavDestination.ClassType(DialogFragment::class) public static class DialogFragmentNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow {
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.DialogFragmentNavigator.Destination> fragmentNavigator);
+    ctor public DialogFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.DialogFragmentNavigator.Destination setClassName(String className);
+    property public final String className;
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+    ctor @Deprecated public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+    method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+  }
+
+  public final class DialogFragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class FragmentKt {
+    method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+  }
+
+  public final class FragmentNavArgsLazyKt {
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+  }
+
+  @androidx.navigation.Navigator.Name("fragment") public class FragmentNavigator extends androidx.navigation.Navigator<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor public FragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, int containerId);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination createDestination();
+    method @Deprecated public androidx.fragment.app.Fragment instantiateFragment(android.content.Context context, androidx.fragment.app.FragmentManager fragmentManager, String className, android.os.Bundle? args);
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Fragment::class) public static class FragmentNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public FragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+    ctor public FragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String getClassName();
+    method public final androidx.navigation.fragment.FragmentNavigator.Destination setClassName(String className);
+    property public final String className;
+  }
+
+  public static final class FragmentNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public java.util.Map<android.view.View,java.lang.String> getSharedElements();
+    property public final java.util.Map<android.view.View,java.lang.String> sharedElements;
+  }
+
+  public static final class FragmentNavigator.Extras.Builder {
+    ctor public FragmentNavigator.Extras.Builder();
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElement(android.view.View sharedElement, String name);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras.Builder addSharedElements(java.util.Map<android.view.View,java.lang.String> sharedElements);
+    method public androidx.navigation.fragment.FragmentNavigator.Extras build();
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+    ctor @Deprecated public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, String route, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+    method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+  }
+
+  public final class FragmentNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+    method @Deprecated public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route);
+    method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class FragmentNavigatorExtrasKt {
+    method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+  }
+
+  public class NavHostFragment extends androidx.fragment.app.Fragment implements androidx.navigation.NavHost {
+    ctor public NavHostFragment();
+    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
+    method public static final androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method @Deprecated protected androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> createFragmentNavigator();
+    method public static final androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
+    method public final androidx.navigation.NavController getNavController();
+    method @Deprecated @CallSuper protected void onCreateNavController(androidx.navigation.NavController navController);
+    method @CallSuper protected void onCreateNavHostController(androidx.navigation.NavHostController navHostController);
+    property public final androidx.navigation.NavController navController;
+    field public static final androidx.navigation.fragment.NavHostFragment.Companion Companion;
+  }
+
+  public static final class NavHostFragment.Companion {
+    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId);
+    method public androidx.navigation.fragment.NavHostFragment create(@NavigationRes int graphResId, optional android.os.Bundle? startDestinationArgs);
+    method public androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment fragment);
+  }
+
+}
+
diff --git a/navigation/navigation-runtime-ktx/api/2.7.0-beta02.txt b/navigation/navigation-runtime-ktx/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-runtime-ktx/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-runtime-ktx/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-runtime-ktx/api/restricted_2.7.0-beta02.txt b/navigation/navigation-runtime-ktx/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/navigation/navigation-runtime/api/2.7.0-beta02.txt b/navigation/navigation-runtime/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..2ec837e
--- /dev/null
+++ b/navigation/navigation-runtime/api/2.7.0-beta02.txt
@@ -0,0 +1,229 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class ActivityKt {
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+  }
+
+  public final class ActivityNavArgsLazyKt {
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+  }
+
+  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigator(android.content.Context context);
+    method public static final void applyPopAnimationsToPendingTransition(android.app.Activity activity);
+    method public androidx.navigation.ActivityNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    field public static final androidx.navigation.ActivityNavigator.Companion Companion;
+  }
+
+  public static final class ActivityNavigator.Companion {
+    method public void applyPopAnimationsToPendingTransition(android.app.Activity activity);
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Activity::class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String? getAction();
+    method public final android.content.ComponentName? getComponent();
+    method public final android.net.Uri? getData();
+    method public final String? getDataPattern();
+    method public final android.content.Intent? getIntent();
+    method public final String? getTargetPackage();
+    method public final androidx.navigation.ActivityNavigator.Destination setAction(String? action);
+    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName? name);
+    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri? data);
+    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String? dataPattern);
+    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent? intent);
+    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String? packageName);
+    property public final String? action;
+    property public final android.content.ComponentName? component;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final android.content.Intent? intent;
+    property public final String? targetPackage;
+  }
+
+  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+    method public int getFlags();
+    property public final androidx.core.app.ActivityOptionsCompat? activityOptions;
+    property public final int flags;
+  }
+
+  public static final class ActivityNavigator.Extras.Builder {
+    ctor public ActivityNavigator.Extras.Builder();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int flags);
+    method public androidx.navigation.ActivityNavigator.Extras build();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat activityOptions);
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
+    method public androidx.navigation.ActivityNavigator.Destination build();
+    method public String? getAction();
+    method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
+    method public android.net.Uri? getData();
+    method public String? getDataPattern();
+    method public String? getTargetPackage();
+    method public void setAction(String?);
+    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>?);
+    method public void setData(android.net.Uri?);
+    method public void setDataPattern(String?);
+    method public void setTargetPackage(String?);
+    property public final String? action;
+    property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final String? targetPackage;
+  }
+
+  public final class ActivityNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ActivityNavigatorExtrasKt {
+    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(optional androidx.core.app.ActivityOptionsCompat? activityOptions, optional int flags);
+  }
+
+  public class NavController {
+    ctor public NavController(android.content.Context context);
+    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
+    method @MainThread public final boolean clearBackStack(@IdRes int destinationId);
+    method @MainThread public final boolean clearBackStack(String route);
+    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method @androidx.navigation.NavDeepLinkSaveStateControl public static final void enableDeepLinkSaveState(boolean saveState);
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int destinationId);
+    method public final androidx.navigation.NavBackStackEntry getBackStackEntry(String route);
+    method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
+    method public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> getCurrentBackStackEntryFlow();
+    method public androidx.navigation.NavDestination? getCurrentDestination();
+    method @MainThread public androidx.navigation.NavGraph getGraph();
+    method public androidx.navigation.NavInflater getNavInflater();
+    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+    method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
+    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int navGraphId);
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getVisibleEntries();
+    method @MainThread public boolean handleDeepLink(android.content.Intent? intent);
+    method @MainThread public void navigate(android.net.Uri deepLink);
+    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.Navigator.Extras navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(@IdRes int resId);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public final void navigate(String route);
+    method @MainThread public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions);
+    method @MainThread public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions, optional androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public final void navigate(String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> builder);
+    method @MainThread public boolean navigateUp();
+    method @MainThread public boolean popBackStack();
+    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive);
+    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive, boolean saveState);
+    method @MainThread public final boolean popBackStack(String route, boolean inclusive);
+    method @MainThread public final boolean popBackStack(String route, boolean inclusive, optional boolean saveState);
+    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
+    method @CallSuper public void restoreState(android.os.Bundle? navState);
+    method @CallSuper public android.os.Bundle? saveState();
+    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph);
+    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph graph, android.os.Bundle? startDestinationArgs);
+    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId);
+    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId, android.os.Bundle? startDestinationArgs);
+    property public androidx.navigation.NavBackStackEntry? currentBackStackEntry;
+    property public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> currentBackStackEntryFlow;
+    property public androidx.navigation.NavDestination? currentDestination;
+    property @MainThread public androidx.navigation.NavGraph graph;
+    property public androidx.navigation.NavInflater navInflater;
+    property public androidx.navigation.NavigatorProvider navigatorProvider;
+    property public androidx.navigation.NavBackStackEntry? previousBackStackEntry;
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> visibleEntries;
+    field public static final androidx.navigation.NavController.Companion Companion;
+    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+  }
+
+  public static final class NavController.Companion {
+    method @androidx.navigation.NavDeepLinkSaveStateControl public void enableDeepLinkSaveState(boolean saveState);
+  }
+
+  public static fun interface NavController.OnDestinationChangedListener {
+    method public void onDestinationChanged(androidx.navigation.NavController controller, androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+  }
+
+  public final class NavControllerKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavDeepLinkBuilder {
+    ctor public NavDeepLinkBuilder(android.content.Context context);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route, optional android.os.Bundle? args);
+    method public android.app.PendingIntent createPendingIntent();
+    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName componentName);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity> activityClass);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph navGraph);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int navGraphId);
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavDeepLinkSaveStateControl {
+  }
+
+  public interface NavHost {
+    method public androidx.navigation.NavController getNavController();
+    property public abstract androidx.navigation.NavController navController;
+  }
+
+  public class NavHostController extends androidx.navigation.NavController {
+    ctor public NavHostController(android.content.Context context);
+    method public final void enableOnBackPressed(boolean enabled);
+    method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner owner);
+    method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher dispatcher);
+    method public final void setViewModelStore(androidx.lifecycle.ViewModelStore viewModelStore);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavInflater {
+    ctor public NavInflater(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider);
+    method public androidx.navigation.NavGraph inflate(@NavigationRes int graphResId);
+    field public static final androidx.navigation.NavInflater.Companion Companion;
+  }
+
+  public static final class NavInflater.Companion {
+  }
+
+  public final class Navigation {
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections directions);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId, optional android.os.Bundle? args);
+    method public static androidx.navigation.NavController findNavController(android.app.Activity activity, @IdRes int viewId);
+    method public static androidx.navigation.NavController findNavController(android.view.View view);
+    method public static void setViewNavController(android.view.View view, androidx.navigation.NavController? controller);
+    field public static final androidx.navigation.Navigation INSTANCE;
+  }
+
+  public final class ViewKt {
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-runtime/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-runtime/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-runtime/api/restricted_2.7.0-beta02.txt b/navigation/navigation-runtime/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..2ec837e
--- /dev/null
+++ b/navigation/navigation-runtime/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,229 @@
+// Signature format: 4.0
+package androidx.navigation {
+
+  public final class ActivityKt {
+    method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+  }
+
+  public final class ActivityNavArgsLazyKt {
+    method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+  }
+
+  @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+    ctor public ActivityNavigator(android.content.Context context);
+    method public static final void applyPopAnimationsToPendingTransition(android.app.Activity activity);
+    method public androidx.navigation.ActivityNavigator.Destination createDestination();
+    method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    field public static final androidx.navigation.ActivityNavigator.Companion Companion;
+  }
+
+  public static final class ActivityNavigator.Companion {
+    method public void applyPopAnimationsToPendingTransition(android.app.Activity activity);
+  }
+
+  @androidx.navigation.NavDestination.ClassType(Activity::class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+    ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+    ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+    method public final String? getAction();
+    method public final android.content.ComponentName? getComponent();
+    method public final android.net.Uri? getData();
+    method public final String? getDataPattern();
+    method public final android.content.Intent? getIntent();
+    method public final String? getTargetPackage();
+    method public final androidx.navigation.ActivityNavigator.Destination setAction(String? action);
+    method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName? name);
+    method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri? data);
+    method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String? dataPattern);
+    method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent? intent);
+    method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String? packageName);
+    property public final String? action;
+    property public final android.content.ComponentName? component;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final android.content.Intent? intent;
+    property public final String? targetPackage;
+  }
+
+  public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+    method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+    method public int getFlags();
+    property public final androidx.core.app.ActivityOptionsCompat? activityOptions;
+    property public final int flags;
+  }
+
+  public static final class ActivityNavigator.Extras.Builder {
+    ctor public ActivityNavigator.Extras.Builder();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int flags);
+    method public androidx.navigation.ActivityNavigator.Extras build();
+    method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat activityOptions);
+  }
+
+  @androidx.navigation.NavDestinationDsl public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+    ctor @Deprecated public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+    ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, String route);
+    method public androidx.navigation.ActivityNavigator.Destination build();
+    method public String? getAction();
+    method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
+    method public android.net.Uri? getData();
+    method public String? getDataPattern();
+    method public String? getTargetPackage();
+    method public void setAction(String?);
+    method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>?);
+    method public void setData(android.net.Uri?);
+    method public void setDataPattern(String?);
+    method public void setTargetPackage(String?);
+    property public final String? action;
+    property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
+    property public final android.net.Uri? data;
+    property public final String? dataPattern;
+    property public final String? targetPackage;
+  }
+
+  public final class ActivityNavigatorDestinationBuilderKt {
+    method @Deprecated public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+    method public static inline void activity(androidx.navigation.NavGraphBuilder, String route, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+  }
+
+  public final class ActivityNavigatorExtrasKt {
+    method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(optional androidx.core.app.ActivityOptionsCompat? activityOptions, optional int flags);
+  }
+
+  public class NavController {
+    ctor public NavController(android.content.Context context);
+    method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
+    method @MainThread public final boolean clearBackStack(@IdRes int destinationId);
+    method @MainThread public final boolean clearBackStack(String route);
+    method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+    method @androidx.navigation.NavDeepLinkSaveStateControl public static final void enableDeepLinkSaveState(boolean saveState);
+    method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int destinationId);
+    method public final androidx.navigation.NavBackStackEntry getBackStackEntry(String route);
+    method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
+    method public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> getCurrentBackStackEntryFlow();
+    method public androidx.navigation.NavDestination? getCurrentDestination();
+    method @MainThread public androidx.navigation.NavGraph getGraph();
+    method public androidx.navigation.NavInflater getNavInflater();
+    method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+    method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
+    method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int navGraphId);
+    method public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> getVisibleEntries();
+    method @MainThread public boolean handleDeepLink(android.content.Intent? intent);
+    method @MainThread public void navigate(android.net.Uri deepLink);
+    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(android.net.Uri deepLink, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(androidx.navigation.NavDeepLinkRequest request, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.Navigator.Extras navigatorExtras);
+    method @MainThread public void navigate(androidx.navigation.NavDirections directions, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(@IdRes int resId);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions);
+    method @MainThread public void navigate(@IdRes int resId, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public final void navigate(String route);
+    method @MainThread public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions);
+    method @MainThread public final void navigate(String route, optional androidx.navigation.NavOptions? navOptions, optional androidx.navigation.Navigator.Extras? navigatorExtras);
+    method @MainThread public final void navigate(String route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> builder);
+    method @MainThread public boolean navigateUp();
+    method @MainThread public boolean popBackStack();
+    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive);
+    method @MainThread public boolean popBackStack(@IdRes int destinationId, boolean inclusive, boolean saveState);
+    method @MainThread public final boolean popBackStack(String route, boolean inclusive);
+    method @MainThread public final boolean popBackStack(String route, boolean inclusive, optional boolean saveState);
+    method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener listener);
+    method @CallSuper public void restoreState(android.os.Bundle? navState);
+    method @CallSuper public android.os.Bundle? saveState();
+    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph);
+    method @CallSuper @MainThread public void setGraph(androidx.navigation.NavGraph graph, android.os.Bundle? startDestinationArgs);
+    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId);
+    method @CallSuper @MainThread public void setGraph(@NavigationRes int graphResId, android.os.Bundle? startDestinationArgs);
+    property public androidx.navigation.NavBackStackEntry? currentBackStackEntry;
+    property public final kotlinx.coroutines.flow.Flow<androidx.navigation.NavBackStackEntry> currentBackStackEntryFlow;
+    property public androidx.navigation.NavDestination? currentDestination;
+    property @MainThread public androidx.navigation.NavGraph graph;
+    property public androidx.navigation.NavInflater navInflater;
+    property public androidx.navigation.NavigatorProvider navigatorProvider;
+    property public androidx.navigation.NavBackStackEntry? previousBackStackEntry;
+    property public final kotlinx.coroutines.flow.StateFlow<java.util.List<androidx.navigation.NavBackStackEntry>> visibleEntries;
+    field public static final androidx.navigation.NavController.Companion Companion;
+    field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+  }
+
+  public static final class NavController.Companion {
+    method @androidx.navigation.NavDeepLinkSaveStateControl public void enableDeepLinkSaveState(boolean saveState);
+  }
+
+  public static fun interface NavController.OnDestinationChangedListener {
+    method public void onDestinationChanged(androidx.navigation.NavController controller, androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+  }
+
+  public final class NavControllerKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavDeepLinkBuilder {
+    ctor public NavDeepLinkBuilder(android.content.Context context);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(@IdRes int destId, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route);
+    method public androidx.navigation.NavDeepLinkBuilder addDestination(String route, optional android.os.Bundle? args);
+    method public android.app.PendingIntent createPendingIntent();
+    method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+    method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName componentName);
+    method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity> activityClass);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int destId, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute);
+    method public androidx.navigation.NavDeepLinkBuilder setDestination(String destRoute, optional android.os.Bundle? args);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph navGraph);
+    method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int navGraphId);
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavDeepLinkSaveStateControl {
+  }
+
+  public interface NavHost {
+    method public androidx.navigation.NavController getNavController();
+    property public abstract androidx.navigation.NavController navController;
+  }
+
+  public class NavHostController extends androidx.navigation.NavController {
+    ctor public NavHostController(android.content.Context context);
+    method public final void enableOnBackPressed(boolean enabled);
+    method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner owner);
+    method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher dispatcher);
+    method public final void setViewModelStore(androidx.lifecycle.ViewModelStore viewModelStore);
+  }
+
+  public final class NavHostKt {
+    method @Deprecated public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, optional @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+    method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, String startDestination, optional String? route, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+  }
+
+  public final class NavInflater {
+    ctor public NavInflater(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider);
+    method public androidx.navigation.NavGraph inflate(@NavigationRes int graphResId);
+    field public static final androidx.navigation.NavInflater.Companion Companion;
+  }
+
+  public static final class NavInflater.Companion {
+  }
+
+  public final class Navigation {
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections directions);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId);
+    method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int resId, optional android.os.Bundle? args);
+    method public static androidx.navigation.NavController findNavController(android.app.Activity activity, @IdRes int viewId);
+    method public static androidx.navigation.NavController findNavController(android.view.View view);
+    method public static void setViewNavController(android.view.View view, androidx.navigation.NavController? controller);
+    field public static final androidx.navigation.Navigation INSTANCE;
+  }
+
+  public final class ViewKt {
+    method public static androidx.navigation.NavController findNavController(android.view.View);
+  }
+
+}
+
diff --git a/navigation/navigation-testing/api/2.7.0-beta02.txt b/navigation/navigation-testing/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..90caa3a
--- /dev/null
+++ b/navigation/navigation-testing/api/2.7.0-beta02.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.navigation.testing {
+
+  public final class TestNavHostController extends androidx.navigation.NavHostController {
+    ctor public TestNavHostController(android.content.Context context);
+    method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
+    method public void setCurrentDestination(@IdRes int destId);
+    method public void setCurrentDestination(@IdRes int destId, optional android.os.Bundle args);
+    method public void setCurrentDestination(String destRoute);
+    method public void setCurrentDestination(String destRoute, optional android.os.Bundle args);
+    property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
+  }
+
+  public final class TestNavigatorState extends androidx.navigation.NavigatorState {
+    ctor public TestNavigatorState();
+    ctor public TestNavigatorState(optional android.content.Context? context);
+    ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+    method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-testing/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-testing/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-testing/api/restricted_2.7.0-beta02.txt b/navigation/navigation-testing/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..90caa3a
--- /dev/null
+++ b/navigation/navigation-testing/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,23 @@
+// Signature format: 4.0
+package androidx.navigation.testing {
+
+  public final class TestNavHostController extends androidx.navigation.NavHostController {
+    ctor public TestNavHostController(android.content.Context context);
+    method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
+    method public void setCurrentDestination(@IdRes int destId);
+    method public void setCurrentDestination(@IdRes int destId, optional android.os.Bundle args);
+    method public void setCurrentDestination(String destRoute);
+    method public void setCurrentDestination(String destRoute, optional android.os.Bundle args);
+    property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
+  }
+
+  public final class TestNavigatorState extends androidx.navigation.NavigatorState {
+    ctor public TestNavigatorState();
+    ctor public TestNavigatorState(optional android.content.Context? context);
+    ctor public TestNavigatorState(optional android.content.Context? context, optional kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public androidx.navigation.NavBackStackEntry createBackStackEntry(androidx.navigation.NavDestination destination, android.os.Bundle? arguments);
+    method public androidx.navigation.NavBackStackEntry restoreBackStackEntry(androidx.navigation.NavBackStackEntry previouslySavedEntry);
+  }
+
+}
+
diff --git a/navigation/navigation-ui-ktx/api/2.7.0-beta02.txt b/navigation/navigation-ui-ktx/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/navigation/navigation-ui-ktx/api/res-2.7.0-beta02.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to navigation/navigation-ui-ktx/api/res-2.7.0-beta02.txt
diff --git a/navigation/navigation-ui-ktx/api/restricted_2.7.0-beta02.txt b/navigation/navigation-ui-ktx/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/navigation/navigation-ui/api/2.7.0-beta02.txt b/navigation/navigation-ui/api/2.7.0-beta02.txt
new file mode 100644
index 0000000..5094c7e
--- /dev/null
+++ b/navigation/navigation-ui/api/2.7.0-beta02.txt
@@ -0,0 +1,94 @@
+// Signature format: 4.0
+package androidx.navigation.ui {
+
+  public final class ActivityKt {
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+  public final class AppBarConfiguration {
+    method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+    method public androidx.customview.widget.Openable? getOpenableLayout();
+    method public java.util.Set<java.lang.Integer> getTopLevelDestinations();
+    method public boolean isTopLevelDestination(androidx.navigation.NavDestination destination);
+    property @Deprecated public final androidx.drawerlayout.widget.DrawerLayout? drawerLayout;
+    property public final androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener;
+    property public final androidx.customview.widget.Openable? openableLayout;
+    property public final java.util.Set<java.lang.Integer> topLevelDestinations;
+  }
+
+  public static final class AppBarConfiguration.Builder {
+    ctor public AppBarConfiguration.Builder(android.view.Menu topLevelMenu);
+    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph navGraph);
+    ctor public AppBarConfiguration.Builder(int... topLevelDestinationIds);
+    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer> topLevelDestinationIds);
+    method public androidx.navigation.ui.AppBarConfiguration build();
+    method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable? openableLayout);
+  }
+
+  public static fun interface AppBarConfiguration.OnNavigateUpListener {
+    method public boolean onNavigateUp();
+  }
+
+  public final class AppBarConfigurationKt {
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+  }
+
+  public final class BottomNavigationViewKt {
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView, androidx.navigation.NavController navController);
+  }
+
+  public final class CollapsingToolbarLayoutKt {
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+  public final class MenuItemKt {
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+  }
+
+  public final class NavControllerKt {
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+  }
+
+  public final class NavigationUI {
+    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController, boolean saveState);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController, boolean saveState);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController, boolean saveState);
+    field public static final androidx.navigation.ui.NavigationUI INSTANCE;
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavigationUiSaveStateControl {
+  }
+
+  public final class NavigationViewKt {
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class ToolbarKt {
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+}
+
diff --git a/navigation/navigation-ui/api/res-2.7.0-beta02.txt b/navigation/navigation-ui/api/res-2.7.0-beta02.txt
new file mode 100644
index 0000000..e65fdbe
--- /dev/null
+++ b/navigation/navigation-ui/api/res-2.7.0-beta02.txt
@@ -0,0 +1,8 @@
+anim nav_default_enter_anim
+anim nav_default_exit_anim
+anim nav_default_pop_enter_anim
+anim nav_default_pop_exit_anim
+animator nav_default_enter_anim
+animator nav_default_exit_anim
+animator nav_default_pop_enter_anim
+animator nav_default_pop_exit_anim
diff --git a/navigation/navigation-ui/api/restricted_2.7.0-beta02.txt b/navigation/navigation-ui/api/restricted_2.7.0-beta02.txt
new file mode 100644
index 0000000..5094c7e
--- /dev/null
+++ b/navigation/navigation-ui/api/restricted_2.7.0-beta02.txt
@@ -0,0 +1,94 @@
+// Signature format: 4.0
+package androidx.navigation.ui {
+
+  public final class ActivityKt {
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+  public final class AppBarConfiguration {
+    method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+    method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+    method public androidx.customview.widget.Openable? getOpenableLayout();
+    method public java.util.Set<java.lang.Integer> getTopLevelDestinations();
+    method public boolean isTopLevelDestination(androidx.navigation.NavDestination destination);
+    property @Deprecated public final androidx.drawerlayout.widget.DrawerLayout? drawerLayout;
+    property public final androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener;
+    property public final androidx.customview.widget.Openable? openableLayout;
+    property public final java.util.Set<java.lang.Integer> topLevelDestinations;
+  }
+
+  public static final class AppBarConfiguration.Builder {
+    ctor public AppBarConfiguration.Builder(android.view.Menu topLevelMenu);
+    ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph navGraph);
+    ctor public AppBarConfiguration.Builder(int... topLevelDestinationIds);
+    ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer> topLevelDestinationIds);
+    method public androidx.navigation.ui.AppBarConfiguration build();
+    method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? fallbackOnNavigateUpListener);
+    method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable? openableLayout);
+  }
+
+  public static fun interface AppBarConfiguration.OnNavigateUpListener {
+    method public boolean onNavigateUp();
+  }
+
+  public final class AppBarConfigurationKt {
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+    method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, optional androidx.customview.widget.Openable? drawerLayout, optional kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener);
+  }
+
+  public final class BottomNavigationViewKt {
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView, androidx.navigation.NavController navController);
+  }
+
+  public final class CollapsingToolbarLayoutKt {
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+  public final class MenuItemKt {
+    method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+  }
+
+  public final class NavControllerKt {
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+  }
+
+  public final class NavigationUI {
+    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static boolean navigateUp(androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static boolean onNavDestinationSelected(android.view.MenuItem item, androidx.navigation.NavController navController, boolean saveState);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity activity, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.customview.widget.Openable? openableLayout);
+    method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout collapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationBarView navigationBarView, androidx.navigation.NavController navController, boolean saveState);
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController);
+    method @androidx.navigation.ui.NavigationUiSaveStateControl public static void setupWithNavController(com.google.android.material.navigation.NavigationView navigationView, androidx.navigation.NavController navController, boolean saveState);
+    field public static final androidx.navigation.ui.NavigationUI INSTANCE;
+  }
+
+  @kotlin.RequiresOptIn(level=kotlin.RequiresOptIn.Level.WARNING) @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface NavigationUiSaveStateControl {
+  }
+
+  public final class NavigationViewKt {
+    method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+  }
+
+  public final class ToolbarKt {
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+    method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, optional androidx.navigation.ui.AppBarConfiguration configuration);
+  }
+
+}
+
diff --git a/paging/paging-common/lint-baseline.xml b/paging/paging-common/lint-baseline.xml
index b4b31d3..034ebe2 100644
--- a/paging/paging-common/lint-baseline.xml
+++ b/paging/paging-common/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -22,8 +22,8 @@
     <issue
         id="SupportAnnotationUsage"
         message="Did you mean `@get:VisibleForTesting`? Without `get:` this annotates the constructor parameter itself instead of the associated getter."
-        errorLine1="        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)"
-        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        errorLine1="        @VisibleForTesting"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~">
         <location
             file="src/main/kotlin/androidx/paging/PageFetcher.kt"/>
     </issue>
diff --git a/paging/paging-compose/lint-baseline.xml b/paging/paging-compose/lint-baseline.xml
new file mode 100644
index 0000000..2612a94
--- /dev/null
+++ b/paging/paging-compose/lint-baseline.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Object> of &apos;itemKey&apos;."
+        errorLine1="): (index: Int) -> Any {"
+        errorLine2="   ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Integer, Object> of &apos;itemContentType&apos;."
+        errorLine1="): (index: Int) -> Any? {"
+        errorLine2="   ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt"/>
+    </issue>
+
+</issues>
diff --git a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
index 82fa44c..bb24cb0 100644
--- a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
+++ b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
@@ -38,8 +38,7 @@
  * based on the key, which means if you add/remove items before the current visible item the
  * item with the given key will be kept as the first visible one.
  */
-@Suppress("PrimitiveInLambda")
-fun <T : Any> LazyPagingItems<T>.itemKey(
+public fun <T : Any> LazyPagingItems<T>.itemKey(
     key: ((item: @JvmSuppressWildcards T) -> Any)? = null
 ): (index: Int) -> Any {
     return { index ->
@@ -69,8 +68,7 @@
  * the same type could be reused more efficiently. Note that null is a valid type and items of
  * such type will be considered compatible.
  */
-@Suppress("PrimitiveInLambda")
-fun <T : Any> LazyPagingItems<T>.itemContentType(
+public fun <T : Any> LazyPagingItems<T>.itemContentType(
     contentType: ((item: @JvmSuppressWildcards T) -> Any?)? = null
 ): (index: Int) -> Any? {
     return { index ->
diff --git a/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/BaseTestActivity.java b/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/BaseTestActivity.java
index 790793b..9dcf237 100755
--- a/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/BaseTestActivity.java
+++ b/percentlayout/percentlayout/src/androidTest/java/androidx/percentlayout/widget/BaseTestActivity.java
@@ -22,6 +22,7 @@
 
 abstract class BaseTestActivity extends Activity {
     @Override
+    @SuppressWarnings("deprecation")
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         overridePendingTransition(0, 0);
@@ -34,6 +35,7 @@
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void finish() {
         super.finish();
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index f8f005e..8b17cc1 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=10178688
-androidx.playground.metalavaBuildId=10250225
+androidx.playground.snapshotBuildId=10295852
+androidx.playground.metalavaBuildId=10307282
 androidx.studio.type=playground
diff --git a/preference/preference/build.gradle b/preference/preference/build.gradle
index 0e7815d..425c9d6 100644
--- a/preference/preference/build.gradle
+++ b/preference/preference/build.gradle
@@ -28,6 +28,7 @@
     // Use the latest version of core library for verifying insets visibility
     api("androidx.core:core:1.6.0")
     implementation("androidx.collection:collection:1.0.0")
+    api("androidx.activity:activity-ktx:1.5.1")
     api("androidx.fragment:fragment-ktx:1.3.6")
     api("androidx.recyclerview:recyclerview:1.0.0")
     api("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
diff --git a/preference/preference/src/main/java/androidx/preference/PreferenceHeaderFragmentCompat.kt b/preference/preference/src/main/java/androidx/preference/PreferenceHeaderFragmentCompat.kt
index 1de9129..86020ce 100644
--- a/preference/preference/src/main/java/androidx/preference/PreferenceHeaderFragmentCompat.kt
+++ b/preference/preference/src/main/java/androidx/preference/PreferenceHeaderFragmentCompat.kt
@@ -24,7 +24,7 @@
 import android.view.ViewGroup
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import androidx.activity.OnBackPressedCallback
-import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.findViewTreeOnBackPressedDispatcherOwner
 import androidx.annotation.CallSuper
 import androidx.core.view.doOnLayout
 import androidx.fragment.app.Fragment
@@ -213,13 +213,11 @@
         childFragmentManager.addOnBackStackChangedListener {
             onBackPressedCallback!!.isEnabled = childFragmentManager.backStackEntryCount == 0
         }
-        val onBackPressedDispatcherOwner = requireContext() as? OnBackPressedDispatcherOwner
-        onBackPressedDispatcherOwner?.let {
-            it.onBackPressedDispatcher.addCallback(
-                viewLifecycleOwner,
-                onBackPressedCallback!!
-            )
-        }
+        val onBackPressedDispatcherOwner = view.findViewTreeOnBackPressedDispatcherOwner()
+        onBackPressedDispatcherOwner?.onBackPressedDispatcher?.addCallback(
+            viewLifecycleOwner,
+            onBackPressedCallback!!
+        )
     }
 
     override fun onViewStateRestored(savedInstanceState: Bundle?) {
diff --git a/privacysandbox/ads/ads-adservices-java/build.gradle b/privacysandbox/ads/ads-adservices-java/build.gradle
index d4734a0..57b63ad 100644
--- a/privacysandbox/ads/ads-adservices-java/build.gradle
+++ b/privacysandbox/ads/ads-adservices-java/build.gradle
@@ -49,8 +49,6 @@
 }
 
 android {
-    compileSdk = 33
-    compileSdkExtension = 5
     namespace "androidx.privacysandbox.ads.adservices.java"
 }
 
diff --git a/privacysandbox/ads/ads-adservices/api/current.txt b/privacysandbox/ads/ads-adservices/api/current.txt
index 30cd307..839dec6 100644
--- a/privacysandbox/ads/ads-adservices/api/current.txt
+++ b/privacysandbox/ads/ads-adservices/api/current.txt
@@ -100,13 +100,20 @@
 package androidx.privacysandbox.ads.adservices.common {
 
   public final class AdData {
-    ctor public AdData(android.net.Uri renderUri, String metadata);
+    ctor public AdData(optional android.net.Uri renderUri, optional String metadata);
     method public String getMetadata();
     method public android.net.Uri getRenderUri();
     property public final String metadata;
     property public final android.net.Uri renderUri;
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class AdData.Builder {
+    ctor public AdData.Builder();
+    method public androidx.privacysandbox.ads.adservices.common.AdData build();
+    method public androidx.privacysandbox.ads.adservices.common.AdData.Builder setMetadata(String metadata);
+    method public androidx.privacysandbox.ads.adservices.common.AdData.Builder setRenderUri(android.net.Uri renderUri);
+  }
+
   public final class AdSelectionSignals {
     ctor public AdSelectionSignals(String signals);
     method public String getSignals();
@@ -185,13 +192,20 @@
   }
 
   public final class TrustedBiddingData {
-    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    ctor public TrustedBiddingData(optional android.net.Uri trustedBiddingUri, optional java.util.List<java.lang.String> trustedBiddingKeys);
     method public java.util.List<java.lang.String> getTrustedBiddingKeys();
     method public android.net.Uri getTrustedBiddingUri();
     property public final java.util.List<java.lang.String> trustedBiddingKeys;
     property public final android.net.Uri trustedBiddingUri;
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class TrustedBiddingData.Builder {
+    ctor public TrustedBiddingData.Builder();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData.Builder setTrustedBiddingKeys(java.util.List<java.lang.String> trustedBiddingKeys);
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData.Builder setTrustedBiddingUri(android.net.Uri trustedBiddingUri);
+  }
+
 }
 
 package androidx.privacysandbox.ads.adservices.measurement {
diff --git a/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta05.txt b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta05.txt
new file mode 100644
index 0000000..30cd307
--- /dev/null
+++ b/privacysandbox/ads/ads-adservices/api/public_plus_experimental_1.0.0-beta05.txt
@@ -0,0 +1,345 @@
+// Signature format: 4.0
+package androidx.privacysandbox.ads.adservices.adid {
+
+  public final class AdId {
+    method public String getAdId();
+    method public boolean isLimitAdTrackingEnabled();
+    property public final String adId;
+    property public final boolean isLimitAdTrackingEnabled;
+  }
+
+  public abstract class AdIdManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID) public abstract suspend Object? getAdId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adid.AdId>);
+    method public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.adid.AdIdManager.Companion Companion;
+  }
+
+  public static final class AdIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adid.AdIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.adselection {
+
+  public final class AdSelectionConfig {
+    ctor public AdSelectionConfig(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller, android.net.Uri decisionLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals, androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals, java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals, android.net.Uri trustedScoringSignalsUri);
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getAdSelectionSignals();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> getCustomAudienceBuyers();
+    method public android.net.Uri getDecisionLogicUri();
+    method public java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> getPerBuyerSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getSeller();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals getSellerSignals();
+    method public android.net.Uri getTrustedScoringSignalsUri();
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals adSelectionSignals;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier> customAudienceBuyers;
+    property public final android.net.Uri decisionLogicUri;
+    property public final java.util.Map<androidx.privacysandbox.ads.adservices.common.AdTechIdentifier,androidx.privacysandbox.ads.adservices.common.AdSelectionSignals> perBuyerSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier seller;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals sellerSignals;
+    property public final android.net.Uri trustedScoringSignalsUri;
+  }
+
+  public abstract class AdSelectionManager {
+    method public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? reportImpression(androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest reportImpressionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? selectAds(androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome>);
+    field public static final androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion Companion;
+  }
+
+  public static final class AdSelectionManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager? obtain(android.content.Context context);
+  }
+
+  public final class AdSelectionOutcome {
+    ctor public AdSelectionOutcome(long adSelectionId, android.net.Uri renderUri);
+    method public long getAdSelectionId();
+    method public android.net.Uri getRenderUri();
+    property public final long adSelectionId;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class ReportImpressionRequest {
+    ctor public ReportImpressionRequest(long adSelectionId, androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig);
+    method public androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig getAdSelectionConfig();
+    method public long getAdSelectionId();
+    property public final androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig adSelectionConfig;
+    property public final long adSelectionId;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.appsetid {
+
+  public final class AppSetId {
+    ctor public AppSetId(String id, int scope);
+    method public String getId();
+    method public int getScope();
+    property public final String id;
+    property public final int scope;
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetId.Companion Companion;
+    field public static final int SCOPE_APP = 1; // 0x1
+    field public static final int SCOPE_DEVELOPER = 2; // 0x2
+  }
+
+  public static final class AppSetId.Companion {
+  }
+
+  public abstract class AppSetIdManager {
+    method public abstract suspend Object? getAppSetId(kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.appsetid.AppSetId>);
+    method public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager.Companion Companion;
+  }
+
+  public static final class AppSetIdManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager? obtain(android.content.Context context);
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.common {
+
+  public final class AdData {
+    ctor public AdData(android.net.Uri renderUri, String metadata);
+    method public String getMetadata();
+    method public android.net.Uri getRenderUri();
+    property public final String metadata;
+    property public final android.net.Uri renderUri;
+  }
+
+  public final class AdSelectionSignals {
+    ctor public AdSelectionSignals(String signals);
+    method public String getSignals();
+    property public final String signals;
+  }
+
+  public final class AdTechIdentifier {
+    ctor public AdTechIdentifier(String identifier);
+    method public String getIdentifier();
+    property public final String identifier;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.customaudience {
+
+  public final class CustomAudience {
+    ctor public CustomAudience(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads, optional java.time.Instant? activationTime, optional java.time.Instant? expirationTime, optional androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals, optional androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals);
+    method public java.time.Instant? getActivationTime();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> getAds();
+    method public android.net.Uri getBiddingLogicUri();
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public android.net.Uri getDailyUpdateUri();
+    method public java.time.Instant? getExpirationTime();
+    method public String getName();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? getTrustedBiddingSignals();
+    method public androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? getUserBiddingSignals();
+    property public final java.time.Instant? activationTime;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads;
+    property public final android.net.Uri biddingLogicUri;
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final android.net.Uri dailyUpdateUri;
+    property public final java.time.Instant? expirationTime;
+    property public final String name;
+    property public final androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData? trustedBiddingSignals;
+    property public final androidx.privacysandbox.ads.adservices.common.AdSelectionSignals? userBiddingSignals;
+  }
+
+  public static final class CustomAudience.Builder {
+    ctor public CustomAudience.Builder(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name, android.net.Uri dailyUpdateUri, android.net.Uri biddingLogicUri, java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setActivationTime(java.time.Instant activationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setAds(java.util.List<androidx.privacysandbox.ads.adservices.common.AdData> ads);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBiddingLogicUri(android.net.Uri biddingLogicUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setBuyer(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setDailyUpdateUri(android.net.Uri dailyUpdateUri);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setExpirationTime(java.time.Instant expirationTime);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setName(String name);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setTrustedBiddingData(androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData trustedBiddingSignals);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience.Builder setUserBiddingSignals(androidx.privacysandbox.ads.adservices.common.AdSelectionSignals userBiddingSignals);
+  }
+
+  public abstract class CustomAudienceManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? joinCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_CUSTOM_AUDIENCE) public abstract suspend Object? leaveCustomAudience(androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion Companion;
+  }
+
+  public static final class CustomAudienceManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager? obtain(android.content.Context context);
+  }
+
+  public final class JoinCustomAudienceRequest {
+    ctor public JoinCustomAudienceRequest(androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience);
+    method public androidx.privacysandbox.ads.adservices.customaudience.CustomAudience getCustomAudience();
+    property public final androidx.privacysandbox.ads.adservices.customaudience.CustomAudience customAudience;
+  }
+
+  public final class LeaveCustomAudienceRequest {
+    ctor public LeaveCustomAudienceRequest(androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer, String name);
+    method public androidx.privacysandbox.ads.adservices.common.AdTechIdentifier getBuyer();
+    method public String getName();
+    property public final androidx.privacysandbox.ads.adservices.common.AdTechIdentifier buyer;
+    property public final String name;
+  }
+
+  public final class TrustedBiddingData {
+    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    method public java.util.List<java.lang.String> getTrustedBiddingKeys();
+    method public android.net.Uri getTrustedBiddingUri();
+    property public final java.util.List<java.lang.String> trustedBiddingKeys;
+    property public final android.net.Uri trustedBiddingUri;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.measurement {
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class DeletionRequest {
+    ctor public DeletionRequest(int deletionMode, int matchBehavior, optional java.time.Instant start, optional java.time.Instant end, optional java.util.List<? extends android.net.Uri> domainUris, optional java.util.List<? extends android.net.Uri> originUris);
+    method public int getDeletionMode();
+    method public java.util.List<android.net.Uri> getDomainUris();
+    method public java.time.Instant getEnd();
+    method public int getMatchBehavior();
+    method public java.util.List<android.net.Uri> getOriginUris();
+    method public java.time.Instant getStart();
+    property public final int deletionMode;
+    property public final java.util.List<android.net.Uri> domainUris;
+    property public final java.time.Instant end;
+    property public final int matchBehavior;
+    property public final java.util.List<android.net.Uri> originUris;
+    property public final java.time.Instant start;
+    field public static final androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Companion Companion;
+    field public static final int DELETION_MODE_ALL = 0; // 0x0
+    field public static final int DELETION_MODE_EXCLUDE_INTERNAL_DATA = 1; // 0x1
+    field public static final int MATCH_BEHAVIOR_DELETE = 0; // 0x0
+    field public static final int MATCH_BEHAVIOR_PRESERVE = 1; // 0x1
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class DeletionRequest.Builder {
+    ctor public DeletionRequest.Builder(int deletionMode, int matchBehavior);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setDomainUris(java.util.List<? extends android.net.Uri> domainUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setEnd(java.time.Instant end);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setOriginUris(java.util.List<? extends android.net.Uri> originUris);
+    method public androidx.privacysandbox.ads.adservices.measurement.DeletionRequest.Builder setStart(java.time.Instant start);
+  }
+
+  public static final class DeletionRequest.Companion {
+  }
+
+  public abstract class MeasurementManager {
+    ctor public MeasurementManager();
+    method public abstract suspend Object? deleteRegistrations(androidx.privacysandbox.ads.adservices.measurement.DeletionRequest deletionRequest, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? getMeasurementApiStatus(kotlin.coroutines.Continuation<? super java.lang.Integer>);
+    method public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerSource(android.net.Uri attributionSource, android.view.InputEvent? inputEvent, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerTrigger(android.net.Uri trigger, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebSource(androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_ATTRIBUTION) public abstract suspend Object? registerWebTrigger(androidx.privacysandbox.ads.adservices.measurement.WebTriggerRegistrationRequest request, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    field public static final androidx.privacysandbox.ads.adservices.measurement.MeasurementManager.Companion Companion;
+    field public static final int MEASUREMENT_API_STATE_DISABLED = 0; // 0x0
+    field public static final int MEASUREMENT_API_STATE_ENABLED = 1; // 0x1
+  }
+
+  public static final class MeasurementManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.measurement.MeasurementManager? obtain(android.content.Context context);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceParams {
+    ctor public WebSourceParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebSourceRegistrationRequest {
+    ctor public WebSourceRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri, optional android.view.InputEvent? inputEvent, optional android.net.Uri? appDestination, optional android.net.Uri? webDestination, optional android.net.Uri? verifiedDestination);
+    method public android.net.Uri? getAppDestination();
+    method public android.view.InputEvent? getInputEvent();
+    method public android.net.Uri getTopOriginUri();
+    method public android.net.Uri? getVerifiedDestination();
+    method public android.net.Uri? getWebDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> getWebSourceParams();
+    property public final android.net.Uri? appDestination;
+    property public final android.view.InputEvent? inputEvent;
+    property public final android.net.Uri topOriginUri;
+    property public final android.net.Uri? verifiedDestination;
+    property public final android.net.Uri? webDestination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams;
+  }
+
+  public static final class WebSourceRegistrationRequest.Builder {
+    ctor public WebSourceRegistrationRequest.Builder(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebSourceParams> webSourceParams, android.net.Uri topOriginUri);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest build();
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setAppDestination(android.net.Uri? appDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setInputEvent(android.view.InputEvent inputEvent);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setVerifiedDestination(android.net.Uri? verifiedDestination);
+    method public androidx.privacysandbox.ads.adservices.measurement.WebSourceRegistrationRequest.Builder setWebDestination(android.net.Uri? webDestination);
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerParams {
+    ctor public WebTriggerParams(android.net.Uri registrationUri, boolean debugKeyAllowed);
+    method public boolean getDebugKeyAllowed();
+    method public android.net.Uri getRegistrationUri();
+    property public final boolean debugKeyAllowed;
+    property public final android.net.Uri registrationUri;
+  }
+
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class WebTriggerRegistrationRequest {
+    ctor public WebTriggerRegistrationRequest(java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams, android.net.Uri destination);
+    method public android.net.Uri getDestination();
+    method public java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> getWebTriggerParams();
+    property public final android.net.Uri destination;
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.measurement.WebTriggerParams> webTriggerParams;
+  }
+
+}
+
+package androidx.privacysandbox.ads.adservices.topics {
+
+  public final class GetTopicsRequest {
+    ctor public GetTopicsRequest(optional String adsSdkName, optional boolean shouldRecordObservation);
+    method public String getAdsSdkName();
+    method public boolean getShouldRecordObservation();
+    property public final String adsSdkName;
+    property public final boolean shouldRecordObservation;
+  }
+
+  public static final class GetTopicsRequest.Builder {
+    ctor public GetTopicsRequest.Builder();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest build();
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setAdsSdkName(String adsSdkName);
+    method public androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest.Builder setShouldRecordObservation(boolean shouldRecordObservation);
+  }
+
+  public final class GetTopicsResponse {
+    ctor public GetTopicsResponse(java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics);
+    method public java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> getTopics();
+    property public final java.util.List<androidx.privacysandbox.ads.adservices.topics.Topic> topics;
+  }
+
+  public final class Topic {
+    ctor public Topic(long taxonomyVersion, long modelVersion, int topicId);
+    method public long getModelVersion();
+    method public long getTaxonomyVersion();
+    method public int getTopicId();
+    property public final long modelVersion;
+    property public final long taxonomyVersion;
+    property public final int topicId;
+  }
+
+  public abstract class TopicsManager {
+    method @RequiresPermission(android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_TOPICS) public abstract suspend Object? getTopics(androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest request, kotlin.coroutines.Continuation<? super androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse>);
+    method public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+    field public static final androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion Companion;
+  }
+
+  public static final class TopicsManager.Companion {
+    method public androidx.privacysandbox.ads.adservices.topics.TopicsManager? obtain(android.content.Context context);
+  }
+
+}
+
diff --git a/privacysandbox/ads/ads-adservices/api/restricted_current.txt b/privacysandbox/ads/ads-adservices/api/restricted_current.txt
index 30cd307..839dec6 100644
--- a/privacysandbox/ads/ads-adservices/api/restricted_current.txt
+++ b/privacysandbox/ads/ads-adservices/api/restricted_current.txt
@@ -100,13 +100,20 @@
 package androidx.privacysandbox.ads.adservices.common {
 
   public final class AdData {
-    ctor public AdData(android.net.Uri renderUri, String metadata);
+    ctor public AdData(optional android.net.Uri renderUri, optional String metadata);
     method public String getMetadata();
     method public android.net.Uri getRenderUri();
     property public final String metadata;
     property public final android.net.Uri renderUri;
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class AdData.Builder {
+    ctor public AdData.Builder();
+    method public androidx.privacysandbox.ads.adservices.common.AdData build();
+    method public androidx.privacysandbox.ads.adservices.common.AdData.Builder setMetadata(String metadata);
+    method public androidx.privacysandbox.ads.adservices.common.AdData.Builder setRenderUri(android.net.Uri renderUri);
+  }
+
   public final class AdSelectionSignals {
     ctor public AdSelectionSignals(String signals);
     method public String getSignals();
@@ -185,13 +192,20 @@
   }
 
   public final class TrustedBiddingData {
-    ctor public TrustedBiddingData(android.net.Uri trustedBiddingUri, java.util.List<java.lang.String> trustedBiddingKeys);
+    ctor public TrustedBiddingData(optional android.net.Uri trustedBiddingUri, optional java.util.List<java.lang.String> trustedBiddingKeys);
     method public java.util.List<java.lang.String> getTrustedBiddingKeys();
     method public android.net.Uri getTrustedBiddingUri();
     property public final java.util.List<java.lang.String> trustedBiddingKeys;
     property public final android.net.Uri trustedBiddingUri;
   }
 
+  @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static final class TrustedBiddingData.Builder {
+    ctor public TrustedBiddingData.Builder();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData build();
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData.Builder setTrustedBiddingKeys(java.util.List<java.lang.String> trustedBiddingKeys);
+    method public androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData.Builder setTrustedBiddingUri(android.net.Uri trustedBiddingUri);
+  }
+
 }
 
 package androidx.privacysandbox.ads.adservices.measurement {
diff --git a/privacysandbox/ads/ads-adservices/build.gradle b/privacysandbox/ads/ads-adservices/build.gradle
index e7fdf07..3e50880 100644
--- a/privacysandbox/ads/ads-adservices/build.gradle
+++ b/privacysandbox/ads/ads-adservices/build.gradle
@@ -44,8 +44,6 @@
 }
 
 android {
-    compileSdk = 33
-    compileSdkExtension = 5
     namespace "androidx.privacysandbox.ads.adservices"
 }
 
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/common/AdDataTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/common/AdDataTest.kt
index 501b15f..c548abb 100644
--- a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/common/AdDataTest.kt
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/common/AdDataTest.kt
@@ -17,7 +17,10 @@
 package androidx.privacysandbox.ads.adservices.common
 
 import android.net.Uri
+import android.os.Build
+import androidx.annotation.RequiresApi
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth
 import org.junit.Test
@@ -25,6 +28,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 33)
 class AdDataTest {
     private val uri: Uri = Uri.parse("abc.com")
     private val metadata = "metadata"
@@ -41,4 +45,14 @@
         var adData2 = AdData(Uri.parse("abc.com"), "metadata")
         Truth.assertThat(adData1 == adData2).isTrue()
     }
+
+    @Test
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    fun testBuilderSetters() {
+        val constructed = AdData(uri, metadata)
+        val builder = AdData.Builder()
+            .setRenderUri(uri)
+            .setMetadata(metadata)
+        Truth.assertThat(builder.build()).isEqualTo(constructed)
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingDataTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingDataTest.kt
index 1476dae..d26ffe5 100644
--- a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingDataTest.kt
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingDataTest.kt
@@ -17,7 +17,10 @@
 package androidx.privacysandbox.ads.adservices.customaudience
 
 import android.net.Uri
+import android.os.Build
+import androidx.annotation.RequiresApi
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth
 import org.junit.Test
@@ -25,6 +28,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 33)
 class TrustedBiddingDataTest {
     private val uri = Uri.parse("abc.com")
     private val keys = listOf("key1", "key2")
@@ -34,4 +38,14 @@
         val trustedBiddingData = TrustedBiddingData(uri, keys)
         Truth.assertThat(trustedBiddingData.toString()).isEqualTo(result)
     }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @Test
+    fun testBuilderSetters() {
+        val constructed = TrustedBiddingData(uri, keys)
+        val builder = TrustedBiddingData.Builder()
+            .setTrustedBiddingUri(uri)
+            .setTrustedBiddingKeys(keys)
+        Truth.assertThat(builder.build()).isEqualTo(constructed)
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/AdData.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/AdData.kt
index ec458ba..7685d0b 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/AdData.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/common/AdData.kt
@@ -17,6 +17,8 @@
 package androidx.privacysandbox.ads.adservices.common
 
 import android.net.Uri
+import android.os.Build
+import androidx.annotation.RequiresApi
 
 /**
  * Represents data specific to an ad that is necessary for ad selection and rendering.
@@ -24,8 +26,8 @@
  * @param metadata buyer ad metadata represented as a JSON string
  */
 class AdData public constructor(
-    val renderUri: Uri,
-    val metadata: String
+    val renderUri: Uri = Uri.EMPTY,
+    val metadata: String = ""
     ) {
 
     /** Checks whether two [AdData] objects contain the same information.  */
@@ -47,4 +49,42 @@
     override fun toString(): String {
         return "AdData: renderUri=$renderUri, metadata='$metadata'"
     }
+
+    /** Builder for [AdData] objects. */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    public class Builder {
+        private var renderUri: Uri = Uri.EMPTY
+        private var metadata: String = ""
+
+        /**
+         * Sets the URI that points to the ad's rendering assets. The URI must use HTTPS.
+         *
+         * @param renderUri a URI pointing to the ad's rendering assets
+         */
+        fun setRenderUri(renderUri: Uri): Builder = apply {
+            this.renderUri = renderUri
+        }
+
+        /**
+         * Sets the buyer ad metadata used during the ad selection process.
+         *
+         * @param metadata The metadata should be a valid JSON object serialized as a string.
+         * Metadata represents ad-specific bidding information that will be used during ad selection
+         * as part of bid generation and used in buyer JavaScript logic, which is executed in an
+         * isolated execution environment.
+         *
+         * If the metadata is not a valid JSON object that can be consumed by the buyer's JS, the
+         * ad will not be eligible for ad selection.
+         */
+        fun setMetadata(metadata: String): Builder = apply {
+            this.metadata = metadata
+        }
+
+        /**
+         * Builds an instance of [AdData]
+         */
+        fun build(): AdData {
+            return AdData(renderUri, metadata)
+        }
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingData.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingData.kt
index fef0a18..86b4672 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingData.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/TrustedBiddingData.kt
@@ -17,6 +17,8 @@
 package androidx.privacysandbox.ads.adservices.customaudience
 
 import android.net.Uri
+import android.os.Build
+import androidx.annotation.RequiresApi
 
 /**
  * Represents data used during the ad selection process to fetch buyer bidding signals from a
@@ -29,8 +31,8 @@
  * bidding signals.
  */
 class TrustedBiddingData public constructor(
-    val trustedBiddingUri: Uri,
-    val trustedBiddingKeys: List<String>
+    val trustedBiddingUri: Uri = Uri.EMPTY,
+    val trustedBiddingKeys: List<String> = emptyList()
     ) {
     /**
      * @return `true` if two [TrustedBiddingData] objects contain the same information
@@ -53,4 +55,38 @@
         return "TrustedBiddingData: trustedBiddingUri=$trustedBiddingUri " +
             "trustedBiddingKeys=$trustedBiddingKeys"
     }
+
+    /** Builder for [TrustedBiddingData] objects. */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    public class Builder {
+        private var trustedBiddingUri: Uri = Uri.EMPTY
+        private var trustedBiddingKeys: List<String> = emptyList()
+
+        /**
+         * Sets the trusted Bidding Uri
+         *
+         * @param trustedBiddingUri the URI pointing to the trusted key-value server holding bidding
+         * signals. The URI must use HTTPS.
+         */
+        fun setTrustedBiddingUri(trustedBiddingUri: Uri): Builder = apply {
+            this.trustedBiddingUri = trustedBiddingUri
+        }
+
+        /**
+         * Sets the trusted Bidding keys.
+         *
+         * @param trustedBiddingKeys list of keys to query the trusted key-value server with.
+         * This list is permitted to be empty.
+         */
+        fun setTrustedBiddingKeys(trustedBiddingKeys: List<String>): Builder = apply {
+            this.trustedBiddingKeys = trustedBiddingKeys
+        }
+
+        /**
+         * Builds and instance of [TrustedBiddingData]
+         */
+        fun build(): TrustedBiddingData {
+            return TrustedBiddingData(trustedBiddingUri, trustedBiddingKeys)
+        }
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/plugins/plugins-privacysandbox-library/src/main/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPlugin.kt b/privacysandbox/plugins/plugins-privacysandbox-library/src/main/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPlugin.kt
index eaf2d0a..a7ecb4f 100644
--- a/privacysandbox/plugins/plugins-privacysandbox-library/src/main/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPlugin.kt
+++ b/privacysandbox/plugins/plugins-privacysandbox-library/src/main/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPlugin.kt
@@ -77,7 +77,7 @@
 
             // Add additional dependencies required for KSP outputs
 
-            val toolsVersion = "1.0.0-alpha03"
+            val toolsVersion = "1.0.0-alpha04"
             project.dependencies {
                 add(
                     "ksp",
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/api/api_lint.ignore b/privacysandbox/sdkruntime/sdkruntime-client/api/api_lint.ignore
index 725751e..b3df653 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/api/api_lint.ignore
+++ b/privacysandbox/sdkruntime/sdkruntime-client/api/api_lint.ignore
@@ -1,4 +1,8 @@
 // Baseline format: 1.0
+ForbiddenSuperClass: androidx.privacysandbox.sdkruntime.client.activity.SdkActivity:
+    SdkActivity should not extend `Activity`. Activity subclasses are impossible to compose. Expose a composable API instead.
+
+
 RegistrationName: androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat#addSdkSandboxProcessDeathCallback(java.util.concurrent.Executor, androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat):
     Callback methods should be named register/unregister; was addSdkSandboxProcessDeathCallback
 RegistrationName: androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat#removeSdkSandboxProcessDeathCallback(androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat):
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/api/current.txt b/privacysandbox/sdkruntime/sdkruntime-client/api/current.txt
index 8d97c00..4251e2e 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/api/current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/api/current.txt
@@ -4,10 +4,14 @@
   public final class SdkSandboxManagerCompat {
     method public void addSdkSandboxProcessDeathCallback(java.util.concurrent.Executor callbackExecutor, androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat callback);
     method public static androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat from(android.content.Context context);
+    method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
     method @kotlin.jvm.Throws(exceptionClasses=LoadSdkCompatException::class) public suspend Object? loadSdk(String sdkName, android.os.Bundle params, kotlin.coroutines.Continuation<? super androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat>) throws androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException;
+    method public void registerAppOwnedSdkSandboxInterface(androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat appOwnedSdk);
     method public void removeSdkSandboxProcessDeathCallback(androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat callback);
+    method public void startSdkSandboxActivity(android.app.Activity fromActivity, android.os.IBinder sdkActivityToken);
     method public void unloadSdk(String sdkName);
+    method public void unregisterAppOwnedSdkSandboxInterface(String sdkName);
     field public static final androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat.Companion Companion;
   }
 
@@ -21,3 +25,11 @@
 
 }
 
+package androidx.privacysandbox.sdkruntime.client.activity {
+
+  public final class SdkActivity extends androidx.activity.ComponentActivity implements androidx.lifecycle.LifecycleOwner {
+    ctor public SdkActivity();
+  }
+
+}
+
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/api/restricted_current.txt b/privacysandbox/sdkruntime/sdkruntime-client/api/restricted_current.txt
index 8d97c00..588ade4 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/api/restricted_current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/api/restricted_current.txt
@@ -4,10 +4,14 @@
   public final class SdkSandboxManagerCompat {
     method public void addSdkSandboxProcessDeathCallback(java.util.concurrent.Executor callbackExecutor, androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat callback);
     method public static androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat from(android.content.Context context);
+    method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
     method @kotlin.jvm.Throws(exceptionClasses=LoadSdkCompatException::class) public suspend Object? loadSdk(String sdkName, android.os.Bundle params, kotlin.coroutines.Continuation<? super androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat>) throws androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException;
+    method public void registerAppOwnedSdkSandboxInterface(androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat appOwnedSdk);
     method public void removeSdkSandboxProcessDeathCallback(androidx.privacysandbox.sdkruntime.client.SdkSandboxProcessDeathCallbackCompat callback);
+    method public void startSdkSandboxActivity(android.app.Activity fromActivity, android.os.IBinder sdkActivityToken);
     method public void unloadSdk(String sdkName);
+    method public void unregisterAppOwnedSdkSandboxInterface(String sdkName);
     field public static final androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat.Companion Companion;
   }
 
@@ -21,3 +25,11 @@
 
 }
 
+package androidx.privacysandbox.sdkruntime.client.activity {
+
+  public final class SdkActivity extends androidx.activity.ComponentActivity {
+    ctor public SdkActivity();
+  }
+
+}
+
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/build.gradle b/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
index a0f618d..beeef14 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
+++ b/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
@@ -25,11 +25,12 @@
 dependencies {
     api(libs.kotlinStdlib)
     api(libs.kotlinCoroutinesCore)
-    implementation("androidx.core:core-ktx:1.8.0")
+    implementation("androidx.core:core-ktx:1.12.0-alpha05")
 
     api project(path: ':privacysandbox:sdkruntime:sdkruntime-core')
 
-    implementation("androidx.core:core:1.8.0")
+    implementation("androidx.core:core:1.12.0-alpha05")
+    implementation("androidx.activity:activity:1.8.0-alpha05")
 
     testImplementation(libs.junit)
     testImplementation(libs.truth)
@@ -42,6 +43,7 @@
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.truth)
     androidTestImplementation(libs.junit)
+    androidTestImplementation(project(':internal-testutils-runtime'))
     androidTestImplementation(project(":internal-testutils-truth")) // for assertThrows
 
     androidTestImplementation(libs.mockitoCore, excludes.bytebuddy) // DexMaker has it"s own MockMaker
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml b/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
index 7b70e67..59ae122 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
+++ b/privacysandbox/sdkruntime/sdkruntime-client/lint-baseline.xml
@@ -1,23 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 33 (current min is 14): `android.app.sdksandbox.SdkSandboxManager#getSandboxedSdks`"
-        errorLine1="        `when`(sdkSandboxManager.sandboxedSdks)"
-        errorLine2="                                 ~~~~~~~~~~~~~">
-        <location
-            file="src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt"/>
-    </issue>
-
-    <issue
-        id="NewApi"
-        message="Call requires API level 33 (current min is 14): `android.app.sdksandbox.SdkSandboxManager#getSandboxedSdks`"
-        errorLine1="        `when`(sdkSandboxManager.sandboxedSdks)"
-        errorLine2="                                 ~~~~~~~~~~~~~">
-        <location
-            file="src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt"/>
-    </issue>
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
 
     <issue
         id="BanThreadSleep"
@@ -46,4 +28,13 @@
             file="src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt"/>
     </issue>
 
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="            return if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt"/>
+    </issue>
+
 </issues>
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/AndroidManifest.xml b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/AndroidManifest.xml
index 3e3ea90..98769ac 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/AndroidManifest.xml
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/AndroidManifest.xml
@@ -14,4 +14,14 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <activity
+            android:name="androidx.privacysandbox.sdkruntime.client.EmptyActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
 </manifest>
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdkTable.xml b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdkTable.xml
index c72c1a2..68b686a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdkTable.xml
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdkTable.xml
@@ -24,6 +24,14 @@
         <package-name>androidx.privacysandbox.sdkruntime.test.v2</package-name>
     </runtime-enabled-sdk>
     <runtime-enabled-sdk>
+        <compat-config-path>RuntimeEnabledSdks/V3/CompatSdkConfig.xml</compat-config-path>
+        <package-name>androidx.privacysandbox.sdkruntime.test.v3</package-name>
+    </runtime-enabled-sdk>
+    <runtime-enabled-sdk>
+        <compat-config-path>RuntimeEnabledSdks/V4/CompatSdkConfig.xml</compat-config-path>
+        <package-name>androidx.privacysandbox.sdkruntime.test.v4</package-name>
+    </runtime-enabled-sdk>
+    <runtime-enabled-sdk>
         <compat-config-path>RuntimeEnabledSdks/InvalidEntryPointSdkConfig.xml</compat-config-path>
         <package-name>androidx.privacysandbox.sdkruntime.test.invalidEntryPoint</package-name>
     </runtime-enabled-sdk>
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkCode.md b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkCode.md
new file mode 100644
index 0000000..750e2a3
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkCode.md
@@ -0,0 +1,263 @@
+Test sdk that was built with V3 library.
+
+DO NOT RECOMPILE WITH ANY CHANGES TO LIBRARY CLASSES.
+Main purpose of that provider is to test that old core versions could be loaded by new client.
+
+classes.dex built from:
+
+1) androidx.privacysandbox.sdkruntime.core.Versions
+@Keep
+object Versions {
+
+    const val API_VERSION = 3
+
+    @JvmField
+    var CLIENT_VERSION: Int? = null
+
+    @JvmStatic
+    fun handShake(clientVersion: Int): Int {
+        CLIENT_VERSION = clientVersion
+        return API_VERSION
+    }
+}
+
+2) androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
+abstract class SandboxedSdkProviderCompat {
+    var context: Context? = null
+        private set
+
+    fun attachContext(context: Context) {
+        check(this.context == null) { "Context already set" }
+        this.context = context
+    }
+
+    @Throws(LoadSdkCompatException::class)
+    abstract fun onLoadSdk(params: Bundle): SandboxedSdkCompat
+
+    open fun beforeUnloadSdk() {}
+
+    abstract fun getView(
+            windowContext: Context,
+            params: Bundle,
+            width: Int,
+            height: Int
+    ): View
+}
+
+3) androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+class SandboxedSdkCompat private constructor(
+   private val sdkImpl: SandboxedSdkImpl
+) {
+
+   constructor(sdkInterface: IBinder) : this(sdkInterface, sdkInfo = null)
+
+   @Keep
+   constructor(
+      sdkInterface: IBinder,
+      sdkInfo: SandboxedSdkInfo?
+   ) : this(CompatImpl(sdkInterface, sdkInfo))
+
+   fun getInterface() = sdkImpl.getInterface()
+
+   fun getSdkInfo(): SandboxedSdkInfo? = sdkImpl.getSdkInfo()
+
+   internal interface SandboxedSdkImpl {
+      fun getInterface(): IBinder?
+      fun getSdkInfo(): SandboxedSdkInfo?
+   }
+
+   private class CompatImpl(
+      private val sdkInterface: IBinder,
+      private val sdkInfo: SandboxedSdkInfo?
+   ) : SandboxedSdkImpl {
+
+      override fun getInterface(): IBinder {
+         return sdkInterface
+      }
+
+      override fun getSdkInfo(): SandboxedSdkInfo? = sdkInfo
+   }
+}
+
+4) androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
+class LoadSdkCompatException : Exception {
+
+    val loadSdkErrorCode: Int
+
+    val extraInformation: Bundle
+
+    @JvmOverloads
+    constructor(
+            loadSdkErrorCode: Int,
+            message: String?,
+            cause: Throwable?,
+            extraInformation: Bundle = Bundle()
+    ) : super(message, cause) {
+        this.loadSdkErrorCode = loadSdkErrorCode
+        this.extraInformation = extraInformation
+    }
+
+    constructor(
+            cause: Throwable,
+            extraInfo: Bundle
+    ) : this(LOAD_SDK_SDK_DEFINED_ERROR, "", cause, extraInfo)
+
+    companion object {
+        const val LOAD_SDK_SDK_DEFINED_ERROR = 102
+    }
+}
+
+5) androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
+class SandboxedSdkInfo(
+    val name: String,
+    val version: Long
+) {
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+        other as SandboxedSdkInfo
+        if (name != other.name) return false
+        if (version != other.version) return false
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = name.hashCode()
+        result = 31 * result + version.hashCode()
+        return result
+    }
+}
+
+6) androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+interface ActivityHolder : LifecycleOwner {
+    fun getActivity(): Activity
+    fun getOnBackPressedDispatcher(): OnBackPressedDispatcher
+}
+
+7) androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+interface SdkSandboxActivityHandlerCompat {
+    fun onActivityCreated(activityHolder: ActivityHolder)
+}
+
+8) androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+class SdkSandboxControllerCompat internal constructor(
+    private val controllerImpl: SandboxControllerImpl
+) {
+    fun getSandboxedSdks(): List<SandboxedSdkCompat> =
+        controllerImpl.getSandboxedSdks()
+
+    fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+        IBinder = controllerImpl.registerSdkSandboxActivityHandler(handlerCompat)
+
+    fun unregisterSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat) =
+        controllerImpl.unregisterSdkSandboxActivityHandler(handlerCompat)
+
+    interface SandboxControllerImpl {
+        fun getSandboxedSdks(): List<SandboxedSdkCompat>
+        fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+            IBinder
+        fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        )
+    }
+
+    companion object {
+        private var localImpl: SandboxControllerImpl? = null
+        @JvmStatic
+        fun from(context: Context): SdkSandboxControllerCompat {
+            val clientVersion = Versions.CLIENT_VERSION
+            if (clientVersion != null) {
+                val implFromClient = localImpl
+                if (implFromClient != null) {
+                    return SdkSandboxControllerCompat(LocalImpl(implFromClient, clientVersion))
+                }
+            }
+            throw IllegalStateException("Should be loaded locally")
+        }
+        @JvmStatic
+        @Keep
+        fun injectLocalImpl(impl: SandboxControllerImpl) {
+            check(localImpl == null) { "Local implementation already injected" }
+            localImpl = impl
+        }
+    }
+}
+
+9) androidx.privacysandbox.sdkruntime.core.controller.impl.LocalImpl
+internal class LocalImpl(
+    private val implFromClient: SdkSandboxControllerCompat.SandboxControllerImpl,
+    private val clientVersion: Int
+) : SdkSandboxControllerCompat.SandboxControllerImpl {
+    override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+        return implFromClient.getSandboxedSdks()
+    }
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        return implFromClient.registerSdkSandboxActivityHandler(handlerCompat)
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        implFromClient.unregisterSdkSandboxActivityHandler(handlerCompat)
+    }
+}
+
+10) androidx.privacysandbox.sdkruntime.test.v3.CompatProvider
+class CompatProvider : SandboxedSdkProviderCompat() {
+
+    @JvmField
+    var onLoadSdkBinder: Binder? = null
+
+    @JvmField
+    var lastOnLoadSdkParams: Bundle? = null
+
+    @JvmField
+    var isBeforeUnloadSdkCalled = false
+
+    @Throws(LoadSdkCompatException::class)
+    override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
+        val result = SdkImpl(context!!)
+        onLoadSdkBinder = result
+        if (params.getBoolean("needFail", false)) {
+            throw LoadSdkCompatException(RuntimeException(), params)
+        }
+        return SandboxedSdkCompat(result)
+    }
+
+    override fun beforeUnloadSdk() {
+        isBeforeUnloadSdkCalled = true
+    }
+
+    override fun getView(
+            windowContext: Context, params: Bundle, width: Int,
+            height: Int
+    ): View {
+        return View(windowContext)
+    }
+
+    class SdkImpl(
+        private val context: Context
+    ) : Binder() {
+        fun getSandboxedSdks(): List<SandboxedSdkCompat> =
+            SdkSandboxControllerCompat.from(context).getSandboxedSdks()
+        fun registerSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat): IBinder =
+            SdkSandboxControllerCompat.from(context).registerSdkSandboxActivityHandler(handler)
+        fun unregisterSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat) {
+            SdkSandboxControllerCompat.from(context).unregisterSdkSandboxActivityHandler(handler)
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkConfig.xml b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkConfig.xml
new file mode 100644
index 0000000..5c23d99
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/CompatSdkConfig.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+<compat-config>
+    <compat-entrypoint>androidx.privacysandbox.sdkruntime.test.v3.CompatProvider</compat-entrypoint>
+    <dex-path>RuntimeEnabledSdks/V3/classes.dex</dex-path>
+</compat-config>
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/classes.dex b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/classes.dex
new file mode 100644
index 0000000..9740bdf
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V3/classes.dex
Binary files differ
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkCode.md b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkCode.md
new file mode 100644
index 0000000..b813a6d
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkCode.md
@@ -0,0 +1,288 @@
+Test sdk that was built with V4 library.
+
+DO NOT RECOMPILE WITH ANY CHANGES TO LIBRARY CLASSES.
+Main purpose of that provider is to test that old core versions could be loaded by new client.
+
+classes.dex built from:
+
+1) androidx.privacysandbox.sdkruntime.core.Versions
+@Keep
+object Versions {
+
+    const val API_VERSION = 4
+
+    @JvmField
+    var CLIENT_VERSION: Int? = null
+
+    @JvmStatic
+    fun handShake(clientVersion: Int): Int {
+        CLIENT_VERSION = clientVersion
+        return API_VERSION
+    }
+}
+
+2) androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
+abstract class SandboxedSdkProviderCompat {
+    var context: Context? = null
+        private set
+
+    fun attachContext(context: Context) {
+        check(this.context == null) { "Context already set" }
+        this.context = context
+    }
+
+    @Throws(LoadSdkCompatException::class)
+    abstract fun onLoadSdk(params: Bundle): SandboxedSdkCompat
+
+    open fun beforeUnloadSdk() {}
+
+    abstract fun getView(
+            windowContext: Context,
+            params: Bundle,
+            width: Int,
+            height: Int
+    ): View
+}
+
+3) androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+class SandboxedSdkCompat private constructor(
+   private val sdkImpl: SandboxedSdkImpl
+) {
+
+   constructor(sdkInterface: IBinder) : this(sdkInterface, sdkInfo = null)
+
+   @Keep
+   constructor(
+      sdkInterface: IBinder,
+      sdkInfo: SandboxedSdkInfo?
+   ) : this(CompatImpl(sdkInterface, sdkInfo))
+
+   fun getInterface() = sdkImpl.getInterface()
+
+   fun getSdkInfo(): SandboxedSdkInfo? = sdkImpl.getSdkInfo()
+
+   internal interface SandboxedSdkImpl {
+      fun getInterface(): IBinder?
+      fun getSdkInfo(): SandboxedSdkInfo?
+   }
+
+   private class CompatImpl(
+      private val sdkInterface: IBinder,
+      private val sdkInfo: SandboxedSdkInfo?
+   ) : SandboxedSdkImpl {
+
+      override fun getInterface(): IBinder {
+         return sdkInterface
+      }
+
+      override fun getSdkInfo(): SandboxedSdkInfo? = sdkInfo
+   }
+}
+
+4) androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
+class LoadSdkCompatException : Exception {
+
+    val loadSdkErrorCode: Int
+
+    val extraInformation: Bundle
+
+    @JvmOverloads
+    constructor(
+            loadSdkErrorCode: Int,
+            message: String?,
+            cause: Throwable?,
+            extraInformation: Bundle = Bundle()
+    ) : super(message, cause) {
+        this.loadSdkErrorCode = loadSdkErrorCode
+        this.extraInformation = extraInformation
+    }
+
+    constructor(
+            cause: Throwable,
+            extraInfo: Bundle
+    ) : this(LOAD_SDK_SDK_DEFINED_ERROR, "", cause, extraInfo)
+
+    companion object {
+        const val LOAD_SDK_SDK_DEFINED_ERROR = 102
+    }
+}
+
+5) androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
+class SandboxedSdkInfo(
+    val name: String,
+    val version: Long
+) {
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (javaClass != other?.javaClass) return false
+        other as SandboxedSdkInfo
+        if (name != other.name) return false
+        if (version != other.version) return false
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = name.hashCode()
+        result = 31 * result + version.hashCode()
+        return result
+    }
+}
+
+6) androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+class AppOwnedSdkSandboxInterfaceCompat(
+    private val name: String,
+    private val version: Long,
+    private val binder: IBinder
+) {
+    fun getName(): String = name
+    fun getVersion(): Long = version
+    fun getInterface(): IBinder = binder
+}
+
+7) androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+interface ActivityHolder : LifecycleOwner {
+    fun getActivity(): Activity
+    fun getOnBackPressedDispatcher(): OnBackPressedDispatcher
+}
+
+8) androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+interface SdkSandboxActivityHandlerCompat {
+    fun onActivityCreated(activityHolder: ActivityHolder)
+}
+
+9) androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+class SdkSandboxControllerCompat internal constructor(
+    private val controllerImpl: SandboxControllerImpl
+) {
+    fun getSandboxedSdks(): List<SandboxedSdkCompat> =
+        controllerImpl.getSandboxedSdks()
+
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        controllerImpl.getAppOwnedSdkSandboxInterfaces()
+
+    fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+        IBinder = controllerImpl.registerSdkSandboxActivityHandler(handlerCompat)
+
+    fun unregisterSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat) =
+        controllerImpl.unregisterSdkSandboxActivityHandler(handlerCompat)
+
+    interface SandboxControllerImpl {
+        fun getSandboxedSdks(): List<SandboxedSdkCompat>
+        fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat>
+        fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+            IBinder
+        fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        )
+    }
+
+    companion object {
+        private var localImpl: SandboxControllerImpl? = null
+        @JvmStatic
+        fun from(context: Context): SdkSandboxControllerCompat {
+            val clientVersion = Versions.CLIENT_VERSION
+            if (clientVersion != null) {
+                val implFromClient = localImpl
+                if (implFromClient != null) {
+                    return SdkSandboxControllerCompat(LocalImpl(implFromClient, clientVersion))
+                }
+            }
+            throw IllegalStateException("Should be loaded locally")
+        }
+        @JvmStatic
+        @Keep
+        fun injectLocalImpl(impl: SandboxControllerImpl) {
+            check(localImpl == null) { "Local implementation already injected" }
+            localImpl = impl
+        }
+    }
+}
+
+10) androidx.privacysandbox.sdkruntime.core.controller.impl.LocalImpl
+internal class LocalImpl(
+    private val implFromClient: SdkSandboxControllerCompat.SandboxControllerImpl,
+    private val clientVersion: Int
+) : SdkSandboxControllerCompat.SandboxControllerImpl {
+    override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+        return implFromClient.getSandboxedSdks()
+    }
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+        return if (clientVersion >= 4) {
+            implFromClient.getAppOwnedSdkSandboxInterfaces()
+        } else {
+            emptyList()
+        }
+    }
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        return implFromClient.registerSdkSandboxActivityHandler(handlerCompat)
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        implFromClient.unregisterSdkSandboxActivityHandler(handlerCompat)
+    }
+}
+
+11) androidx.privacysandbox.sdkruntime.test.v3.CompatProvider
+class CompatProvider : SandboxedSdkProviderCompat() {
+
+    @JvmField
+    var onLoadSdkBinder: Binder? = null
+
+    @JvmField
+    var lastOnLoadSdkParams: Bundle? = null
+
+    @JvmField
+    var isBeforeUnloadSdkCalled = false
+
+    @Throws(LoadSdkCompatException::class)
+    override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
+        val result = SdkImpl(context!!)
+        onLoadSdkBinder = result
+        if (params.getBoolean("needFail", false)) {
+            throw LoadSdkCompatException(RuntimeException(), params)
+        }
+        return SandboxedSdkCompat(result)
+    }
+
+    override fun beforeUnloadSdk() {
+        isBeforeUnloadSdkCalled = true
+    }
+
+    override fun getView(
+            windowContext: Context, params: Bundle, width: Int,
+            height: Int
+    ): View {
+        return View(windowContext)
+    }
+
+    class SdkImpl(
+        private val context: Context
+    ) : Binder() {
+        fun getSandboxedSdks(): List<SandboxedSdkCompat> =
+            SdkSandboxControllerCompat.from(context).getSandboxedSdks()
+        fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+            SdkSandboxControllerCompat.from(context).getAppOwnedSdkSandboxInterfaces()
+        fun registerSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat): IBinder =
+            SdkSandboxControllerCompat.from(context).registerSdkSandboxActivityHandler(handler)
+        fun unregisterSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat) {
+            SdkSandboxControllerCompat.from(context).unregisterSdkSandboxActivityHandler(handler)
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkConfig.xml b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkConfig.xml
new file mode 100644
index 0000000..83cc241
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/CompatSdkConfig.xml
@@ -0,0 +1,19 @@
+<!--
+  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.
+  -->
+<compat-config>
+    <compat-entrypoint>androidx.privacysandbox.sdkruntime.test.v4.CompatProvider</compat-entrypoint>
+    <dex-path>RuntimeEnabledSdks/V4/classes.dex</dex-path>
+</compat-config>
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/classes.dex b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/classes.dex
new file mode 100644
index 0000000..6b3991c
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/assets/RuntimeEnabledSdks/V4/classes.dex
Binary files differ
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/EmptyActivity.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/EmptyActivity.kt
new file mode 100644
index 0000000..f7d19b4
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/EmptyActivity.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.privacysandbox.sdkruntime.client
+
+import androidx.activity.ComponentActivity
+
+/**
+ * Activity for components tests.
+ * [androidx.privacysandbox.sdkruntime.client.activity.SdkActivity] can't be used for most tests as
+ * it will be moved to finished state during creation when no valid token provided.
+ */
+class EmptyActivity : ComponentActivity()
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerAppOwnedInterfacesTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerAppOwnedInterfacesTest.kt
new file mode 100644
index 0000000..bac6861
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerAppOwnedInterfacesTest.kt
@@ -0,0 +1,189 @@
+/*
+ * 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.privacysandbox.sdkruntime.client
+
+import android.app.sdksandbox.SdkSandboxManager
+import android.content.Context
+import android.os.Binder
+import android.os.Bundle
+import androidx.core.content.getSystemService
+import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
+import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedInterfaceConverter
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Tests related to AppOwnedInterfaces support in SdkSandboxManagerCompat.
+ * Later most of them will be extracted to E2E test with separate test app/sdk.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SdkSandboxManagerAppOwnedInterfacesTest {
+
+    private lateinit var context: Context
+    private lateinit var sandboxManagerCompat: SdkSandboxManagerCompat
+
+    @Before
+    fun setUp() {
+        context = ApplicationProvider.getApplicationContext()
+        sandboxManagerCompat = SdkSandboxManagerCompat.from(context)
+    }
+
+    @After
+    fun tearDown() {
+        SdkSandboxManagerCompat.reset()
+        if (isAppOwnedInterfacesApiAvailable()) {
+            val registeredInterfaces = getRegisteredInterfaces()
+            unregisterInterfaces(registeredInterfaces)
+        }
+    }
+
+    @Test
+    fun registerAppOwnedSdkSandboxInterfaceTest() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sandboxManagerCompat.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+
+        val registeredInterfaces = sandboxManagerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(registeredInterfaces).hasSize(1)
+        val result = registeredInterfaces[0]
+
+        assertThat(result.getName()).isEqualTo(appOwnedInterface.getName())
+        assertThat(result.getVersion()).isEqualTo(appOwnedInterface.getVersion())
+        assertThat(result.getInterface()).isEqualTo(appOwnedInterface.getInterface())
+    }
+
+    @Test
+    fun registerAppOwnedSdkSandboxInterface_whenApiAvailable_registerInPlatform() {
+        assumeTrue(
+            "Requires AppOwnedInterfacesApi API available",
+            isAppOwnedInterfacesApiAvailable()
+        )
+
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sandboxManagerCompat.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+        val platformRegisteredInterfaces = getRegisteredInterfaces()
+        assertThat(platformRegisteredInterfaces).hasSize(1)
+        assertThat(platformRegisteredInterfaces[0].getName()).isEqualTo(appOwnedInterface.getName())
+    }
+
+    @Test
+    fun unregisterAppOwnedSdkSandboxInterfaceTest() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sandboxManagerCompat.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+        sandboxManagerCompat.unregisterAppOwnedSdkSandboxInterface(appOwnedInterface.getName())
+
+        val registeredInterfaces = sandboxManagerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(registeredInterfaces).isEmpty()
+    }
+
+    @Test
+    fun unregisterAppOwnedSdkSandboxInterface_whenApiAvailable_unregisterFromPlatform() {
+        assumeTrue(
+            "Requires AppOwnedInterfacesApi API available",
+            isAppOwnedInterfacesApiAvailable()
+        )
+
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sandboxManagerCompat.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+        sandboxManagerCompat.unregisterAppOwnedSdkSandboxInterface(appOwnedInterface.getName())
+
+        val platformRegisteredInterfaces = getRegisteredInterfaces()
+        assertThat(platformRegisteredInterfaces).isEmpty()
+    }
+
+    @Test
+    fun sdkController_getAppOwnedSdkSandboxInterfaces_returnsRegisteredAppOwnedInterfaces() {
+        val localSdk = runBlocking {
+            sandboxManagerCompat.loadSdk(
+                "androidx.privacysandbox.sdkruntime.test.v4",
+                Bundle()
+            )
+        }
+
+        val registeredAppOwnedSdk = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+        sandboxManagerCompat.registerAppOwnedSdkSandboxInterface(registeredAppOwnedSdk)
+
+        val testSdk = localSdk.asTestSdk()
+
+        val apiResult = testSdk.getAppOwnedSdkSandboxInterfaces()
+        assertThat(apiResult).hasSize(1)
+        val appOwnedSdkResult = apiResult[0]
+
+        assertThat(appOwnedSdkResult.getName()).isEqualTo(registeredAppOwnedSdk.getName())
+        assertThat(appOwnedSdkResult.getVersion()).isEqualTo(registeredAppOwnedSdk.getVersion())
+        assertThat(appOwnedSdkResult.getInterface()).isEqualTo(registeredAppOwnedSdk.getInterface())
+    }
+
+    private fun getRegisteredInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+        val converter = AppOwnedInterfaceConverter()
+
+        val sandboxManager = context.getSystemService<SdkSandboxManager>()!!
+        val getInterfacesMethod = sandboxManager.javaClass.getMethod(
+            "getAppOwnedSdkSandboxInterfaces"
+        )
+
+        val results = getInterfacesMethod.invoke(sandboxManager) as List<*>
+        return results.map { converter.toCompat(it!!) }
+    }
+
+    private fun unregisterInterfaces(appOwnedInterfaces: List<AppOwnedSdkSandboxInterfaceCompat>) {
+        val sandboxManager = context.getSystemService<SdkSandboxManager>()!!
+        val unregisterMethod = sandboxManager.javaClass.getMethod(
+            "unregisterAppOwnedSdkSandboxInterface",
+            /* parameter1 */ String::class.java
+        )
+
+        appOwnedInterfaces.forEach { unregisterMethod.invoke(sandboxManager, it.getName()) }
+    }
+
+    private fun isAppOwnedInterfacesApiAvailable() =
+        AdServicesInfo.isDeveloperPreview()
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
index ab6b951..a56a801 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.privacysandbox.sdkruntime.client
 
+import android.app.Activity
 import android.app.sdksandbox.LoadSdkException
 import android.app.sdksandbox.SandboxedSdk
 import android.app.sdksandbox.SdkSandboxManager
@@ -23,6 +24,7 @@
 import android.os.Binder
 import android.os.Build
 import android.os.Bundle
+import android.os.IBinder
 import android.os.OutcomeReceiver
 import android.os.ext.SdkExtensions.AD_SERVICES
 import androidx.annotation.RequiresExtension
@@ -169,6 +171,19 @@
     }
 
     @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    fun startSdkSandboxActivity_whenSandboxAvailable_delegateToPlatform() {
+        val sdkSandboxManager = mockSandboxManager(mContext)
+        val managerCompat = SdkSandboxManagerCompat.from(mContext)
+
+        val fromActivityMock = mock(Activity::class.java)
+        val tokenMock = mock(IBinder::class.java)
+        managerCompat.startSdkSandboxActivity(fromActivityMock, tokenMock)
+
+        verify(sdkSandboxManager).startSdkSandboxActivity(fromActivityMock, tokenMock)
+    }
+
+    @Test
     fun removeSdkSandboxProcessDeathCallback_whenSandboxAvailable_removeAddedCallback() {
         val sdkSandboxManager = mockSandboxManager(mContext)
         val managerCompat = SdkSandboxManagerCompat.from(mContext)
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
index 3a49aa7..8db037e 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
@@ -15,10 +15,14 @@
  */
 package androidx.privacysandbox.sdkruntime.client
 
+import android.app.Activity
 import android.content.Context
 import android.content.ContextWrapper
+import android.os.Binder
 import android.os.Build
 import android.os.Bundle
+import androidx.privacysandbox.sdkruntime.client.activity.SdkActivity
+import androidx.privacysandbox.sdkruntime.client.loader.CatchingSdkActivityHandler
 import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
 import androidx.privacysandbox.sdkruntime.client.loader.extractSdkProviderFieldValue
 import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
@@ -26,16 +30,17 @@
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_INTERNAL_ERROR
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_SDK_DEFINED_ERROR
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
+import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
+import androidx.testutils.withActivity
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.runBlocking
 import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Assume.assumeTrue
-import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito
@@ -283,7 +288,46 @@
         verify(context, Mockito.never()).getSystemService(any())
     }
 
-    @Ignore("b/277764220")
+    @Test
+    // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
+    fun startSdkSandboxActivity_whenSandboxNotAvailable_dontDelegateToSandbox() {
+        // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
+        assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
+
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val managerCompat = SdkSandboxManagerCompat.from(context)
+
+        val fromActivitySpy = Mockito.mock(Activity::class.java)
+        managerCompat.startSdkSandboxActivity(fromActivitySpy, Binder())
+
+        verify(context, Mockito.never()).getSystemService(any())
+    }
+
+    @Test
+    fun startSdkSandboxActivity_startLocalSdkActivity() {
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val managerCompat = SdkSandboxManagerCompat.from(context)
+
+        val localSdk = runBlocking {
+            managerCompat.loadSdk("androidx.privacysandbox.sdkruntime.test.v3", Bundle())
+        }
+
+        val handler = CatchingSdkActivityHandler()
+
+        val testSdk = localSdk.asTestSdk()
+        val token = testSdk.registerSdkSandboxActivityHandler(handler)
+
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                managerCompat.startSdkSandboxActivity(this, token)
+            }
+        }
+
+        val activityHolder = handler.waitForActivity()
+        assertThat(activityHolder.getActivity()).isInstanceOf(SdkActivity::class.java)
+    }
+
     @Test
     fun sdkController_getSandboxedSdks_returnsLocallyLoadedSdks() {
         val context = ApplicationProvider.getApplicationContext<Context>()
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/TestActivityHolder.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/TestActivityHolder.kt
new file mode 100644
index 0000000..66a8470
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/TestActivityHolder.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.privacysandbox.sdkruntime.client
+
+import android.app.Activity
+import androidx.activity.OnBackPressedDispatcher
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleRegistry
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+
+internal class TestActivityHolder(
+    private val activity: Activity,
+) : ActivityHolder {
+    val lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
+    val backPresseddispatcher: OnBackPressedDispatcher = OnBackPressedDispatcher()
+
+    override fun getActivity(): Activity = activity
+
+    override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher = backPresseddispatcher
+
+    override val lifecycle: Lifecycle
+        get() = lifecycleRegistry
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarterTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarterTest.kt
new file mode 100644
index 0000000..5bae49a
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarterTest.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.activity
+
+import android.os.Binder
+import android.view.Window
+import androidx.privacysandbox.sdkruntime.client.EmptyActivity
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.test.core.app.ActivityScenario
+import androidx.testutils.withActivity
+import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import org.junit.Test
+
+class LocalSdkActivityStarterTest {
+
+    @Test
+    fun tryStart_whenHandlerRegistered_startSdkActivityAndReturnTrue() {
+        val handler = TestHandler()
+        val registeredToken = LocalSdkActivityHandlerRegistry.register(handler)
+
+        val startResult = with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                LocalSdkActivityStarter.tryStart(this, registeredToken)
+            }
+        }
+
+        assertThat(startResult).isTrue()
+
+        val activityHolder = handler.waitForActivity()
+        assertThat(activityHolder.getActivity()).isInstanceOf(SdkActivity::class.java)
+
+        val sdkActivity = activityHolder.getActivity() as SdkActivity
+        assertThat(sdkActivity.window.hasFeature(Window.FEATURE_NO_TITLE)).isTrue()
+
+        assertThat(activityHolder.lifecycle).isSameInstanceAs(sdkActivity.lifecycle)
+        assertThat(activityHolder.getOnBackPressedDispatcher())
+            .isSameInstanceAs(sdkActivity.onBackPressedDispatcher)
+    }
+
+    @Test
+    fun tryStart_whenHandlerNotRegistered_ReturnFalse() {
+        val unregisteredToken = Binder()
+
+        val startResult = with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                LocalSdkActivityStarter.tryStart(this, unregisteredToken)
+            }
+        }
+
+        assertThat(startResult).isFalse()
+    }
+
+    private class TestHandler : SdkSandboxActivityHandlerCompat {
+        var result: ActivityHolder? = null
+        var async = CountDownLatch(1)
+
+        override fun onActivityCreated(activityHolder: ActivityHolder) {
+            result = activityHolder
+            async.countDown()
+        }
+
+        fun waitForActivity(): ActivityHolder {
+            async.await()
+            return result!!
+        }
+    }
+}
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/LocalControllerTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/LocalControllerTest.kt
index b44ba98..92b7a74 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/LocalControllerTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/LocalControllerTest.kt
@@ -18,8 +18,12 @@
 
 import android.os.Binder
 import android.os.Bundle
+import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
 import androidx.privacysandbox.sdkruntime.client.loader.LocalSdkProvider
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -32,12 +36,14 @@
 class LocalControllerTest {
 
     private lateinit var locallyLoadedSdks: LocallyLoadedSdks
+    private lateinit var appOwnedSdkRegistry: StubAppOwnedSdkInterfaceRegistry
     private lateinit var controller: LocalController
 
     @Before
     fun setUp() {
         locallyLoadedSdks = LocallyLoadedSdks()
-        controller = LocalController(locallyLoadedSdks)
+        appOwnedSdkRegistry = StubAppOwnedSdkInterfaceRegistry()
+        controller = LocalController(locallyLoadedSdks, appOwnedSdkRegistry)
     }
 
     @Test
@@ -54,6 +60,48 @@
         assertThat(result).containsExactly(sandboxedSdk)
     }
 
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_returnsResultsFromAppOwnedSdkRegistry() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+        appOwnedSdkRegistry.appOwnedSdks = listOf(appOwnedInterface)
+
+        val result = controller.getAppOwnedSdkSandboxInterfaces()
+        assertThat(result).containsExactly(appOwnedInterface)
+    }
+
+    @Test
+    fun registerSdkSandboxActivityHandler_delegateToLocalSdkActivityHandlerRegistry() {
+        val handler = object : SdkSandboxActivityHandlerCompat {
+            override fun onActivityCreated(activityHolder: ActivityHolder) {
+                // do nothing
+            }
+        }
+
+        val token = controller.registerSdkSandboxActivityHandler(handler)
+
+        val registeredHandler = LocalSdkActivityHandlerRegistry.getHandlerByToken(token)
+        assertThat(registeredHandler).isSameInstanceAs(handler)
+    }
+
+    @Test
+    fun unregisterSdkSandboxActivityHandler_delegateToLocalSdkActivityHandlerRegistry() {
+        val handler = object : SdkSandboxActivityHandlerCompat {
+            override fun onActivityCreated(activityHolder: ActivityHolder) {
+                // do nothing
+            }
+        }
+
+        val token = controller.registerSdkSandboxActivityHandler(handler)
+        controller.unregisterSdkSandboxActivityHandler(handler)
+
+        val registeredHandler = LocalSdkActivityHandlerRegistry.getHandlerByToken(token)
+        assertThat(registeredHandler).isNull()
+    }
+
     private class NoOpSdkProvider : LocalSdkProvider(Any()) {
         override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
             throw IllegalStateException("Unexpected call")
@@ -63,4 +111,22 @@
             throw IllegalStateException("Unexpected call")
         }
     }
+
+    private class StubAppOwnedSdkInterfaceRegistry : AppOwnedSdkRegistry {
+
+        var appOwnedSdks: List<AppOwnedSdkSandboxInterfaceCompat> = emptyList()
+
+        override fun registerAppOwnedSdkSandboxInterface(
+            appOwnedSdk: AppOwnedSdkSandboxInterfaceCompat
+        ) {
+            throw IllegalStateException("Unexpected call")
+        }
+
+        override fun unregisterAppOwnedSdkSandboxInterface(sdkName: String) {
+            throw IllegalStateException("Unexpected call")
+        }
+
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+            appOwnedSdks
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistryTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistryTest.kt
new file mode 100644
index 0000000..71563bc
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistryTest.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.controller.impl
+
+import android.os.Binder
+import androidx.privacysandbox.sdkruntime.client.controller.AppOwnedSdkRegistry
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.testutils.assertThrows
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class LocalAppOwnedSdkRegistryTest {
+
+    private lateinit var sdkRegistry: AppOwnedSdkRegistry
+
+    @Before
+    fun setUp() {
+        sdkRegistry = LocalAppOwnedSdkRegistry()
+    }
+
+    @Test
+    fun registerAppOwnedSdkSandboxInterfaceTest() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+
+        val registeredInterfaces = sdkRegistry.getAppOwnedSdkSandboxInterfaces()
+        assertThat(registeredInterfaces).hasSize(1)
+        val result = registeredInterfaces[0]
+
+        assertThat(result.getName()).isEqualTo(appOwnedInterface.getName())
+        assertThat(result.getVersion()).isEqualTo(appOwnedInterface.getVersion())
+        assertThat(result.getInterface()).isEqualTo(appOwnedInterface.getInterface())
+    }
+
+    @Test
+    fun registerAppOwnedSdkSandboxInterface_whenAlreadyRegistered_throwsIllegalStateException() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+
+        val interfaceWithSameName = AppOwnedSdkSandboxInterfaceCompat(
+            name = appOwnedInterface.getName(),
+            version = 1,
+            binder = Binder()
+        )
+        assertThrows<IllegalStateException> {
+            sdkRegistry.registerAppOwnedSdkSandboxInterface(interfaceWithSameName)
+        }
+    }
+
+    @Test
+    fun unregisterAppOwnedSdkSandboxInterfaceTest() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+        sdkRegistry.unregisterAppOwnedSdkSandboxInterface(appOwnedInterface.getName())
+
+        val registeredInterfaces = sdkRegistry.getAppOwnedSdkSandboxInterfaces()
+        assertThat(registeredInterfaces).isEmpty()
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistryTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistryTest.kt
new file mode 100644
index 0000000..23ed22f
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistryTest.kt
@@ -0,0 +1,142 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.controller.impl
+
+import android.app.sdksandbox.SdkSandboxManager
+import android.content.Context
+import android.os.Binder
+import android.os.Build
+import android.os.ext.SdkExtensions.AD_SERVICES
+import androidx.annotation.RequiresExtension
+import androidx.core.content.getSystemService
+import androidx.privacysandbox.sdkruntime.client.controller.AppOwnedSdkRegistry
+import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedInterfaceConverter
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+// TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
+@RequiresExtension(extension = AD_SERVICES, version = 4)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+class PlatformAppOwnedSdkRegistryTest {
+
+    private lateinit var context: Context
+    private lateinit var sdkRegistry: AppOwnedSdkRegistry
+
+    @Before
+    fun setUp() {
+        assumeTrue(
+            "Requires AppOwnedInterfacesApi API available",
+            AdServicesInfo.isDeveloperPreview()
+        )
+        context = ApplicationProvider.getApplicationContext()
+        sdkRegistry = PlatformAppOwnedSdkRegistry(context)
+    }
+
+    @After
+    fun tearDown() {
+        if (AdServicesInfo.isDeveloperPreview()) {
+            val registeredInterfaces = getRegisteredInterfaces()
+            unregisterInterfaces(registeredInterfaces)
+        }
+    }
+
+    @Test
+    fun registerAppOwnedSdkSandboxInterface_registerInPlatform() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+
+        val registeredInterfaces = getRegisteredInterfaces()
+        assertThat(registeredInterfaces).hasSize(1)
+        val result = registeredInterfaces[0]
+
+        assertThat(result.getName()).isEqualTo(appOwnedInterface.getName())
+        assertThat(result.getVersion()).isEqualTo(appOwnedInterface.getVersion())
+        assertThat(result.getInterface()).isEqualTo(appOwnedInterface.getInterface())
+    }
+
+    @Test
+    fun unregisterAppOwnedSdkSandboxInterface_unregisterFromPlatform() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+        sdkRegistry.unregisterAppOwnedSdkSandboxInterface(appOwnedInterface.getName())
+
+        val registeredInterfaces = getRegisteredInterfaces()
+        assertThat(registeredInterfaces).isEmpty()
+    }
+
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_returnsRegisteredSdkInterfaces() {
+        val appOwnedInterface = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestSDK",
+            version = 1,
+            binder = Binder()
+        )
+        sdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedInterface)
+
+        val results = sdkRegistry.getAppOwnedSdkSandboxInterfaces()
+        assertThat(results).hasSize(1)
+        val result = results[0]
+
+        assertThat(result.getName()).isEqualTo(appOwnedInterface.getName())
+        assertThat(result.getVersion()).isEqualTo(appOwnedInterface.getVersion())
+        assertThat(result.getInterface()).isEqualTo(appOwnedInterface.getInterface())
+    }
+
+    private fun getRegisteredInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+        val converter = AppOwnedInterfaceConverter()
+
+        val sandboxManager = context.getSystemService<SdkSandboxManager>()!!
+        val getInterfacesMethod = sandboxManager.javaClass.getMethod(
+            "getAppOwnedSdkSandboxInterfaces"
+        )
+
+        val results = getInterfacesMethod.invoke(sandboxManager) as List<*>
+        return results.map { converter.toCompat(it!!) }
+    }
+
+    private fun unregisterInterfaces(appOwnedInterfaces: List<AppOwnedSdkSandboxInterfaceCompat>) {
+        val sandboxManager = context.getSystemService<SdkSandboxManager>()!!
+        val unregisterMethod = sandboxManager.javaClass.getMethod(
+            "unregisterAppOwnedSdkSandboxInterface",
+            /* parameter1 */ String::class.java
+        )
+
+        appOwnedInterfaces.forEach { unregisterMethod.invoke(sandboxManager, it.getName()) }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
index f34de7b1..6a42d95 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
@@ -18,19 +18,27 @@
 import android.content.Context
 import android.os.Binder
 import android.os.Bundle
+import android.os.IBinder
 import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.privacysandbox.sdkruntime.client.EmptyActivity
+import androidx.privacysandbox.sdkruntime.client.TestActivityHolder
 import androidx.privacysandbox.sdkruntime.client.config.LocalSdkConfig
 import androidx.privacysandbox.sdkruntime.client.loader.impl.SandboxedSdkContextCompat
 import androidx.privacysandbox.sdkruntime.client.loader.storage.TestLocalSdkStorage
 import androidx.privacysandbox.sdkruntime.client.loader.storage.toClassPathString
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+import androidx.test.core.app.ActivityScenario
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.SmallTest
+import androidx.testutils.withActivity
 import com.google.common.truth.Truth.assertThat
 import dalvik.system.BaseDexClassLoader
 import java.io.File
@@ -124,6 +132,101 @@
         assertThat(result.getSdkVersion()).isEqualTo(expectedResult.getSdkInfo()!!.version)
     }
 
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_delegateToSdkController() {
+        assumeTrue(
+            "Requires Versions.API_VERSION >= 4",
+            sdkVersion >= 4
+        )
+
+        val expectedResult = AppOwnedSdkSandboxInterfaceCompat(
+            name = "TestAppOwnedSdk",
+            version = 42,
+            binder = Binder(),
+        )
+        controller.appOwnedSdksResult = listOf(
+            expectedResult
+        )
+
+        val testSdk = loadedSdk.loadTestSdk()
+        val appOwnedSdks = testSdk.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedSdks).hasSize(1)
+        val result = appOwnedSdks[0]
+
+        assertThat(result.getName()).isEqualTo(expectedResult.getName())
+        assertThat(result.getVersion()).isEqualTo(expectedResult.getVersion())
+        assertThat(result.getInterface()).isEqualTo(expectedResult.getInterface())
+    }
+
+    @Test
+    fun registerSdkSandboxActivityHandler_delegateToSdkController() {
+        assumeTrue(
+            "Requires Versions.API_VERSION >= 3",
+            sdkVersion >= 3
+        )
+
+        val catchingHandler = CatchingSdkActivityHandler()
+
+        val testSdk = loadedSdk.loadTestSdk()
+        val token = testSdk.registerSdkSandboxActivityHandler(catchingHandler)
+        val localHandler = controller.sdkActivityHandlers[token]!!
+
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                localHandler.onActivityCreated(activityHolder)
+
+                val receivedActivityHolder = catchingHandler.result!!
+                val receivedActivity = receivedActivityHolder.getActivity()
+                assertThat(receivedActivity).isSameInstanceAs(activityHolder.getActivity())
+            }
+        }
+    }
+
+    @Test
+    fun sdkSandboxActivityHandler_ReceivesLifecycleEventsFromOriginalActivityHolder() {
+        assumeTrue(
+            "Requires Versions.API_VERSION >= 3",
+            sdkVersion >= 3
+        )
+
+        val catchingHandler = CatchingSdkActivityHandler()
+
+        val testSdk = loadedSdk.loadTestSdk()
+        val token = testSdk.registerSdkSandboxActivityHandler(catchingHandler)
+        val localHandler = controller.sdkActivityHandlers[token]!!
+
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                localHandler.onActivityCreated(activityHolder)
+                val receivedActivityHolder = catchingHandler.result!!
+
+                for (event in Lifecycle.Event.values().filter { it != Lifecycle.Event.ON_ANY }) {
+                    activityHolder.lifecycleRegistry.handleLifecycleEvent(event)
+                    assertThat(receivedActivityHolder.getLifeCycleCurrentState())
+                        .isEqualTo(event.targetState)
+                }
+            }
+        }
+    }
+
+    @Test
+    fun unregisterSdkSandboxActivityHandler_delegateToSdkController() {
+        assumeTrue(
+            "Requires Versions.API_VERSION >= 3",
+            sdkVersion >= 3
+        )
+
+        val handler = CatchingSdkActivityHandler()
+
+        val testSdk = loadedSdk.loadTestSdk()
+        val token = testSdk.registerSdkSandboxActivityHandler(handler)
+        testSdk.unregisterSdkSandboxActivityHandler(handler)
+
+        assertThat(controller.sdkActivityHandlers[token]).isNull()
+    }
+
     class CurrentVersionProviderLoadTest : SandboxedSdkProviderCompat() {
         @JvmField
         var onLoadSdkBinder: Binder? = null
@@ -166,6 +269,16 @@
     ) : Binder() {
         fun getSandboxedSdks(): List<SandboxedSdkCompat> =
             SdkSandboxControllerCompat.from(context).getSandboxedSdks()
+
+        fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+            SdkSandboxControllerCompat.from(context).getAppOwnedSdkSandboxInterfaces()
+
+        fun registerSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat): IBinder =
+            SdkSandboxControllerCompat.from(context).registerSdkSandboxActivityHandler(handler)
+
+        fun unregisterSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat) {
+            SdkSandboxControllerCompat.from(context).unregisterSdkSandboxActivityHandler(handler)
+        }
     }
 
     internal class TestClassLoaderFactory(
@@ -214,6 +327,16 @@
                 2,
                 "RuntimeEnabledSdks/V2/classes.dex",
                 "androidx.privacysandbox.sdkruntime.test.v2.CompatProvider"
+            ),
+            TestSdkInfo(
+                3,
+                "RuntimeEnabledSdks/V3/classes.dex",
+                "androidx.privacysandbox.sdkruntime.test.v3.CompatProvider"
+            ),
+            TestSdkInfo(
+                4,
+                "RuntimeEnabledSdks/V4/classes.dex",
+                "androidx.privacysandbox.sdkruntime.test.v4.CompatProvider"
             )
         )
 
@@ -222,14 +345,12 @@
         fun params(): List<Array<Any>> = buildList {
             assertThat(SDKS.size).isEqualTo(Versions.API_VERSION)
 
-            val controller = TestStubController()
-
-            val assetsSdkLoader = createAssetsSdkLoader(controller)
             for (i in SDKS.indices) {
                 val sdk = SDKS[i]
                 assertThat(sdk.apiVersion).isEqualTo(i + 1)
 
-                val loadedSdk = assetsSdkLoader.loadSdk(sdk.localSdkConfig)
+                val controller = TestStubController()
+                val loadedSdk = loadTestSdkFromAssets(sdk.localSdkConfig, controller)
                 assertThat(loadedSdk.extractApiVersion())
                     .isEqualTo(sdk.apiVersion)
 
@@ -244,6 +365,7 @@
             }
 
             // add SDK loaded from test sources
+            val controller = TestStubController()
             add(
                 arrayOf(
                     "BuiltFromSource",
@@ -275,26 +397,50 @@
             )
         }
 
-        private fun createAssetsSdkLoader(controller: TestStubController): SdkLoader {
+        private fun loadTestSdkFromAssets(
+            sdkConfig: LocalSdkConfig,
+            controller: TestStubController
+        ): LocalSdkProvider {
             val context = ApplicationProvider.getApplicationContext<Context>()
             val testStorage = TestLocalSdkStorage(
                 context,
                 rootFolder = File(context.cacheDir, "LocalSdkTest")
             )
-            return SdkLoader(
+            val sdkLoader = SdkLoader(
                 TestClassLoaderFactory(testStorage),
                 context,
                 controller
             )
+            return sdkLoader.loadSdk(sdkConfig)
         }
     }
 
     internal class TestStubController : SdkSandboxControllerCompat.SandboxControllerImpl {
 
         var sandboxedSdksResult: List<SandboxedSdkCompat> = emptyList()
+        var appOwnedSdksResult: List<AppOwnedSdkSandboxInterfaceCompat> = emptyList()
+        var sdkActivityHandlers: MutableMap<IBinder, SdkSandboxActivityHandlerCompat> =
+            mutableMapOf()
 
         override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
             return sandboxedSdksResult
         }
+
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+            appOwnedSdksResult
+
+        override fun registerSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ): IBinder {
+            val token = Binder()
+            sdkActivityHandlers[token] = handlerCompat
+            return token
+        }
+
+        override fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ) {
+            sdkActivityHandlers.values.remove(handlerCompat)
+        }
     }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
index 40aee3a..3b48bc8 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
@@ -16,12 +16,18 @@
 
 package androidx.privacysandbox.sdkruntime.client.loader
 
+import android.app.Activity
 import android.content.Context
 import android.os.Bundle
 import android.os.IBinder
+import androidx.lifecycle.Lifecycle
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import java.lang.reflect.Proxy
+import java.util.concurrent.CountDownLatch
 import kotlin.reflect.cast
 
 /**
@@ -72,6 +78,9 @@
  * Underlying TestSDK should implement and delegate to
  * [androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat]:
  *  1) getSandboxedSdks() : List<SandboxedSdkCompat>
+ *  2) getAppOwnedSdkSandboxInterfaces() : List<AppOwnedSdkSandboxInterfaceCompat>
+ *  3) registerSdkSandboxActivityHandler(SdkSandboxActivityHandlerCompat) : IBinder
+ *  4) unregisterSdkSandboxActivityHandler(SdkSandboxActivityHandlerCompat)
  */
 internal class TestSdkWrapper(
     private val sdk: Any
@@ -82,6 +91,61 @@
         ) as List<*>
         return sdks.map { SandboxedSdkWrapper(it!!) }
     }
+
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkWrapper> {
+        val sdks = sdk.callMethod(
+            methodName = "getAppOwnedSdkSandboxInterfaces"
+        ) as List<*>
+        return sdks.map { AppOwnedSdkWrapper(it!!) }
+    }
+
+    fun registerSdkSandboxActivityHandler(handler: CatchingSdkActivityHandler): IBinder {
+        val classLoader = sdk.javaClass.classLoader!!
+        val activityHandlerClass = Class.forName(
+            SdkSandboxActivityHandlerCompat::class.java.name,
+            false,
+            classLoader
+        )
+
+        val proxy = Proxy.newProxyInstance(
+            classLoader,
+            arrayOf(activityHandlerClass)
+        ) { proxy, method, args ->
+            when (method.name) {
+                "hashCode" -> hashCode()
+                "equals" -> proxy === args[0]
+                "onActivityCreated" -> handler.setResult(args[0])
+                else -> {
+                    throw UnsupportedOperationException(
+                        "Unexpected method call object:$proxy, method: $method, args: $args"
+                    )
+                }
+            }
+        }
+
+        val registerMethod = sdk.javaClass
+            .getMethod("registerSdkSandboxActivityHandler", activityHandlerClass)
+
+        val token = registerMethod.invoke(sdk, proxy) as IBinder
+        handler.proxy = proxy
+
+        return token
+    }
+
+    fun unregisterSdkSandboxActivityHandler(handler: CatchingSdkActivityHandler) {
+        val classLoader = sdk.javaClass.classLoader!!
+        val activityHandlerClass = Class.forName(
+            SdkSandboxActivityHandlerCompat::class.java.name,
+            false,
+            classLoader
+        )
+
+        val unregisterMethod = sdk.javaClass
+            .getMethod("unregisterSdkSandboxActivityHandler", activityHandlerClass)
+
+        unregisterMethod.invoke(sdk, handler.proxy)
+        handler.proxy = null
+    }
 }
 
 /**
@@ -124,6 +188,77 @@
 }
 
 /**
+ * Reflection wrapper for [AppOwnedSdkSandboxInterfaceCompat]
+ */
+internal class AppOwnedSdkWrapper(
+    private val sdk: Any
+) {
+    fun getName(): String {
+        return sdk.callMethod(
+            methodName = "getName"
+        ) as String
+    }
+
+    fun getVersion(): Long {
+        return sdk.callMethod(
+            methodName = "getVersion"
+        ) as Long
+    }
+
+    fun getInterface(): IBinder {
+        return sdk.callMethod(
+            methodName = "getInterface"
+        ) as IBinder
+    }
+}
+
+/**
+ * ActivityHandler to use with [TestSdkWrapper.registerSdkSandboxActivityHandler].
+ * Store received ActivityHolder.
+ */
+internal class CatchingSdkActivityHandler {
+    var proxy: Any? = null
+    var result: ActivityHolderWrapper? = null
+    val async = CountDownLatch(1)
+
+    fun waitForActivity(): ActivityHolderWrapper {
+        async.await()
+        return result!!
+    }
+}
+
+private fun CatchingSdkActivityHandler.setResult(activityHolder: Any) {
+    result = ActivityHolderWrapper(activityHolder)
+    async.countDown()
+}
+
+/**
+ * Reflection wrapper for [androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder]
+ */
+internal class ActivityHolderWrapper(
+    private val activityHolder: Any
+) {
+    fun getActivity(): Activity {
+        return activityHolder.callMethod(
+            methodName = "getActivity"
+        ) as Activity
+    }
+
+    fun getLifeCycleCurrentState(): Lifecycle.State {
+        val lifecycle = activityHolder.callMethod(
+            methodName = "getLifecycle"
+        )
+        val currentState = lifecycle!!.callMethod(
+            methodName = "getCurrentState"
+        )
+        val currentStateString = currentState!!.callMethod(
+            methodName = "name"
+        ) as String
+        return Lifecycle.State.valueOf(currentStateString)
+    }
+}
+
+/**
  * Load SDK and wrap it as TestSDK.
  * @see [TestSdkWrapper]
  */
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SandboxedSdkContextCompatTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SandboxedSdkContextCompatTest.kt
index 11c62973..42f7b49e 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SandboxedSdkContextCompatTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SandboxedSdkContextCompatTest.kt
@@ -15,27 +15,387 @@
  */
 package androidx.privacysandbox.sdkruntime.client.loader
 
+import android.content.Context
+import android.os.Build
 import androidx.privacysandbox.sdkruntime.client.loader.impl.SandboxedSdkContextCompat
 import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
+import androidx.testutils.assertThrows
 import com.google.common.truth.Truth.assertThat
+import java.io.DataInputStream
+import java.io.DataOutputStream
+import java.io.File
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class SandboxedSdkContextCompatTest {
+@RunWith(Parameterized::class)
+internal class SandboxedSdkContextCompatTest(
+    private val contextType: String,
+    private val sdkContextCompat: SandboxedSdkContextCompat,
+    private val appStorageContext: Context
+) {
 
     @Test
     fun getClassloader_returnSdkClassloader() {
         val sdkClassLoader = javaClass.classLoader!!.parent!!
-
-        val sdkContextCompat = SandboxedSdkContextCompat(
-            ApplicationProvider.getApplicationContext(),
-            sdkClassLoader
-        )
         assertThat(sdkContextCompat.classLoader)
             .isEqualTo(sdkClassLoader)
     }
+
+    @Test
+    fun getDataDir_returnSdkDataDirInAppDir() {
+        val expectedSdksRoot = appStorageContext.getDir(SDK_ROOT_FOLDER, Context.MODE_PRIVATE)
+        val expectedSdkDataDir = File(expectedSdksRoot, SDK_PACKAGE_NAME)
+
+        assertThat(sdkContextCompat.dataDir)
+            .isEqualTo(expectedSdkDataDir)
+
+        assertThat(expectedSdkDataDir.exists()).isTrue()
+    }
+
+    @Test
+    fun getCacheDir_returnSdkCacheDirInAppCacheDir() {
+        val expectedSdksCacheRoot = File(appStorageContext.cacheDir, SDK_ROOT_FOLDER)
+        val expectedSdkCache = File(expectedSdksCacheRoot, SDK_PACKAGE_NAME)
+
+        assertThat(sdkContextCompat.cacheDir)
+            .isEqualTo(expectedSdkCache)
+
+        assertThat(expectedSdkCache.exists()).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 21)
+    fun getCodeCacheDir_returnSdkCodeCacheDirInAppCodeCacheDir() {
+        val expectedSdksCodeCacheRoot = File(appStorageContext.codeCacheDir, SDK_ROOT_FOLDER)
+        val expectedSdkCodeCache = File(expectedSdksCodeCacheRoot, SDK_PACKAGE_NAME)
+
+        assertThat(sdkContextCompat.codeCacheDir)
+            .isEqualTo(expectedSdkCodeCache)
+
+        assertThat(expectedSdkCodeCache.exists()).isTrue()
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 21)
+    fun getNoBackupFilesDir_returnSdkNoBackupDirInAppNoBackupDir() {
+        val expectedSdksNoBackupRoot = File(appStorageContext.noBackupFilesDir, SDK_ROOT_FOLDER)
+        val expectedSdkNoBackupDir = File(expectedSdksNoBackupRoot, SDK_PACKAGE_NAME)
+
+        assertThat(sdkContextCompat.noBackupFilesDir)
+            .isEqualTo(expectedSdkNoBackupDir)
+
+        assertThat(expectedSdkNoBackupDir.exists()).isTrue()
+    }
+
+    @Test
+    fun getDir_returnDirWithPrefixInSdkDataDir() {
+        val expectedDir = File(sdkContextCompat.dataDir, "app_test")
+
+        assertThat(sdkContextCompat.getDir("test", Context.MODE_PRIVATE))
+            .isEqualTo(expectedDir)
+
+        assertThat(expectedDir.exists()).isTrue()
+    }
+
+    @Test
+    fun getFilesDir_returnFilesDirInSdkDataDir() {
+        val expectedFilesDir = File(sdkContextCompat.dataDir, "files")
+
+        assertThat(sdkContextCompat.filesDir)
+            .isEqualTo(expectedFilesDir)
+
+        assertThat(expectedFilesDir.exists()).isTrue()
+    }
+
+    @Test
+    fun openFileInput_openFileInSdkFilesDir() {
+        val fileToOpen = File(sdkContextCompat.filesDir, "testOpenFileInput")
+        fileToOpen.outputStream().use { outputStream ->
+            DataOutputStream(outputStream).use { dataStream ->
+                dataStream.writeInt(42)
+            }
+        }
+
+        val content = sdkContextCompat.openFileInput("testOpenFileInput")
+            .use { inputStream ->
+                DataInputStream(inputStream).use { dataStream ->
+                    dataStream.readInt()
+                }
+            }
+
+        assertThat(content)
+            .isEqualTo(42)
+    }
+
+    @Test
+    fun openFileInput_whenFileNameContainsFileSeparator_throwsIllegalArgumentException() {
+        assertThrows<IllegalArgumentException> {
+            sdkContextCompat.openFileInput("folder/file")
+        }
+    }
+
+    @Test
+    fun openFileOutput_openFileInSdkFilesDir() {
+        sdkContextCompat.openFileOutput("testOpenFileOutput", Context.MODE_PRIVATE)
+            .use { outputStream ->
+                DataOutputStream(outputStream).use { dataStream ->
+                    dataStream.writeInt(42)
+                }
+            }
+
+        val expectedFile = File(sdkContextCompat.filesDir, "testOpenFileOutput")
+        val content = expectedFile.inputStream().use { inputStream ->
+            DataInputStream(inputStream).use { dataStream ->
+                dataStream.readInt()
+            }
+        }
+
+        assertThat(content)
+            .isEqualTo(42)
+    }
+
+    @Test
+    fun openFileOutput_whenAppendFlagSet_appendToFileInSdkFilesDir() {
+        sdkContextCompat.openFileOutput(
+            "testOpenFileOutputAppend",
+            Context.MODE_PRIVATE or Context.MODE_APPEND
+        ).use { outputStream ->
+            DataOutputStream(outputStream).use { dataStream ->
+                dataStream.writeInt(42)
+            }
+        }
+        sdkContextCompat.openFileOutput(
+            "testOpenFileOutputAppend",
+            Context.MODE_PRIVATE or Context.MODE_APPEND
+        ).use { outputStream ->
+            DataOutputStream(outputStream).use { dataStream ->
+                dataStream.writeInt(1)
+            }
+        }
+
+        val expectedFile = File(sdkContextCompat.filesDir, "testOpenFileOutputAppend")
+        val content = expectedFile.inputStream().use { inputStream ->
+            DataInputStream(inputStream).use { dataStream ->
+                dataStream.readInt() + dataStream.readInt()
+            }
+        }
+
+        assertThat(content)
+            .isEqualTo(43)
+    }
+
+    @Test
+    fun openFileOutput_whenFileNameContainsFileSeparator_throwsIllegalArgumentException() {
+        assertThrows<IllegalArgumentException> {
+            sdkContextCompat.openFileOutput("folder/file", Context.MODE_PRIVATE)
+        }
+    }
+
+    @Test
+    fun deleteFile_deleteFileInSdkFilesDir() {
+        val fileToDelete = File(sdkContextCompat.filesDir, "testDelete")
+        fileToDelete.createNewFile()
+        assertThat(fileToDelete.exists()).isTrue()
+
+        assertThat(sdkContextCompat.deleteFile("testDelete")).isTrue()
+        assertThat(fileToDelete.exists()).isFalse()
+    }
+
+    @Test
+    fun deleteFile_whenFileNameContainsFileSeparator_throwsIllegalArgumentException() {
+        assertThrows<IllegalArgumentException> {
+            sdkContextCompat.deleteFile("folder/file")
+        }
+    }
+
+    @Test
+    fun getFileStreamPath_returnFileFromSdkFilesDir() {
+        val expectedFile = File(sdkContextCompat.filesDir, "testGetFileStreamPath")
+
+        assertThat(sdkContextCompat.getFileStreamPath("testGetFileStreamPath"))
+            .isEqualTo(expectedFile)
+    }
+
+    @Test
+    fun getFileStreamPath_whenFileNameContainsFileSeparator_throwsIllegalArgumentException() {
+        assertThrows<IllegalArgumentException> {
+            sdkContextCompat.getFileStreamPath("folder/file")
+        }
+    }
+
+    @Test
+    fun fileList_returnContentOfSdkFilesDir() {
+        val expectedFile = File(sdkContextCompat.filesDir, "testFileList")
+        expectedFile.createNewFile()
+
+        val result = sdkContextCompat.fileList().asList()
+        assertThat(result).contains("testFileList")
+        assertThat(result).isEqualTo(sdkContextCompat.filesDir.list()!!.asList())
+    }
+
+    @Test
+    fun getDatabasePath_whenDataBaseNamePassed_returnPathToDatabaseInSdkDatabasesDir() {
+        val expectedDatabasePath = File(
+            sdkContextCompat.dataDir,
+            "databases/testGetDatabasePath"
+        )
+
+        assertThat(sdkContextCompat.getDatabasePath("testGetDatabasePath"))
+            .isEqualTo(expectedDatabasePath)
+    }
+
+    @Test
+    fun getDatabasePath_whenDataBasePathPassed_returnSamePath() {
+        val expectedDatabasePath = File(
+            sdkContextCompat.dataDir,
+            "databases/testGetDatabasePathAbsolute"
+        )
+
+        assertThat(sdkContextCompat.getDatabasePath(expectedDatabasePath.absolutePath))
+            .isEqualTo(expectedDatabasePath)
+    }
+
+    @Test
+    fun openOrCreateDatabase_returnDatabaseFromSdkDatabasesDir() {
+        val databaseName = "testOpenDataBase.db"
+
+        sdkContextCompat.deleteDatabase(databaseName)
+        val database = sdkContextCompat.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null
+        )
+
+        database.execSQL("CREATE TABLE test (data int)")
+        database.execSQL("INSERT INTO test (data) values (42)")
+
+        val databaseFrom4ParamMethod = sdkContextCompat.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null,
+            errorHandler = null
+        )
+
+        val result = databaseFrom4ParamMethod.rawQuery("SELECT * FROM test", null)
+        result.moveToFirst()
+        assertThat(result.getInt(0))
+            .isEqualTo(42)
+
+        val databasePath = sdkContextCompat.getDatabasePath(databaseName)
+        assertThat(databasePath.exists()).isTrue()
+    }
+
+    @Test
+    fun deleteDatabase_deleteDatabaseFromSdkDatabasesDir() {
+        val databaseName = "testDeleteDatabase.db"
+        sdkContextCompat.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null
+        )
+        assertThat(sdkContextCompat.getDatabasePath(databaseName).exists()).isTrue()
+
+        sdkContextCompat.deleteDatabase(databaseName)
+
+        assertThat(sdkContextCompat.getDatabasePath(databaseName).exists()).isFalse()
+    }
+
+    @Test
+    fun databaseList_returnContentOfSdkDatabasesDir() {
+        val databaseName = "testDatabaseList.db"
+        sdkContextCompat.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null
+        )
+
+        val result = sdkContextCompat.databaseList().asList()
+        assertThat(result).contains(databaseName)
+        assertThat(result).isEqualTo(
+            File(sdkContextCompat.dataDir, "databases").list()!!.asList()
+        )
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
+    fun moveDatabaseFrom_migrateDatabaseToSdkDatabasesDir() {
+        val sourceAppStorageContext = if (sdkContextCompat.isDeviceProtectedStorage) {
+            ApplicationProvider.getApplicationContext()
+        } else {
+            appStorageContext.createDeviceProtectedStorageContext()
+        }
+        val sourceContext = SandboxedSdkContextCompat(
+            sourceAppStorageContext,
+            sdkPackageName = SDK_PACKAGE_NAME,
+            classLoader = javaClass.classLoader!!.parent!!
+        )
+
+        val databaseName = "testMoveTo$contextType.db"
+
+        sourceContext.deleteDatabase(databaseName)
+        val database = sourceContext.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null
+        )
+
+        database.execSQL("CREATE TABLE test (data int)")
+        database.execSQL("INSERT INTO test (data) values (42)")
+
+        val moveResult = sdkContextCompat.moveDatabaseFrom(sourceContext, databaseName)
+        assertThat(moveResult).isTrue()
+
+        val migratedDatabase = sdkContextCompat.openOrCreateDatabase(
+            name = databaseName,
+            mode = Context.MODE_PRIVATE,
+            factory = null
+        )
+
+        val result = migratedDatabase.rawQuery("SELECT * FROM test", null)
+        result.moveToFirst()
+        assertThat(result.getInt(0))
+            .isEqualTo(42)
+
+        val oldDatabasePath = sourceContext.getDatabasePath(databaseName)
+        assertThat(oldDatabasePath.exists()).isFalse()
+    }
+
+    companion object {
+        private const val SDK_ROOT_FOLDER = "RuntimeEnabledSdksData"
+        private const val SDK_PACKAGE_NAME = "androidx.privacysandbox.sdkruntime.testsdk1"
+
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun params(): List<Array<Any>> = buildList {
+            val appContext = ApplicationProvider.getApplicationContext<Context>()
+
+            val sdkContext = SandboxedSdkContextCompat(
+                appContext,
+                sdkPackageName = SDK_PACKAGE_NAME,
+                classLoader = javaClass.classLoader!!.parent!!
+            )
+            add(
+                arrayOf(
+                    "SimpleContext",
+                    sdkContext,
+                    appContext
+                )
+            )
+
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                val deviceProtectedSdkContext = sdkContext.createDeviceProtectedStorageContext()
+                add(
+                    arrayOf(
+                        "DeviceProtectedStorageContext",
+                        deviceProtectedSdkContext,
+                        appContext.createDeviceProtectedStorageContext()
+                    )
+                )
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
index 341d08f..dceeeff1 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoaderTest.kt
@@ -17,11 +17,14 @@
 
 import android.content.Context
 import android.os.Build
+import android.os.IBinder
 import androidx.privacysandbox.sdkruntime.client.config.LocalSdkConfig
 import androidx.privacysandbox.sdkruntime.client.config.ResourceRemappingConfig
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -87,6 +90,21 @@
     }
 
     @Test
+    fun testContextFilesDir() {
+        val loadedSdk = sdkLoader.loadSdk(testSdkConfig)
+
+        val sdkContext = loadedSdk.extractSdkContext()
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val expectedSdksRoot = context.getDir("RuntimeEnabledSdksData", Context.MODE_PRIVATE)
+        val expectedSdkData = File(expectedSdksRoot, testSdkConfig.packageName)
+        val expectedSdkFilesDir = File(expectedSdkData, "files")
+
+        assertThat(sdkContext.filesDir)
+            .isEqualTo(expectedSdkFilesDir)
+    }
+
+    @Test
     fun testJavaResources() {
         val loadedSdk = sdkLoader.loadSdk(testSdkConfig)
 
@@ -149,5 +167,21 @@
         override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
             throw UnsupportedOperationException("NoOp")
         }
+
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+            throw UnsupportedOperationException("NoOp")
+        }
+
+        override fun registerSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ): IBinder {
+            throw UnsupportedOperationException("NoOp")
+        }
+
+        override fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ) {
+            throw UnsupportedOperationException("NoOp")
+        }
     }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtilsTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtilsTest.kt
new file mode 100644
index 0000000..2972d47
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtilsTest.kt
@@ -0,0 +1,171 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl
+
+import android.content.Context
+import android.os.Build
+import android.system.Os
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.io.DataInputStream
+import java.io.DataOutputStream
+import java.io.File
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+class MigrationUtilsTest {
+
+    private lateinit var context: Context
+    private lateinit var fromDir: File
+    private lateinit var toDir: File
+
+    @Before
+    fun setUp() {
+        context = ApplicationProvider.getApplicationContext()
+
+        // Clean up between tests
+        val testDir = File(context.cacheDir, "MigrationUtilsTest")
+        testDir.deleteRecursively()
+        testDir.deleteOnExit()
+
+        fromDir = File(testDir, "from")
+        fromDir.mkdirs()
+
+        toDir = File(testDir, "to")
+        toDir.mkdirs()
+    }
+
+    @Test
+    fun moveFiles_moveFileContents() {
+        val fileToMove = File(fromDir, "testFile")
+        fileToMove.createNewFile()
+        fileToMove.outputStream().use { outputStream ->
+            DataOutputStream(outputStream).use { dataStream ->
+                dataStream.writeInt(42)
+            }
+        }
+
+        val result = MigrationUtils.moveFiles(fromDir, toDir, fileToMove.name)
+        assertThat(result).isTrue()
+        assertThat(fileToMove.exists()).isFalse()
+
+        val resultFile = File(toDir, fileToMove.name)
+        assertThat(resultFile.exists()).isTrue()
+
+        val content = resultFile.inputStream().use { inputStream ->
+            DataInputStream(inputStream).use { dataStream ->
+                dataStream.readInt()
+            }
+        }
+
+        assertThat(content)
+            .isEqualTo(42)
+    }
+
+    @Test
+    fun moveFiles_copyPermissions() {
+        val fileToMove = File(fromDir, "testFile")
+        fileToMove.createNewFile()
+        Os.chmod(fileToMove.absolutePath, 511) // 0777
+        val statFrom = Os.stat(fileToMove.absolutePath)
+
+        MigrationUtils.moveFiles(fromDir, toDir, fileToMove.name)
+
+        val resultFile = File(toDir, fileToMove.name)
+        val stat = Os.stat(resultFile.absolutePath)
+        assertThat(stat.st_mode).isEqualTo(statFrom.st_mode)
+    }
+
+    @Test
+    fun moveFiles_moveMultipleFilesWithPrefix() {
+        val fileToMove1 = File(fromDir, "testFile1")
+        val fileToMove2 = File(fromDir, "testFile2")
+        val fileToKeep = File(fromDir, "keepFile1")
+
+        fileToMove1.createNewFile()
+        fileToMove2.createNewFile()
+        fileToKeep.createNewFile()
+
+        val result = MigrationUtils.moveFiles(fromDir, toDir, "testFile")
+        assertThat(result).isTrue()
+
+        assertThat(fileToMove1.exists()).isFalse()
+        assertThat(fileToMove2.exists()).isFalse()
+        assertThat(fileToKeep.exists()).isTrue()
+
+        val resultFile1 = File(toDir, fileToMove1.name)
+        val resultFile2 = File(toDir, fileToMove2.name)
+        val notCopiedFile = File(toDir, fileToKeep.name)
+
+        assertThat(resultFile1.exists()).isTrue()
+        assertThat(resultFile2.exists()).isTrue()
+        assertThat(notCopiedFile.exists()).isFalse()
+    }
+
+    @Test
+    fun moveFiles_whenSameFromAndTo_keepExistingFile() {
+        val fileToMove = File(fromDir, "testFile")
+        fileToMove.outputStream().use { outputStream ->
+            DataOutputStream(outputStream).use { dataStream ->
+                dataStream.writeInt(42)
+            }
+        }
+
+        val result = MigrationUtils.moveFiles(fromDir, fromDir, fileToMove.name)
+        assertThat(result).isTrue()
+
+        assertThat(fileToMove.exists()).isTrue()
+        val content = fileToMove.inputStream().use { inputStream ->
+            DataInputStream(inputStream).use { dataStream ->
+                dataStream.readInt()
+            }
+        }
+
+        assertThat(content)
+            .isEqualTo(42)
+    }
+
+    @Test
+    fun moveFiles_skipFailedFilesAndReturnFalse() {
+        val fileToMove1 = File(fromDir, "testFile1")
+        val fileToFail = File(fromDir, "testFile2")
+        val fileToMove2 = File(fromDir, "testFile3")
+
+        fileToMove1.createNewFile()
+        fileToFail.mkdir() // to fail copy
+        fileToMove2.createNewFile()
+
+        val result = MigrationUtils.moveFiles(fromDir, toDir, "testFile")
+        assertThat(result).isFalse()
+
+        assertThat(fileToMove1.exists()).isFalse()
+        assertThat(fileToMove2.exists()).isFalse()
+
+        val resultFile1 = File(toDir, fileToMove1.name)
+        val resultFile2 = File(toDir, fileToMove2.name)
+
+        assertThat(resultFile1.exists()).isTrue()
+        assertThat(resultFile2.exists()).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactoryTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactoryTest.kt
new file mode 100644
index 0000000..4aad685
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactoryTest.kt
@@ -0,0 +1,135 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.Lifecycle
+import androidx.privacysandbox.sdkruntime.client.EmptyActivity
+import androidx.privacysandbox.sdkruntime.client.TestActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.test.core.app.ActivityScenario
+import androidx.testutils.withActivity
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+class ActivityHolderProxyFactoryTest {
+
+    private lateinit var factory: ActivityHolderProxyFactory
+
+    @Before
+    fun setUp() {
+        factory = ActivityHolderProxyFactory.createFor(javaClass.classLoader!!)
+    }
+
+    @Test
+    fun createProxyFor_RetrievesActivityFromOriginalActivityHolder() {
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                val proxy = factory.createProxyFor(activityHolder) as ActivityHolder
+                assertThat(proxy.getActivity()).isSameInstanceAs(activityHolder.getActivity())
+            }
+        }
+    }
+
+    @Suppress("ReplaceCallWithBinaryOperator") // Explicitly testing equals on proxy
+    @Test
+    fun createProxyFor_CreatesProxyWithValidEqualsAndHashCode() {
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                val proxy = factory.createProxyFor(activityHolder)
+                assertThat(proxy.equals(proxy)).isTrue()
+                assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode())
+                assertThat(proxy.toString()).isEqualTo(proxy.toString())
+            }
+        }
+    }
+
+    @Test
+    fun getOnBackPressedDispatcher_ProxyBackPressedFromSourceDispatcher() {
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                val proxy = factory.createProxyFor(activityHolder) as ActivityHolder
+                val callback = CountingOnBackPressedCallback()
+
+                val sourceDispatcher = activityHolder.getOnBackPressedDispatcher()
+                val proxyDispatcher = proxy.getOnBackPressedDispatcher()
+
+                proxyDispatcher.addCallback(callback)
+                sourceDispatcher.onBackPressed()
+                assertThat(callback.count).isEqualTo(1)
+
+                callback.remove()
+                sourceDispatcher.onBackPressed()
+                assertThat(callback.count).isEqualTo(1)
+            }
+        }
+    }
+
+    @Test
+    fun getOnBackPressedDispatcher_EnableSourceCallbackOnlyWhenEnabledCallbackAddedToProxy() {
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = TestActivityHolder(this)
+                val proxy = factory.createProxyFor(activityHolder) as ActivityHolder
+                val callback = CountingOnBackPressedCallback()
+
+                val sourceDispatcher = activityHolder.getOnBackPressedDispatcher()
+                val proxyDispatcher = proxy.getOnBackPressedDispatcher()
+
+                assertThat(sourceDispatcher.hasEnabledCallbacks()).isFalse()
+
+                proxyDispatcher.addCallback(callback)
+                assertThat(sourceDispatcher.hasEnabledCallbacks()).isTrue()
+
+                callback.isEnabled = false
+                assertThat(sourceDispatcher.hasEnabledCallbacks()).isFalse()
+
+                callback.isEnabled = true
+                assertThat(sourceDispatcher.hasEnabledCallbacks()).isTrue()
+
+                callback.remove()
+                assertThat(sourceDispatcher.hasEnabledCallbacks()).isFalse()
+            }
+        }
+    }
+
+    @Test
+    fun getLifecycle_ProxyLifecycleEventsFromSourceActivityHolder() {
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val sourceActivityHolder = TestActivityHolder(this)
+                val proxy = factory.createProxyFor(sourceActivityHolder) as ActivityHolder
+                for (event in Lifecycle.Event.values().filter { it != Lifecycle.Event.ON_ANY }) {
+                    sourceActivityHolder.lifecycleRegistry.handleLifecycleEvent(event)
+                    assertThat(proxy.lifecycle.currentState).isEqualTo(event.targetState)
+                }
+            }
+        }
+    }
+
+    private class CountingOnBackPressedCallback : OnBackPressedCallback(true) {
+        var count = 0
+
+        override fun handleOnBackPressed() {
+            count++
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapperTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapperTest.kt
new file mode 100644
index 0000000..a4622db
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapperTest.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import androidx.privacysandbox.sdkruntime.client.EmptyActivity
+import androidx.privacysandbox.sdkruntime.client.activity.ComponentActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.testutils.withActivity
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SdkActivityHandlerWrapperTest {
+
+    private lateinit var wrapperFactory: SdkActivityHandlerWrapper
+
+    @Before
+    fun setUp() {
+        wrapperFactory = SdkActivityHandlerWrapper.createFor(javaClass.classLoader!!)
+    }
+
+    @Test
+    fun wrapSdkSandboxActivityHandlerCompat_passActivityToOriginalHandler() {
+        val catchingHandler = TestHandler()
+
+        val wrappedHandler = wrapperFactory.wrapSdkSandboxActivityHandlerCompat(catchingHandler)
+
+        with(ActivityScenario.launch(EmptyActivity::class.java)) {
+            withActivity {
+                val activityHolder = ComponentActivityHolder(this)
+
+                wrappedHandler.onActivityCreated(activityHolder)
+                val receivedActivityHolder = catchingHandler.result!!
+
+                assertThat(receivedActivityHolder.getActivity())
+                    .isSameInstanceAs(activityHolder.getActivity())
+            }
+        }
+    }
+
+    private class TestHandler : SdkSandboxActivityHandlerCompat {
+        var result: ActivityHolder? = null
+
+        override fun onActivityCreated(activityHolder: ActivityHolder) {
+            result = activityHolder
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/AndroidManifest.xml b/privacysandbox/sdkruntime/sdkruntime-client/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ff1665b
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <activity
+            android:name="androidx.privacysandbox.sdkruntime.client.activity.SdkActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
index 5104e2a..06b36066 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
@@ -16,21 +16,30 @@
 package androidx.privacysandbox.sdkruntime.client
 
 import android.annotation.SuppressLint
+import android.app.Activity
 import android.app.sdksandbox.LoadSdkException
 import android.app.sdksandbox.SandboxedSdk
 import android.app.sdksandbox.SdkSandboxManager
 import android.content.Context
 import android.os.Bundle
+import android.os.IBinder
 import android.os.ext.SdkExtensions.AD_SERVICES
 import androidx.annotation.DoNotInline
+import androidx.annotation.OptIn
 import androidx.annotation.RequiresApi
 import androidx.annotation.RequiresExtension
+import androidx.core.os.BuildCompat
 import androidx.core.os.asOutcomeReceiver
+import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityStarter
 import androidx.privacysandbox.sdkruntime.client.config.LocalSdkConfigsHolder
+import androidx.privacysandbox.sdkruntime.client.controller.AppOwnedSdkRegistry
 import androidx.privacysandbox.sdkruntime.client.controller.LocalController
 import androidx.privacysandbox.sdkruntime.client.controller.LocallyLoadedSdks
+import androidx.privacysandbox.sdkruntime.client.controller.impl.LocalAppOwnedSdkRegistry
+import androidx.privacysandbox.sdkruntime.client.controller.impl.PlatformAppOwnedSdkRegistry
 import androidx.privacysandbox.sdkruntime.client.loader.SdkLoader
 import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_ALREADY_LOADED
 import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_NOT_FOUND
@@ -88,6 +97,7 @@
     private val platformApi: PlatformApi,
     private val configHolder: LocalSdkConfigsHolder,
     private val localLocallyLoadedSdks: LocallyLoadedSdks,
+    private val appOwnedSdkRegistry: AppOwnedSdkRegistry,
     private val sdkLoader: SdkLoader
 ) {
     /**
@@ -204,6 +214,57 @@
         return platformResult + localResult
     }
 
+    /**
+     * Registers [AppOwnedSdkSandboxInterfaceCompat] for an app process.
+     *
+     * Registering an [AppOwnedSdkSandboxInterfaceCompat] that has same name as a previously
+     * registered interface will result in [IllegalStateException].
+     *
+     * [AppOwnedSdkSandboxInterfaceCompat.name] refers to the name of the interface.
+     *
+     * @param appOwnedSdk the [AppOwnedSdkSandboxInterfaceCompat] to be registered
+     */
+    fun registerAppOwnedSdkSandboxInterface(appOwnedSdk: AppOwnedSdkSandboxInterfaceCompat) {
+        appOwnedSdkRegistry.registerAppOwnedSdkSandboxInterface(appOwnedSdk)
+    }
+
+    /**
+     * Unregisters [AppOwnedSdkSandboxInterfaceCompat] for an app process.
+     *
+     * @param sdkName the name under which [AppOwnedSdkSandboxInterfaceCompat] was registered.
+     */
+    fun unregisterAppOwnedSdkSandboxInterface(sdkName: String) {
+        appOwnedSdkRegistry.unregisterAppOwnedSdkSandboxInterface(sdkName)
+    }
+
+    /**
+     * Fetches all [AppOwnedSdkSandboxInterfaceCompat] that are registered by the app.
+     *
+     * @return List of all currently registered [AppOwnedSdkSandboxInterfaceCompat]
+     */
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        appOwnedSdkRegistry.getAppOwnedSdkSandboxInterfaces()
+
+    /**
+     * Starts an [Activity] in the SDK sandbox.
+     *
+     * This function will start a new [Activity] in the same task of the passed `fromActivity` and
+     * pass it to the SDK that shared the passed `sdkActivityToken` that identifies a request from
+     * that SDK to stat this [Activity].
+     *
+     * @param fromActivity the [Activity] will be used to start the new sandbox [Activity] by
+     * calling [Activity#startActivity] against it.
+     * @param sdkActivityToken the identifier that is shared by the SDK which requests the
+     * [Activity].
+     * @see SdkSandboxManager.startSdkSandboxActivity
+     */
+    fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
+        if (LocalSdkActivityStarter.tryStart(fromActivity, sdkActivityToken)) {
+            return
+        }
+        platformApi.startSdkSandboxActivity(fromActivity, sdkActivityToken)
+    }
+
     @TestOnly
     internal fun getLocallyLoadedSdk(sdkName: String): LocallyLoadedSdks.Entry? =
         localLocallyLoadedSdks.get(sdkName)
@@ -228,6 +289,8 @@
 
         @DoNotInline
         fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+
+        fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder)
     }
 
     @RequiresApi(33)
@@ -284,6 +347,12 @@
             }
         }
 
+        override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
+            throw UnsupportedOperationException(
+                "This API is only supported for devices run on Android U+"
+            )
+        }
+
         private suspend fun loadSdkInternal(
             sdkName: String,
             params: Bundle
@@ -310,7 +379,7 @@
 
     @RequiresApi(33)
     @RequiresExtension(extension = AD_SERVICES, version = 5)
-    private class ApiAdServicesV5Impl(
+    private open class ApiAdServicesV5Impl(
         context: Context
     ) : ApiAdServicesV4Impl(context) {
         @DoNotInline
@@ -321,6 +390,16 @@
         }
     }
 
+    @RequiresExtension(extension = AD_SERVICES, version = 5)
+    @RequiresApi(34)
+    private class ApiAdServicesUDCImpl(
+        context: Context
+    ) : ApiAdServicesV5Impl(context) {
+        override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
+            sdkSandboxManager.startSdkSandboxActivity(fromActivity, sdkActivityToken)
+        }
+    }
+
     private class FailImpl : PlatformApi {
         @DoNotInline
         override suspend fun loadSdk(
@@ -343,6 +422,9 @@
             callback: SdkSandboxProcessDeathCallbackCompat
         ) {
         }
+
+        override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
+        }
     }
 
     companion object {
@@ -364,13 +446,19 @@
                 if (instance == null) {
                     val configHolder = LocalSdkConfigsHolder.load(context)
                     val localSdks = LocallyLoadedSdks()
-                    val controller = LocalController(localSdks)
+                    val appOwnedSdkRegistry = if (AdServicesInfo.isDeveloperPreview()) {
+                        PlatformAppOwnedSdkRegistry(context)
+                    } else {
+                        LocalAppOwnedSdkRegistry()
+                    }
+                    val controller = LocalController(localSdks, appOwnedSdkRegistry)
                     val sdkLoader = SdkLoader.create(context, controller)
                     val platformApi = PlatformApiFactory.create(context)
                     instance = SdkSandboxManagerCompat(
                         platformApi,
                         configHolder,
                         localSdks,
+                        appOwnedSdkRegistry,
                         sdkLoader
                     )
                     sInstances[context] = WeakReference(instance)
@@ -389,8 +477,11 @@
 
     private object PlatformApiFactory {
         @SuppressLint("NewApi", "ClassVerificationFailure")
+        @OptIn(markerClass = [BuildCompat.PrereleaseSdkCheck::class])
         fun create(context: Context): PlatformApi {
-            return if (AdServicesInfo.isAtLeastV5()) {
+            return if (BuildCompat.isAtLeastU() || AdServicesInfo.isDeveloperPreview()) {
+                ApiAdServicesUDCImpl(context)
+            } else if (AdServicesInfo.isAtLeastV5()) {
                 ApiAdServicesV5Impl(context)
             } else if (AdServicesInfo.isAtLeastV4()) {
                 ApiAdServicesV4Impl(context)
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/ComponentActivityHolder.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/ComponentActivityHolder.kt
new file mode 100644
index 0000000..f47279e
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/ComponentActivityHolder.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.activity
+
+import android.app.Activity
+import androidx.activity.ComponentActivity
+import androidx.activity.OnBackPressedDispatcher
+import androidx.lifecycle.Lifecycle
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+
+/**
+ * Simple implementation of [ActivityHolder] for [ComponentActivity].
+ */
+internal class ComponentActivityHolder(
+    private val activity: ComponentActivity
+) : ActivityHolder {
+    override fun getActivity(): Activity = activity
+
+    override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher =
+        activity.onBackPressedDispatcher
+
+    override val lifecycle: Lifecycle
+        get() = activity.lifecycle
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityHandlerRegistry.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityHandlerRegistry.kt
new file mode 100644
index 0000000..2f9bf53
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityHandlerRegistry.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.activity
+
+import android.os.Binder
+import android.os.IBinder
+import androidx.annotation.GuardedBy
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import org.jetbrains.annotations.TestOnly
+
+/**
+ * Singleton class to store instances of [SdkSandboxActivityHandlerCompat] registered by locally
+ * loaded SDKs.
+ */
+internal object LocalSdkActivityHandlerRegistry {
+
+    private val mapsLock = Any()
+
+    @GuardedBy("mapsLock")
+    private val handlerToToken =
+        hashMapOf<SdkSandboxActivityHandlerCompat, IBinder>()
+
+    @GuardedBy("mapsLock")
+    private val tokenToHandler =
+        hashMapOf<IBinder, SdkSandboxActivityHandlerCompat>()
+
+    fun register(handler: SdkSandboxActivityHandlerCompat): IBinder =
+        synchronized(mapsLock) {
+            val existingToken = handlerToToken[handler]
+            if (existingToken != null) {
+                return existingToken
+            }
+
+            val token = Binder()
+            handlerToToken[handler] = token
+            tokenToHandler[token] = handler
+
+            return token
+        }
+
+    fun unregister(handler: SdkSandboxActivityHandlerCompat) =
+        synchronized(mapsLock) {
+            val unregisteredToken = handlerToToken.remove(handler)
+            if (unregisteredToken != null) {
+                tokenToHandler.remove(unregisteredToken)
+            }
+        }
+
+    fun isRegistered(token: IBinder): Boolean =
+        synchronized(mapsLock) {
+            return tokenToHandler.containsKey(token)
+        }
+
+    @TestOnly
+    fun getHandlerByToken(token: IBinder): SdkSandboxActivityHandlerCompat? =
+        synchronized(mapsLock) {
+            return tokenToHandler[token]
+        }
+
+    fun notifyOnActivityCreation(
+        token: IBinder,
+        activityHolder: ActivityHolder
+    ) = synchronized(mapsLock) {
+        val handler = tokenToHandler[token]
+            ?: throw IllegalStateException("There is no registered handler to notify")
+        handler.onActivityCreated(activityHolder)
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarter.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarter.kt
new file mode 100644
index 0000000..64fc30a
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/LocalSdkActivityStarter.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.activity
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.os.IBinder
+import androidx.core.os.BundleCompat
+
+/**
+ * Singleton helper object to start [SdkActivity].
+ * Creates [Intent] with token provided by SDK.
+ */
+internal object LocalSdkActivityStarter {
+
+    private const val EXTRA_ACTIVITY_TOKEN = "androidx.privacysandbox.sdkruntime.ACTIVITY_HANDLER"
+
+    /**
+     * Trying to start [SdkActivity].
+     *
+     * If [token] registered in [LocalSdkActivityHandlerRegistry] this method will create
+     * [Intent] for starting [SdkActivity] and call [Activity.startActivity]
+     *
+     * @param fromActivity the [Activity] will be used to start the new [SdkActivity] by
+     * calling [Activity.startActivity] against it.
+     * @param token the identifier that is shared by the SDK which requests the [Activity].
+     *
+     * @return true if Intent was created, false if not (token wasn't registered locally).
+     */
+    fun tryStart(fromActivity: Activity, token: IBinder): Boolean {
+        if (!LocalSdkActivityHandlerRegistry.isRegistered(token)) {
+            return false
+        }
+
+        val intent = Intent(fromActivity, SdkActivity::class.java)
+
+        val params = Bundle()
+        BundleCompat.putBinder(params, EXTRA_ACTIVITY_TOKEN, token)
+        intent.putExtras(params)
+
+        fromActivity.startActivity(intent)
+
+        return true
+    }
+
+    /**
+     * Retrieve token from [Intent] used for creation [SdkActivity].
+     *
+     * @return token or null if [EXTRA_ACTIVITY_TOKEN] param is missing in [Intent.getExtras]
+     */
+    fun getTokenFromSdkActivityStartIntent(intent: Intent): IBinder? {
+        val params = intent.extras ?: return null
+        return BundleCompat.getBinder(params, EXTRA_ACTIVITY_TOKEN)
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/SdkActivity.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/SdkActivity.kt
new file mode 100644
index 0000000..2689fee
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/activity/SdkActivity.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.activity
+
+import android.os.Bundle
+import android.util.Log
+import android.view.Window
+import androidx.activity.ComponentActivity
+import androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+
+/**
+ * Activity to start for SDKs running locally.
+ * Not for App / SDK Usage.
+ *
+ * SDK should use [SdkSandboxControllerCompat.registerSdkSandboxActivityHandler] for handler
+ * registration.
+ *
+ * App should use [SdkSandboxManagerCompat.startSdkSandboxActivity] for starting activity.
+ */
+class SdkActivity : ComponentActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        requestWindowFeature(Window.FEATURE_NO_TITLE)
+        notifySdkOnActivityCreation()
+    }
+
+    private fun notifySdkOnActivityCreation() {
+        val token = LocalSdkActivityStarter.getTokenFromSdkActivityStartIntent(intent)
+        if (token == null) {
+            Log.e(
+                LOG_TAG,
+                "Token is missing in starting SdkActivity intent params"
+            )
+            finish()
+            return
+        }
+
+        try {
+            val activityHolder = ComponentActivityHolder(this)
+            LocalSdkActivityHandlerRegistry.notifyOnActivityCreation(token, activityHolder)
+        } catch (e: Exception) {
+            Log.e(
+                LOG_TAG,
+                "Failed to start the SdkActivity and going to finish it: ",
+                e
+            )
+            finish()
+        }
+    }
+
+    private companion object {
+        private const val LOG_TAG = "SdkActivity"
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/AppOwnedSdkRegistry.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/AppOwnedSdkRegistry.kt
new file mode 100644
index 0000000..e89a059
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/AppOwnedSdkRegistry.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.controller
+
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+
+/**
+ * Register/Unregister/Fetches [AppOwnedSdkSandboxInterfaceCompat]
+ */
+internal interface AppOwnedSdkRegistry {
+
+    fun registerAppOwnedSdkSandboxInterface(appOwnedSdk: AppOwnedSdkSandboxInterfaceCompat)
+
+    fun unregisterAppOwnedSdkSandboxInterface(sdkName: String)
+
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat>
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
index ecddba5..c2ec13d 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/LocalController.kt
@@ -16,17 +16,37 @@
 
 package androidx.privacysandbox.sdkruntime.client.controller
 
+import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 
 /**
  * Local implementation that will be injected to locally loaded SDKs.
  */
 internal class LocalController(
-    private val locallyLoadedSdks: LocallyLoadedSdks
+    private val locallyLoadedSdks: LocallyLoadedSdks,
+    private val appOwnedSdkRegistry: AppOwnedSdkRegistry
 ) : SdkSandboxControllerCompat.SandboxControllerImpl {
 
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
         return locallyLoadedSdks.getLoadedSdks()
     }
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        appOwnedSdkRegistry.getAppOwnedSdkSandboxInterfaces()
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        return LocalSdkActivityHandlerRegistry.register(handlerCompat)
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        LocalSdkActivityHandlerRegistry.unregister(handlerCompat)
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistry.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistry.kt
new file mode 100644
index 0000000..3322247
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/LocalAppOwnedSdkRegistry.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.controller.impl
+
+import androidx.privacysandbox.sdkruntime.client.controller.AppOwnedSdkRegistry
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+
+/**
+ * Local implementation for platform versions without AppOwnedSdkSandboxInterface support.
+ */
+internal class LocalAppOwnedSdkRegistry : AppOwnedSdkRegistry {
+
+    private val appOwnedInterfaces = HashMap<String, AppOwnedSdkSandboxInterfaceCompat>()
+
+    override fun registerAppOwnedSdkSandboxInterface(
+        appOwnedSdk: AppOwnedSdkSandboxInterfaceCompat
+    ) = synchronized(appOwnedInterfaces) {
+        val interfaceName = appOwnedSdk.getName()
+        if (appOwnedInterfaces.containsKey(interfaceName)) {
+            throw IllegalStateException("Already registered interface of name $interfaceName")
+        }
+        appOwnedInterfaces[interfaceName] = appOwnedSdk
+    }
+
+    override fun unregisterAppOwnedSdkSandboxInterface(
+        sdkName: String
+    ): Unit = synchronized(appOwnedInterfaces) {
+        appOwnedInterfaces.remove(sdkName)
+    }
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        synchronized(appOwnedInterfaces) {
+            return appOwnedInterfaces.values.toList()
+        }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistry.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistry.kt
new file mode 100644
index 0000000..e2c7abf
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/controller/impl/PlatformAppOwnedSdkRegistry.kt
@@ -0,0 +1,85 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.controller.impl
+
+import android.annotation.SuppressLint
+import android.app.sdksandbox.SdkSandboxManager
+import android.content.Context
+import androidx.annotation.RequiresApi
+import androidx.privacysandbox.sdkruntime.client.controller.AppOwnedSdkRegistry
+import androidx.privacysandbox.sdkruntime.core.AppOwnedInterfaceConverter
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+
+/**
+ * Implementation for Developer Preview builds backed by [SdkSandboxManager].
+ * Using reflection to call public methods / constructors.
+ * TODO(b/281397807) Replace reflection for method calls when new prebuilt will be available.
+ */
+@RequiresApi(33) // will be available later via mainline update
+internal class PlatformAppOwnedSdkRegistry(
+    context: Context
+) : AppOwnedSdkRegistry {
+
+    private val sdkSandboxManager = context.getSystemService(
+        SdkSandboxManager::class.java
+    )
+
+    private val appOwnedSdkInterfaceClass = Class.forName(
+        "android.app.sdksandbox.AppOwnedSdkSandboxInterface"
+    )
+
+    private val registerAppOwnedSdkMethod = sdkSandboxManager.javaClass.getMethod(
+        "registerAppOwnedSdkSandboxInterface",
+        /* parameter1 */ appOwnedSdkInterfaceClass
+    )
+
+    private val unregisterAppOwnedSdkMethod = sdkSandboxManager.javaClass.getMethod(
+        "unregisterAppOwnedSdkSandboxInterface",
+        /* parameter1 */ String::class.java
+    )
+
+    private val getAppOwnedSdksMethod = sdkSandboxManager.javaClass.getMethod(
+        "getAppOwnedSdkSandboxInterfaces"
+    )
+
+    private val converter: AppOwnedInterfaceConverter = AppOwnedInterfaceConverter()
+
+    @SuppressLint("BanUncheckedReflection") // calling public non restricted methods
+    override fun registerAppOwnedSdkSandboxInterface(
+        appOwnedSdk: AppOwnedSdkSandboxInterfaceCompat
+    ) {
+        val platformObj = converter.toPlatform(appOwnedSdk)
+        registerAppOwnedSdkMethod.invoke(
+            sdkSandboxManager,
+            /* parameter1 */ platformObj
+        )
+    }
+
+    @SuppressLint("BanUncheckedReflection") // calling public non restricted methods
+    override fun unregisterAppOwnedSdkSandboxInterface(sdkName: String) {
+        unregisterAppOwnedSdkMethod.invoke(
+            sdkSandboxManager,
+            /* parameter1 */ sdkName
+        )
+    }
+
+    @SuppressLint("BanUncheckedReflection") // calling public non restricted methods
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+        val apiResult = getAppOwnedSdksMethod.invoke(sdkSandboxManager) as List<*>
+        return apiResult.map { converter.toCompat(it!!) }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
index 3fcefd8..f8b08ed 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/SdkLoader.kt
@@ -64,7 +64,7 @@
             val apiVersion = VersionHandshake.perform(classLoader)
             ResourceRemapping.apply(classLoader, sdkConfig.resourceRemapping)
             if (apiVersion >= 2) {
-                return createSdkProviderV2(classLoader, sdkConfig)
+                return createSdkProviderV2(classLoader, apiVersion, sdkConfig)
             } else if (apiVersion >= 1) {
                 return createSdkProviderV1(classLoader, sdkConfig)
             }
@@ -91,9 +91,10 @@
 
     private fun createSdkProviderV2(
         sdkClassLoader: ClassLoader,
+        sdkVersion: Int,
         sdkConfig: LocalSdkConfig
     ): LocalSdkProvider {
-        SandboxControllerInjector.inject(sdkClassLoader, controller)
+        SandboxControllerInjector.inject(sdkClassLoader, sdkVersion, controller)
         return SdkProviderV1.create(sdkClassLoader, sdkConfig, appContext)
     }
 
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtils.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtils.kt
new file mode 100644
index 0000000..6e3488b
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/MigrationUtils.kt
@@ -0,0 +1,105 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl
+
+import android.os.Build
+import android.os.FileUtils
+import android.system.ErrnoException
+import android.system.Os
+import android.util.Log
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
+
+@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+internal object MigrationUtils {
+
+    private const val LOG_TAG = "MigrationUtils"
+
+    /**
+     * Try to migrate all files from source to target that match requested prefix.
+     * Skip failed files.
+     *
+     * @return true if all files moved, or false if some fails happened.
+     */
+    fun moveFiles(srcDir: File, destDir: File, prefix: String): Boolean {
+        if (srcDir == destDir) {
+            return true
+        }
+
+        val sourceFiles = srcDir.listFiles { _, name -> name.startsWith(prefix) }
+            ?: emptyArray()
+
+        var hadFails = false
+        for (sourceFile in sourceFiles) {
+            val targetFile = File(destDir, sourceFile.name)
+            Log.d(LOG_TAG, "Migrating $sourceFile to $targetFile")
+            try {
+                copyFile(sourceFile, targetFile)
+                copyPermissions(sourceFile, targetFile)
+                if (!sourceFile.delete()) {
+                    Log.w(LOG_TAG, "Failed to clean up $sourceFile")
+                    hadFails = true
+                }
+            } catch (e: IOException) {
+                Log.w(LOG_TAG, "Failed to migrate $sourceFile", e)
+                hadFails = true
+            } catch (e: ErrnoException) {
+                Log.w(LOG_TAG, "Failed to migrate $sourceFile", e)
+                hadFails = true
+            }
+        }
+        return !hadFails
+    }
+
+    private fun copyFile(sourceFile: File, targetFile: File) {
+        if (targetFile.exists()) {
+            targetFile.delete()
+        }
+        FileInputStream(sourceFile).use { sourceStream ->
+            FileOutputStream(targetFile).use { targetStream ->
+                copy(sourceStream, targetStream)
+                Os.fsync(targetStream.fd)
+            }
+        }
+    }
+
+    private fun copyPermissions(sourceFile: File, targetFile: File) {
+        val stat = Os.stat(sourceFile.absolutePath)
+        Os.chmod(targetFile.absolutePath, stat.st_mode)
+        Os.chown(targetFile.absolutePath, stat.st_uid, stat.st_gid)
+    }
+
+    private fun copy(from: InputStream, to: OutputStream): Long {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            return Api29.copy(from, to)
+        }
+        return from.copyTo(to)
+    }
+
+    @RequiresApi(Build.VERSION_CODES.Q)
+    private object Api29 {
+        @DoNotInline
+        fun copy(from: InputStream, to: OutputStream): Long =
+            FileUtils.copy(from, to)
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
index 745c352..e22a12d 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxControllerInjector.kt
@@ -16,9 +16,13 @@
 
 package androidx.privacysandbox.sdkruntime.client.loader.impl
 
+import android.annotation.SuppressLint
 import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.client.loader.impl.injector.AppOwnedSdkInterfaceProxyFactory
+import androidx.privacysandbox.sdkruntime.client.loader.impl.injector.SdkActivityHandlerWrapper
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 import java.lang.reflect.Constructor
 import java.lang.reflect.InvocationHandler
@@ -38,8 +42,10 @@
      * 2) Create proxy that implements class from (1) and delegate to [controller]
      * 3) Call (via reflection) [SdkSandboxControllerCompat.injectLocalImpl] with proxy from (2)
      */
+    @SuppressLint("BanUncheckedReflection") // using reflection on library classes
     fun inject(
         sdkClassLoader: ClassLoader,
+        sdkVersion: Int,
         controller: SdkSandboxControllerCompat.SandboxControllerImpl
     ) {
         val controllerClass = Class.forName(
@@ -58,12 +64,24 @@
 
         val sdkCompatBuilder = CompatSdkBuilder.createFor(sdkClassLoader)
 
+        val sdkActivityHandlerWrapper = if (sdkVersion >= 3)
+            SdkActivityHandlerWrapper.createFor(sdkClassLoader)
+        else
+            null
+
+        val appOwnedSdkInterfaceProxyFactory = if (sdkVersion >= 4)
+            AppOwnedSdkInterfaceProxyFactory.createFor(sdkClassLoader)
+        else
+            null
+
         val proxy = Proxy.newProxyInstance(
             sdkClassLoader,
             arrayOf(controllerImplClass),
             Handler(
                 controller,
-                sdkCompatBuilder
+                sdkCompatBuilder,
+                appOwnedSdkInterfaceProxyFactory,
+                sdkActivityHandlerWrapper
             )
         )
 
@@ -72,11 +90,26 @@
 
     private class Handler(
         private val controller: SdkSandboxControllerCompat.SandboxControllerImpl,
-        private val compatSdkBuilder: CompatSdkBuilder
+        private val compatSdkBuilder: CompatSdkBuilder,
+        private val appOwnedSdkInterfaceProxyFactory: AppOwnedSdkInterfaceProxyFactory?,
+        private val sdkActivityHandlerWrapper: SdkActivityHandlerWrapper?
     ) : InvocationHandler {
+
+        private val sdkToAppHandlerMap =
+            hashMapOf<Any, SdkSandboxActivityHandlerCompat>()
+
         override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any {
             return when (method.name) {
                 "getSandboxedSdks" -> getSandboxedSdks()
+
+                "getAppOwnedSdkSandboxInterfaces" -> getAppOwnedSdkSandboxInterfaces()
+
+                "registerSdkSandboxActivityHandler" ->
+                    registerSdkSandboxActivityHandler(args!![0]!!)
+
+                "unregisterSdkSandboxActivityHandler" ->
+                    unregisterSdkSandboxActivityHandler(args!![0]!!)
+
                 else -> {
                     throw UnsupportedOperationException(
                         "Unexpected method call object:$proxy, method: $method, args: $args"
@@ -90,6 +123,55 @@
                 .getSandboxedSdks()
                 .map { compatSdkBuilder.createFrom(it) }
         }
+
+        private fun getAppOwnedSdkSandboxInterfaces(): List<Any> {
+            if (appOwnedSdkInterfaceProxyFactory == null) {
+                throw IllegalStateException(
+                    "Unexpected call from SDK without AppOwnedInterfaces support"
+                )
+            }
+
+            return controller
+                .getAppOwnedSdkSandboxInterfaces()
+                .map { appOwnedSdkInterfaceProxyFactory.createFrom(it) }
+        }
+
+        private fun registerSdkSandboxActivityHandler(sdkSideHandler: Any): Any {
+            val handlerToRegister = wrapSdkActivityHandler(sdkSideHandler)
+            return controller
+                .registerSdkSandboxActivityHandler(handlerToRegister)
+        }
+
+        private fun unregisterSdkSandboxActivityHandler(sdkSideHandler: Any) {
+            val appSideHandler = synchronized(sdkToAppHandlerMap) {
+                sdkToAppHandlerMap.remove(sdkSideHandler)
+            }
+            if (appSideHandler != null) {
+                controller
+                    .unregisterSdkSandboxActivityHandler(appSideHandler)
+            }
+        }
+
+        private fun wrapSdkActivityHandler(sdkSideHandler: Any): SdkSandboxActivityHandlerCompat =
+            synchronized(sdkToAppHandlerMap) {
+                if (sdkActivityHandlerWrapper == null) {
+                    throw IllegalStateException(
+                        "Unexpected call from SDK without Activity support"
+                    )
+                }
+
+                val existingAppSideHandler = sdkToAppHandlerMap[sdkSideHandler]
+                if (existingAppSideHandler != null) {
+                    return existingAppSideHandler
+                }
+
+                val appSideHandler =
+                    sdkActivityHandlerWrapper.wrapSdkSandboxActivityHandlerCompat(sdkSideHandler)
+
+                sdkToAppHandlerMap[sdkSideHandler] = appSideHandler
+
+                return appSideHandler
+            }
     }
 
     private class CompatSdkBuilder(
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxedSdkContextCompat.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxedSdkContextCompat.kt
index 4a9fd3b..686e3f7 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxedSdkContextCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SandboxedSdkContextCompat.kt
@@ -17,19 +17,229 @@
 
 import android.content.Context
 import android.content.ContextWrapper
-import androidx.annotation.RestrictTo
+import android.database.DatabaseErrorHandler
+import android.database.sqlite.SQLiteDatabase
+import android.os.Build
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
 
 /**
  * Refers to the context of the SDK loaded locally.
  *
- * @suppress
+ * Supports Per-SDK storage by pointing storage related APIs to folders unique for each SDK.
+ * Where possible maintains same folders hierarchy as for applications by creating folders
+ * inside [getDataDir].
+ * Folders with special permissions or additional logic (caches, etc) created as subfolders of same
+ * application folders.
+ *
+ * SDK Folders hierarchy (from application [getDataDir]):
+ * 1) /cache/RuntimeEnabledSdksData/<sdk_package_name> - cache
+ * 2) /code_cache/RuntimeEnabledSdksData/<sdk_package_name> - code_cache
+ * 3) /no_backup/RuntimeEnabledSdksData/<sdk_package_name> - no_backup
+ * 4) /app_RuntimeEnabledSdksData/<sdk_package_name>/ - SDK Root (data dir)
+ * 5) /app_RuntimeEnabledSdksData/<sdk_package_name>/files - [getFilesDir]
+ * 6) /app_RuntimeEnabledSdksData/<sdk_package_name>/app_<folder_name> - [getDir]
+ * 7) /app_RuntimeEnabledSdksData/<sdk_package_name>/databases - SDK Databases
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
 internal class SandboxedSdkContextCompat(
     base: Context,
+    private val sdkPackageName: String,
     private val classLoader: ClassLoader?
 ) : ContextWrapper(base) {
+
+    @RequiresApi(Build.VERSION_CODES.N)
+    override fun createDeviceProtectedStorageContext(): Context {
+        return SandboxedSdkContextCompat(
+            Api24.createDeviceProtectedStorageContext(baseContext),
+            sdkPackageName,
+            classLoader
+        )
+    }
+
+    /**
+     *  Points to <app_data_dir>/app_RuntimeEnabledSdksData/<sdk_package_name>
+     */
+    override fun getDataDir(): File {
+        val sdksDataRoot = baseContext.getDir(
+            SDK_ROOT_FOLDER,
+            Context.MODE_PRIVATE
+        )
+        return ensureDirExists(sdksDataRoot, sdkPackageName)
+    }
+
+    /**
+     *  Points to <app_data_dir>/cache/RuntimeEnabledSdksData/<sdk_package_name>
+     */
+    override fun getCacheDir(): File {
+        val sdksCacheRoot = ensureDirExists(baseContext.cacheDir, SDK_ROOT_FOLDER)
+        return ensureDirExists(sdksCacheRoot, sdkPackageName)
+    }
+
+    /**
+     *  Points to <app_data_dir>/code_cache/RuntimeEnabledSdksData/<sdk_package_name>
+     */
+    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+    override fun getCodeCacheDir(): File {
+        val sdksCodeCacheRoot = ensureDirExists(
+            Api21.codeCacheDir(baseContext),
+            SDK_ROOT_FOLDER
+        )
+        return ensureDirExists(sdksCodeCacheRoot, sdkPackageName)
+    }
+
+    /**
+     *  Points to <app_data_dir>/no_backup/RuntimeEnabledSdksData/<sdk_package_name>
+     */
+    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+    override fun getNoBackupFilesDir(): File {
+        val sdksNoBackupRoot = ensureDirExists(
+            Api21.noBackupFilesDir(baseContext),
+            SDK_ROOT_FOLDER
+        )
+        return ensureDirExists(sdksNoBackupRoot, sdkPackageName)
+    }
+
+    /**
+     *  Points to <app_data_dir>/app_RuntimeEnabledSdksData/<sdk_package_name>/app_<folder_name>
+     *  Prefix required to maintain same hierarchy as for applications - when dir could be
+     *  accessed by both [getDir] and [getDir]/app_<folder_name>.
+     */
+    override fun getDir(name: String, mode: Int): File {
+        val dirName = "app_$name"
+        return ensureDirExists(dataDir, dirName)
+    }
+
+    /**
+     *  Points to <app_data_dir>/app_RuntimeEnabledSdksData/<sdk_package_name>/files
+     */
+    override fun getFilesDir(): File {
+        return ensureDirExists(dataDir, "files")
+    }
+
+    override fun openFileInput(name: String): FileInputStream {
+        val file = makeFilename(filesDir, name)
+        return FileInputStream(file)
+    }
+
+    override fun openFileOutput(name: String, mode: Int): FileOutputStream {
+        val file = makeFilename(filesDir, name)
+        val append = (mode and MODE_APPEND) != 0
+        return FileOutputStream(file, append)
+    }
+
+    override fun deleteFile(name: String): Boolean {
+        val file = makeFilename(filesDir, name)
+        return file.delete()
+    }
+
+    override fun getFileStreamPath(name: String): File {
+        return makeFilename(filesDir, name)
+    }
+
+    override fun fileList(): Array<String> {
+        return listOrEmpty(filesDir)
+    }
+
+    override fun getDatabasePath(name: String): File {
+        if (name[0] == File.separatorChar) {
+            return baseContext.getDatabasePath(name)
+        }
+        val absolutePath = File(getDatabasesDir(), name)
+        return baseContext.getDatabasePath(absolutePath.absolutePath)
+    }
+
+    override fun openOrCreateDatabase(
+        name: String,
+        mode: Int,
+        factory: SQLiteDatabase.CursorFactory?
+    ): SQLiteDatabase {
+        return openOrCreateDatabase(name, mode, factory, null)
+    }
+
+    override fun openOrCreateDatabase(
+        name: String,
+        mode: Int,
+        factory: SQLiteDatabase.CursorFactory?,
+        errorHandler: DatabaseErrorHandler?
+    ): SQLiteDatabase {
+        return baseContext.openOrCreateDatabase(
+            getDatabasePath(name).absolutePath,
+            mode,
+            factory,
+            errorHandler
+        )
+    }
+
+    @RequiresApi(Build.VERSION_CODES.N)
+    override fun moveDatabaseFrom(sourceContext: Context, name: String): Boolean {
+        synchronized(SandboxedSdkContextCompat::class.java) {
+            val source = sourceContext.getDatabasePath(name)
+            val target = getDatabasePath(name)
+            return MigrationUtils.moveFiles(
+                source.parentFile!!,
+                target.parentFile!!,
+                source.name
+            )
+        }
+    }
+
+    override fun deleteDatabase(name: String): Boolean {
+        return baseContext.deleteDatabase(
+            getDatabasePath(name).absolutePath
+        )
+    }
+
+    override fun databaseList(): Array<String> {
+        return listOrEmpty(getDatabasesDir())
+    }
     override fun getClassLoader(): ClassLoader? {
         return classLoader
     }
+
+    private fun getDatabasesDir(): File =
+        ensureDirExists(dataDir, "databases")
+
+    private fun listOrEmpty(dir: File?): Array<String> {
+        return dir?.list() ?: emptyArray()
+    }
+
+    private fun makeFilename(parent: File, name: String): File {
+        if (name.indexOf(File.separatorChar) >= 0) {
+            throw IllegalArgumentException(
+                "File $name contains a path separator"
+            )
+        }
+        return File(parent, name)
+    }
+
+    private fun ensureDirExists(parent: File, dirName: String): File {
+        val dir = File(parent, dirName)
+        if (!dir.exists()) {
+            dir.mkdir()
+        }
+        return dir
+    }
+
+    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+    private object Api21 {
+        @DoNotInline
+        fun codeCacheDir(context: Context): File = context.codeCacheDir
+
+        @DoNotInline
+        fun noBackupFilesDir(context: Context): File = context.noBackupFilesDir
+    }
+
+    @RequiresApi(Build.VERSION_CODES.N)
+    private object Api24 {
+        @DoNotInline
+        fun createDeviceProtectedStorageContext(context: Context): Context =
+            context.createDeviceProtectedStorageContext()
+    }
+
+    private companion object {
+        private const val SDK_ROOT_FOLDER = "RuntimeEnabledSdksData"
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SdkProviderV1.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SdkProviderV1.kt
index ce51c0ef..4a6d959 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SdkProviderV1.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/SdkProviderV1.kt
@@ -175,7 +175,11 @@
                 LoadSdkCompatExceptionBuilderV1.create(classLoader)
 
             val sdkProvider = sdkProviderClass.getConstructor().newInstance()
-            val sandboxedSdkContextCompat = SandboxedSdkContextCompat(appContext, classLoader)
+            val sandboxedSdkContextCompat = SandboxedSdkContextCompat(
+                appContext,
+                sdkConfig.packageName,
+                classLoader
+            )
             attachContextMethod.invoke(sdkProvider, sandboxedSdkContextCompat)
 
             return SdkProviderV1(
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactory.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactory.kt
new file mode 100644
index 0000000..ed9d37e
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/ActivityHolderProxyFactory.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import android.app.Activity
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import java.lang.reflect.InvocationHandler
+import java.lang.reflect.Method
+import java.lang.reflect.Proxy
+
+/**
+ * Create proxy of [ActivityHolder] that implements same interface loaded by SDK Classloader.
+ */
+internal class ActivityHolderProxyFactory private constructor(
+    private val sdkClassLoader: ClassLoader,
+
+    private val activityHolderClass: Class<*>,
+
+    private val backPressedDispatcherProxyFactory: BackPressedDispatcherProxyFactory,
+
+    private val lifecycleRegistryProxyFactory: LifecycleRegistryProxyFactory,
+) {
+
+    fun createProxyFor(activityHolder: ActivityHolder): Any {
+        val dispatcherProxy = backPressedDispatcherProxyFactory.setupOnBackPressedDispatcherProxy(
+            activityHolder.getOnBackPressedDispatcher()
+        )
+
+        val handler = ActivityHolderHandler(
+            activityHolder.getActivity(),
+            dispatcherProxy
+        )
+
+        val activityHolderProxy = Proxy.newProxyInstance(
+            sdkClassLoader,
+            arrayOf(activityHolderClass),
+            handler
+        )
+
+        val lifecycleProxy = lifecycleRegistryProxyFactory.setupLifecycleProxy(
+            activityHolderProxy,
+            activityHolder.lifecycle
+        )
+        handler.lifecycleProxy = lifecycleProxy
+
+        return activityHolderProxy
+    }
+
+    private class ActivityHolderHandler(
+        private val activity: Activity,
+        private val onBackPressedDispatcherProxy: Any,
+    ) : InvocationHandler {
+
+        var lifecycleProxy: Any? = null
+
+        override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any {
+            return when (method.name) {
+                "equals" -> proxy === args?.get(0)
+                "hashCode" -> hashCode()
+                "toString" -> toString()
+                "getActivity" -> activity
+                "getOnBackPressedDispatcher" -> onBackPressedDispatcherProxy
+                "getLifecycle" -> lifecycleProxy!!
+                else -> {
+                    throw UnsupportedOperationException(
+                        "Unexpected method call object:$proxy, method: $method, args: $args"
+                    )
+                }
+            }
+        }
+    }
+
+    companion object {
+        fun createFor(classLoader: ClassLoader): ActivityHolderProxyFactory {
+            val activityHolderClass = Class.forName(
+                ActivityHolder::class.java.name,
+                /* initialize = */ false,
+                classLoader
+            )
+
+            val lifecycleRegistryProxyFactory = LifecycleRegistryProxyFactory.createFor(classLoader)
+            val backPressedDispatcherProxyFactory =
+                BackPressedDispatcherProxyFactory.createFor(classLoader)
+
+            return ActivityHolderProxyFactory(
+                sdkClassLoader = classLoader,
+                activityHolderClass = activityHolderClass,
+                backPressedDispatcherProxyFactory = backPressedDispatcherProxyFactory,
+                lifecycleRegistryProxyFactory = lifecycleRegistryProxyFactory
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/AppOwnedSdkInterfaceProxyFactory.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/AppOwnedSdkInterfaceProxyFactory.kt
new file mode 100644
index 0000000..113b176
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/AppOwnedSdkInterfaceProxyFactory.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import java.lang.reflect.Constructor
+
+/**
+ * Create instance of [AppOwnedSdkSandboxInterfaceCompat] class loaded by SDK Classloader.
+ */
+internal class AppOwnedSdkInterfaceProxyFactory(
+    private val appOwnedSdkSandboxInterfaceCompatConstructor: Constructor<out Any>
+) {
+
+    /**
+     * Creates instance of [AppOwnedSdkSandboxInterfaceCompat] class loaded by SDK Classloader.
+     *
+     * @param source instance of AppOwnedSdkSandboxInterfaceCompat loaded by app classloader.
+     * @return instance of AppOwnedSdkSandboxInterfaceCompat loaded by SDK classloader.
+     */
+    fun createFrom(source: AppOwnedSdkSandboxInterfaceCompat): Any {
+        return appOwnedSdkSandboxInterfaceCompatConstructor.newInstance(
+            /* parameter1 */ source.getName(),
+            /* parameter2 */ source.getVersion(),
+            /* parameter3 */ source.getInterface()
+        )
+    }
+
+    companion object {
+        fun createFor(classLoader: ClassLoader): AppOwnedSdkInterfaceProxyFactory {
+            val appOwnedSdkSandboxInterfaceCompatClass = Class.forName(
+                AppOwnedSdkSandboxInterfaceCompat::class.java.name,
+                /* initialize = */ false,
+                classLoader
+            )
+            val appOwnedSdkSandboxInterfaceCompatConstructor =
+                appOwnedSdkSandboxInterfaceCompatClass.getConstructor(
+                    /* name      */ String::class.java,
+                    /* version   */ Long::class.java,
+                    /* interface */ IBinder::class.java
+                )
+            return AppOwnedSdkInterfaceProxyFactory(appOwnedSdkSandboxInterfaceCompatConstructor)
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/BackPressedDispatcherProxyFactory.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/BackPressedDispatcherProxyFactory.kt
new file mode 100644
index 0000000..794d5c7
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/BackPressedDispatcherProxyFactory.kt
@@ -0,0 +1,124 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import android.annotation.SuppressLint
+import androidx.activity.OnBackPressedCallback
+import androidx.activity.OnBackPressedDispatcher
+import java.lang.reflect.Constructor
+import java.lang.reflect.InvocationHandler
+import java.lang.reflect.Method
+import java.lang.reflect.Proxy
+
+/**
+ * Create instance of [OnBackPressedDispatcher] class loaded by SDK Classloader.
+ * Set callback for [OnBackPressedDispatcher.onHasEnabledCallbacksChanged] and enable/disable
+ * callback in original [OnBackPressedDispatcher].
+ * Proxy [OnBackPressedDispatcher.onBackPressed] from original dispatcher to proxy.
+ */
+internal class BackPressedDispatcherProxyFactory(
+    private val onBackPressedDispatcherConstructor: Constructor<out Any>,
+    private val consumerClass: Class<*>,
+    private val dispatcherOnBackPressedMethod: Method,
+    private val sdkClassLoader: ClassLoader
+) {
+    fun setupOnBackPressedDispatcherProxy(
+        sourceDispatcher: OnBackPressedDispatcher
+    ): Any {
+        val enabledChangedHandler = OnHasEnabledCallbacksChangedHandler()
+
+        val onHasEnabledCallbacksChangedCallback = Proxy.newProxyInstance(
+            sdkClassLoader,
+            arrayOf(consumerClass),
+            enabledChangedHandler
+        )
+        val dispatcherProxy = onBackPressedDispatcherConstructor.newInstance(
+            /* parameter1 */ null,
+            /* parameter2 */ onHasEnabledCallbacksChangedCallback
+        )
+
+        val sourceDispatcherCallback =
+            SourceDispatcherCallback(dispatcherProxy, dispatcherOnBackPressedMethod)
+
+        enabledChangedHandler.sourceDispatcherCallback = sourceDispatcherCallback
+
+        sourceDispatcher.addCallback(sourceDispatcherCallback)
+
+        return dispatcherProxy
+    }
+
+    private class OnHasEnabledCallbacksChangedHandler : InvocationHandler {
+
+        var sourceDispatcherCallback: OnBackPressedCallback? = null
+
+        override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any {
+            return when (method.name) {
+                "equals" -> proxy === args?.get(0)
+                "hashCode" -> hashCode()
+                "toString" -> toString()
+                "accept" -> sourceDispatcherCallback?.isEnabled = args!![0] as Boolean
+                else -> {
+                    throw UnsupportedOperationException(
+                        "Unexpected method call object:$proxy, method: $method, args: $args"
+                    )
+                }
+            }
+        }
+    }
+
+    private class SourceDispatcherCallback(
+        private val dispatcherProxy: Any,
+        private val dispatcherOnBackPressedMethod: Method,
+    ) : OnBackPressedCallback(false) {
+
+        @SuppressLint("BanUncheckedReflection") // using reflection on library classes
+        override fun handleOnBackPressed() {
+            dispatcherOnBackPressedMethod.invoke(dispatcherProxy)
+        }
+    }
+
+    companion object {
+        fun createFor(classLoader: ClassLoader): BackPressedDispatcherProxyFactory {
+            val onBackPressedDispatcherClass = Class.forName(
+                "androidx.activity.OnBackPressedDispatcher",
+                /* initialize = */ false,
+                classLoader
+            )
+
+            val consumerClass = Class.forName(
+                "androidx.core.util.Consumer",
+                /* initialize = */ false,
+                classLoader
+            )
+
+            val onBackPressedDispatcherConstructor = onBackPressedDispatcherClass.getConstructor(
+                /* parameter1 */ Runnable::class.java,
+                /* parameter2 */ consumerClass
+            )
+
+            val dispatcherOnBackPressedMethod = onBackPressedDispatcherClass
+                .getMethod("onBackPressed")
+
+            return BackPressedDispatcherProxyFactory(
+                onBackPressedDispatcherConstructor,
+                consumerClass,
+                dispatcherOnBackPressedMethod,
+                classLoader
+            )
+        }
+    }
+}
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/LifecycleRegistryProxyFactory.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/LifecycleRegistryProxyFactory.kt
new file mode 100644
index 0000000..509cf50
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/LifecycleRegistryProxyFactory.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import android.annotation.SuppressLint
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
+import androidx.lifecycle.LifecycleOwner
+import java.lang.reflect.Constructor
+import java.lang.reflect.Method
+
+/**
+ * Create proxy of [Lifecycle] that implements same interface loaded by SDK Classloader.
+ * Proxy [Lifecycle.Event] from original object to proxy.
+ */
+internal class LifecycleRegistryProxyFactory private constructor(
+    private val lifecycleRegistryConstructor: Constructor<out Any>,
+    private val lifecycleEventInstances: Map<String, Any>,
+    private val handleLifecycleEventMethod: Method
+) {
+    fun setupLifecycleProxy(
+        activityHolderProxy: Any,
+        sourceLifecycle: Lifecycle
+    ): Any {
+        val registry = lifecycleRegistryConstructor.newInstance(activityHolderProxy)
+        sourceLifecycle.addObserver(object : LifecycleEventObserver {
+            @SuppressLint("BanUncheckedReflection") // using reflection on library classes
+            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
+                val enumInstance = lifecycleEventInstances[event.name]
+                if (enumInstance != null) {
+                    handleLifecycleEventMethod.invoke(registry, enumInstance)
+                }
+            }
+        })
+        return registry
+    }
+
+    companion object {
+        fun createFor(classLoader: ClassLoader): LifecycleRegistryProxyFactory {
+            val lifecycleOwnerClass = Class.forName(
+                "androidx.lifecycle.LifecycleOwner",
+                /* initialize = */ false,
+                classLoader
+            )
+            val lifecycleRegistryClass = Class.forName(
+                "androidx.lifecycle.LifecycleRegistry",
+                /* initialize = */ false,
+                classLoader
+            )
+            val lifecycleRegistryConstructor =
+                lifecycleRegistryClass.getConstructor(
+                    /* parameter1 */ lifecycleOwnerClass
+                )
+
+            val lifecycleEventEnum =
+                Class.forName(
+                    Lifecycle.Event::class.java.name,
+                    /* initialize = */ false,
+                    classLoader
+                )
+            val lifecycleEventInstances = lifecycleEventEnum
+                .enumConstants
+                .filterIsInstance(Enum::class.java)
+                .associateBy({ it.name }, { it })
+
+            val handleLifecycleEventMethod = lifecycleRegistryClass.getMethod(
+                "handleLifecycleEvent",
+                /* parameter1 */ lifecycleEventEnum
+            )
+
+            return LifecycleRegistryProxyFactory(
+                lifecycleRegistryConstructor,
+                lifecycleEventInstances,
+                handleLifecycleEventMethod
+            )
+        }
+    }
+}
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapper.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapper.kt
new file mode 100644
index 0000000..d9549f9
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/loader/impl/injector/SdkActivityHandlerWrapper.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.privacysandbox.sdkruntime.client.loader.impl.injector
+
+import android.annotation.SuppressLint
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import java.lang.reflect.Method
+
+/**
+ * Creates reflection wrapper for implementation of [SdkSandboxActivityHandlerCompat] interface
+ * loaded by SDK classloader.
+ */
+internal class SdkActivityHandlerWrapper private constructor(
+    private val activityHolderProxyFactory: ActivityHolderProxyFactory,
+    private val handlerOnActivityCreatedMethod: Method,
+) {
+
+    fun wrapSdkSandboxActivityHandlerCompat(handlerCompat: Any): SdkSandboxActivityHandlerCompat =
+        WrappedHandler(handlerCompat, handlerOnActivityCreatedMethod, activityHolderProxyFactory)
+
+    private class WrappedHandler(
+        private val originalHandler: Any,
+        private val handlerOnActivityCreatedMethod: Method,
+        private val activityHolderProxyFactory: ActivityHolderProxyFactory
+    ) : SdkSandboxActivityHandlerCompat {
+
+        @SuppressLint("BanUncheckedReflection") // using reflection on library classes
+        override fun onActivityCreated(activityHolder: ActivityHolder) {
+            val activityHolderProxy = activityHolderProxyFactory.createProxyFor(activityHolder)
+            handlerOnActivityCreatedMethod.invoke(originalHandler, activityHolderProxy)
+        }
+    }
+
+    companion object {
+        fun createFor(classLoader: ClassLoader): SdkActivityHandlerWrapper {
+            val sdkSandboxActivityHandlerCompatClass = Class.forName(
+                SdkSandboxActivityHandlerCompat::class.java.name,
+                /* initialize = */ false,
+                classLoader
+            )
+            val activityHolderClass = Class.forName(
+                ActivityHolder::class.java.name,
+                /* initialize = */ false,
+                classLoader
+            )
+            val handlerOnActivityCreatedMethod =
+                sdkSandboxActivityHandlerCompatClass.getMethod(
+                    "onActivityCreated",
+                    activityHolderClass
+                )
+
+            val activityHolderProxyFactory = ActivityHolderProxyFactory.createFor(classLoader)
+
+            return SdkActivityHandlerWrapper(
+                activityHolderProxyFactory = activityHolderProxyFactory,
+                handlerOnActivityCreatedMethod = handlerOnActivityCreatedMethod
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt b/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
index 56a2116..e062bff 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/api/current.txt
@@ -1,6 +1,13 @@
 // Signature format: 4.0
 package androidx.privacysandbox.sdkruntime.core {
 
+  public final class AppOwnedSdkSandboxInterfaceCompat {
+    ctor public AppOwnedSdkSandboxInterfaceCompat(String name, long version, android.os.IBinder binder);
+    method public android.os.IBinder getInterface();
+    method public String getName();
+    method public long getVersion();
+  }
+
   public final class LoadSdkCompatException extends java.lang.Exception {
     ctor public LoadSdkCompatException(Throwable cause, android.os.Bundle extraInfo);
     method public android.os.Bundle getExtraInformation();
@@ -51,11 +58,27 @@
 
 }
 
+package androidx.privacysandbox.sdkruntime.core.activity {
+
+  public interface ActivityHolder extends androidx.lifecycle.LifecycleOwner {
+    method public android.app.Activity getActivity();
+    method public androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+  }
+
+  public interface SdkSandboxActivityHandlerCompat {
+    method public void onActivityCreated(androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder activityHolder);
+  }
+
+}
+
 package androidx.privacysandbox.sdkruntime.core.controller {
 
   public final class SdkSandboxControllerCompat {
     method public static androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat from(android.content.Context context);
+    method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
+    method public android.os.IBinder registerSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
+    method public void unregisterSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     field public static final androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat.Companion Companion;
   }
 
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt b/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
index 56a2116..e062bff 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/api/restricted_current.txt
@@ -1,6 +1,13 @@
 // Signature format: 4.0
 package androidx.privacysandbox.sdkruntime.core {
 
+  public final class AppOwnedSdkSandboxInterfaceCompat {
+    ctor public AppOwnedSdkSandboxInterfaceCompat(String name, long version, android.os.IBinder binder);
+    method public android.os.IBinder getInterface();
+    method public String getName();
+    method public long getVersion();
+  }
+
   public final class LoadSdkCompatException extends java.lang.Exception {
     ctor public LoadSdkCompatException(Throwable cause, android.os.Bundle extraInfo);
     method public android.os.Bundle getExtraInformation();
@@ -51,11 +58,27 @@
 
 }
 
+package androidx.privacysandbox.sdkruntime.core.activity {
+
+  public interface ActivityHolder extends androidx.lifecycle.LifecycleOwner {
+    method public android.app.Activity getActivity();
+    method public androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
+  }
+
+  public interface SdkSandboxActivityHandlerCompat {
+    method public void onActivityCreated(androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder activityHolder);
+  }
+
+}
+
 package androidx.privacysandbox.sdkruntime.core.controller {
 
   public final class SdkSandboxControllerCompat {
     method public static androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat from(android.content.Context context);
+    method public java.util.List<androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat> getAppOwnedSdkSandboxInterfaces();
     method public java.util.List<androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat> getSandboxedSdks();
+    method public android.os.IBinder registerSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
+    method public void unregisterSdkSandboxActivityHandler(androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat handlerCompat);
     field public static final androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat.Companion Companion;
   }
 
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/build.gradle b/privacysandbox/sdkruntime/sdkruntime-core/build.gradle
index 68c7464..2eec85b 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/build.gradle
+++ b/privacysandbox/sdkruntime/sdkruntime-core/build.gradle
@@ -26,7 +26,8 @@
     api(libs.kotlinStdlib)
     api("androidx.annotation:annotation:1.6.0")
 
-    implementation("androidx.core:core:1.8.0")
+    implementation("androidx.core:core:1.12.0-alpha05")
+    implementation("androidx.activity:activity:1.8.0-alpha05")
 
     // TODO(b/249982004): cleanup dependencies
     androidTestImplementation(libs.testCore)
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/lint-baseline.xml b/privacysandbox/sdkruntime/sdkruntime-core/lint-baseline.xml
new file mode 100644
index 0000000..4f913f5e
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+
+    <issue
+        id="PrereleaseSdkCoreDependency"
+        message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+        errorLine1="                if (BuildCompat.isAtLeastU()) {"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt"/>
+    </issue>
+
+</issues>
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompatTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompatTest.kt
new file mode 100644
index 0000000..22d69b5
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompatTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.privacysandbox.sdkruntime.core
+
+import android.os.Binder
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 35, codeName = "UpsideDownCakePrivacySandbox")
+class AppOwnedSdkSandboxInterfaceCompatTest {
+
+    @Test
+    fun converterTest() {
+        val converter = AppOwnedInterfaceConverter()
+
+        val compatObj = AppOwnedSdkSandboxInterfaceCompat(
+            name = "SDK",
+            version = 1,
+            binder = Binder()
+        )
+
+        val platformObj = converter.toPlatform(compatObj)
+        assertThat(platformObj.javaClass.name)
+            .isEqualTo("android.app.sdksandbox.AppOwnedSdkSandboxInterface")
+
+        val convertedCompatObj = converter.toCompat(platformObj)
+
+        assertThat(convertedCompatObj.getName()).isEqualTo(compatObj.getName())
+        assertThat(convertedCompatObj.getVersion()).isEqualTo(compatObj.getVersion())
+        assertThat(convertedCompatObj.getInterface()).isEqualTo(compatObj.getInterface())
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt
new file mode 100644
index 0000000..a9c750d
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerAppOwnedInterfacesTest.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.privacysandbox.sdkruntime.core.controller
+
+import android.annotation.SuppressLint
+import android.app.sdksandbox.sdkprovider.SdkSandboxController
+import android.content.Context
+import android.os.Binder
+import android.os.Build
+import android.os.ext.SdkExtensions
+import androidx.annotation.RequiresExtension
+import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedInterfaceConverter
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
+import org.junit.Test
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when`
+
+// TODO(b/249982507) Rewrite test to use real SDK in sandbox instead of mocking controller
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+class SdkSandboxControllerAppOwnedInterfacesTest {
+
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_whenControllerNotAvailable_returnsEmptyList() {
+        assumeFalse(
+            "Requires SandboxController not available",
+            isSandboxControllerAvailable()
+        )
+
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).isEmpty()
+    }
+
+    @Test
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    fun getAppOwnedSdkSandboxInterfaces_whenApiNotAvailable_returnsEmptyList() {
+        assumeTrue(
+            "Requires SandboxController available",
+            isSandboxControllerAvailable()
+        )
+        assumeFalse(
+            "Requires AppOwnedInterfaces API not available",
+            isAppOwnedInterfacesApiAvailable()
+        )
+
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val sdkSandboxController = mock(SdkSandboxController::class.java)
+        doReturn(sdkSandboxController)
+            .`when`(context).getSystemService(SdkSandboxController::class.java)
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).isEmpty()
+        verifyZeroInteractions(sdkSandboxController)
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = 35, codeName = "UpsideDownCakePrivacySandbox")
+    fun getAppOwnedSdkSandboxInterfaces_whenApiAvailable_delegateToPlatform() {
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val controllerMock = mock(SdkSandboxController::class.java)
+        doReturn(controllerMock)
+            .`when`(context).getSystemService(SdkSandboxController::class.java)
+
+        val expectedObj = AppOwnedSdkSandboxInterfaceCompat(
+            name = "test",
+            version = 1,
+            binder = Binder()
+        )
+        setupMockedMethodResult(controllerMock, expectedObj)
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).hasSize(1)
+        val resultObj = appOwnedInterfaces[0]
+
+        assertThat(resultObj.getName()).isEqualTo(expectedObj.getName())
+        assertThat(resultObj.getVersion()).isEqualTo(expectedObj.getVersion())
+        assertThat(resultObj.getInterface()).isEqualTo(expectedObj.getInterface())
+    }
+
+    private fun isSandboxControllerAvailable() =
+        AdServicesInfo.isAtLeastV5()
+
+    private fun isAppOwnedInterfacesApiAvailable() =
+        AdServicesInfo.isDeveloperPreview()
+
+    companion object AppOwnedInterfacesApi { // to avoid fail if SdkSandboxController not present
+        @SuppressLint("NewApi", "ClassVerificationFailure") // UpsideDownCakePrivacySandbox is UDC
+        private fun setupMockedMethodResult(
+            controllerMock: SdkSandboxController,
+            result: AppOwnedSdkSandboxInterfaceCompat
+        ) {
+            val getAppOwnedInterfacesMethod = SdkSandboxController::class.java.getDeclaredMethod(
+                "getAppOwnedSdkSandboxInterfaces"
+            )
+
+            val platformObj = AppOwnedInterfaceConverter().toPlatform(result)
+
+            // Mockito require method call to setup result. Reflection call works same way as normal.
+            `when`(getAppOwnedInterfacesMethod.invoke(controllerMock))
+                .thenReturn(listOf(platformObj))
+        }
+    }
+}
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
index 1307cec..a37f3f2 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatLocalTest.kt
@@ -18,13 +18,18 @@
 
 import android.content.Context
 import android.os.Binder
+import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
+import org.junit.Assert
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -71,9 +76,138 @@
         assertThat(sandboxedSdks).isEqualTo(expectedResult)
     }
 
-    private class TestStubImpl(
-        private val sandboxedSdks: List<SandboxedSdkCompat> = emptyList()
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_withoutLocalImpl_returnsEmptyList() {
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).isEmpty()
+    }
+
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_clientApiBelow4_returnsEmptyList() {
+        // Emulate loading via client lib with version below 4
+        Versions.handShake(3)
+
+        SdkSandboxControllerCompat.injectLocalImpl(
+            TestStubImpl(
+                appOwnedSdks = listOf(
+                    AppOwnedSdkSandboxInterfaceCompat(
+                        name = "TestSdk",
+                        version = 42,
+                        binder = Binder(),
+                    )
+                )
+            )
+        )
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).isEmpty()
+    }
+
+    @Test
+    fun getAppOwnedSdkSandboxInterfaces_withLocalImpl_returnsListFromLocalImpl() {
+        val expectedResult = listOf(
+            AppOwnedSdkSandboxInterfaceCompat(
+                name = "TestSdk",
+                version = 42,
+                binder = Binder(),
+            )
+        )
+        SdkSandboxControllerCompat.injectLocalImpl(
+            TestStubImpl(
+                appOwnedSdks = expectedResult
+            )
+        )
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val appOwnedInterfaces = controllerCompat.getAppOwnedSdkSandboxInterfaces()
+        assertThat(appOwnedInterfaces).isEqualTo(expectedResult)
+    }
+
+    @Test
+    fun registerSdkSandboxActivityHandler_withLocalImpl_registerItInLocalImpl() {
+        val localImpl = TestStubImpl()
+        SdkSandboxControllerCompat.injectLocalImpl(localImpl)
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val handlerCompat = object : SdkSandboxActivityHandlerCompat {
+            override fun onActivityCreated(activityHolder: ActivityHolder) {}
+        }
+        val token = controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
+        assertThat(token).isEqualTo(localImpl.token)
+    }
+
+    @Test
+    fun unregisterSdkSandboxActivityHandler_withLocalImpl_unregisterItFromLocalImpl() {
+        val localImpl = TestStubImpl()
+        SdkSandboxControllerCompat.injectLocalImpl(localImpl)
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val handlerCompat = object : SdkSandboxActivityHandlerCompat {
+            override fun onActivityCreated(activityHolder: ActivityHolder) {}
+        }
+        val token = controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
+        assertThat(token).isEqualTo(localImpl.token)
+
+        controllerCompat.unregisterSdkSandboxActivityHandler(handlerCompat)
+        assertThat(localImpl.token).isNull()
+    }
+
+    @Test
+    fun registerSdkSandboxActivityHandler_clientApiBelow3_throwsUnsupportedOperationException() {
+        // Emulate loading via client lib with version below 3
+        Versions.handShake(2)
+
+        SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        Assert.assertThrows(UnsupportedOperationException::class.java) {
+            controllerCompat.registerSdkSandboxActivityHandler(
+                object : SdkSandboxActivityHandlerCompat {
+                    override fun onActivityCreated(activityHolder: ActivityHolder) {}
+                }
+            )
+        }
+    }
+
+    @Test
+    fun unregisterSdkSandboxActivityHandler_clientApiBelow3_throwsUnsupportedOperationException() {
+        // Emulate loading via client lib with version below 3
+        Versions.handShake(2)
+
+        SdkSandboxControllerCompat.injectLocalImpl(TestStubImpl())
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+
+        Assert.assertThrows(UnsupportedOperationException::class.java) {
+            controllerCompat.unregisterSdkSandboxActivityHandler(
+                object : SdkSandboxActivityHandlerCompat {
+                    override fun onActivityCreated(activityHolder: ActivityHolder) {}
+                }
+            )
+        }
+    }
+
+    internal class TestStubImpl(
+        private val sandboxedSdks: List<SandboxedSdkCompat> = emptyList(),
+        private val appOwnedSdks: List<AppOwnedSdkSandboxInterfaceCompat> = emptyList()
     ) : SdkSandboxControllerCompat.SandboxControllerImpl {
+        var token: IBinder? = null
         override fun getSandboxedSdks() = sandboxedSdks
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+            appOwnedSdks
+
+        override fun registerSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ): IBinder {
+            token = Binder()
+            return token!!
+        }
+
+        override fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        ) {
+            token = null
+        }
     }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
index b133fe0..bcac996 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/androidTest/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompatSandboxedTest.kt
@@ -16,23 +16,35 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller
 
+import android.app.Activity
+import android.app.Application
 import android.app.sdksandbox.SandboxedSdk
+import android.app.sdksandbox.sdkprovider.SdkSandboxActivityHandler
 import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
 import android.os.Binder
 import android.os.Build
+import android.os.Bundle
 import android.os.ext.SdkExtensions
+import android.window.OnBackInvokedDispatcher
 import androidx.annotation.RequiresExtension
+import androidx.lifecycle.Lifecycle
 import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.SdkSuppress
+import androidx.test.internal.runner.junit4.statement.UiThreadStatement
 import com.google.common.truth.Truth.assertThat
+import org.junit.Assert
 import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
 import org.junit.Test
+import org.mockito.ArgumentCaptor
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.Mockito.`when`
 
@@ -41,7 +53,7 @@
 class SdkSandboxControllerCompatSandboxedTest {
 
     @Test
-    fun getSandboxedSdks_whenApiNotAvailable_notDelegateToSandbox() {
+    fun controllerAPIs_whenApiNotAvailable_notDelegateToSandbox() {
         assumeFalse(
             "Requires SandboxController API not available",
             isSandboxControllerAvailable()
@@ -51,7 +63,15 @@
         val controllerCompat = SdkSandboxControllerCompat.from(context)
 
         controllerCompat.getSandboxedSdks()
-
+        val handlerCompat = object : SdkSandboxActivityHandlerCompat {
+            override fun onActivityCreated(activityHolder: ActivityHolder) {}
+        }
+        Assert.assertThrows(UnsupportedOperationException::class.java) {
+            controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
+        }
+        Assert.assertThrows(UnsupportedOperationException::class.java) {
+            controllerCompat.unregisterSdkSandboxActivityHandler(handlerCompat)
+        }
         verifyZeroInteractions(context)
     }
 
@@ -97,6 +117,120 @@
         assertThat(result.getInterface()).isEqualTo(sandboxedSdk.getInterface())
     }
 
+    @Test
+    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    fun registerSdkSandboxHandlerCompat_whenApiAvailable_registerItToPlatform() {
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val sdkSandboxController = mock(SdkSandboxController::class.java)
+        doReturn(sdkSandboxController)
+            .`when`(context).getSystemService(SdkSandboxController::class.java)
+
+        val platformRegisteredHandlerCaptor = ArgumentCaptor.forClass(
+            SdkSandboxActivityHandler::class.java)
+        doReturn(Binder())
+            .`when`(sdkSandboxController).registerSdkSandboxActivityHandler(
+                platformRegisteredHandlerCaptor.capture())
+
+        val handlerCompat = mock(SdkSandboxActivityHandlerCompat::class.java)
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
+
+        verify(sdkSandboxController).registerSdkSandboxActivityHandler(
+            platformRegisteredHandlerCaptor.value
+        )
+
+        val activityMock = mock(Activity::class.java)
+        val onBackInvokedDispatcher = mock(OnBackInvokedDispatcher::class.java)
+        doReturn(onBackInvokedDispatcher).`when`(activityMock).onBackInvokedDispatcher
+
+        platformRegisteredHandlerCaptor.value.onActivityCreated(activityMock)
+        var activityHolderCaptor: ArgumentCaptor<ActivityHolder> =
+            ArgumentCaptor.forClass(ActivityHolder::class.java)
+        verify(handlerCompat).onActivityCreated(capture(activityHolderCaptor))
+        assertThat(activityHolderCaptor.value.getActivity()).isEqualTo(activityMock)
+
+        assertThat(activityHolderCaptor.value.getOnBackPressedDispatcher()).isNotNull()
+
+        assertThat(activityHolderCaptor.value.lifecycle).isNotNull()
+        var activityLifecycleCallbackCaptor:
+            ArgumentCaptor<Application.ActivityLifecycleCallbacks> =
+            ArgumentCaptor.forClass(Application.ActivityLifecycleCallbacks::class.java)
+        verify(activityMock).registerActivityLifecycleCallbacks(
+            activityLifecycleCallbackCaptor.capture()
+        )
+        var bundleMock = mock(Bundle::class.java)
+        UiThreadStatement.runOnUiThread {
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.INITIALIZED)
+            activityLifecycleCallbackCaptor.value.onActivityCreated(activityMock, bundleMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.CREATED)
+
+            activityLifecycleCallbackCaptor.value.onActivityStarted(activityMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.STARTED)
+
+            activityLifecycleCallbackCaptor.value.onActivityResumed(activityMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.RESUMED)
+
+            activityLifecycleCallbackCaptor.value.onActivityPaused(activityMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.STARTED)
+
+            activityLifecycleCallbackCaptor.value.onActivityStopped(activityMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.CREATED)
+
+            activityLifecycleCallbackCaptor.value.onActivityDestroyed(activityMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(
+                Lifecycle.State.DESTROYED)
+
+            val currentState = activityHolderCaptor.value.lifecycle.currentState
+            activityLifecycleCallbackCaptor.value.onActivitySaveInstanceState(
+                activityMock, bundleMock)
+            assertThat(activityHolderCaptor.value.lifecycle.currentState).isEqualTo(currentState)
+        }
+    }
+
+    @Test
+    // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
+    @RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+    fun unregisterSdkSandboxHandlerCompat_whenApiAvailable_unregisterItToPlatform() {
+        val context = spy(ApplicationProvider.getApplicationContext<Context>())
+        val sdkSandboxController = mock(SdkSandboxController::class.java)
+        doReturn(sdkSandboxController)
+            .`when`(context).getSystemService(SdkSandboxController::class.java)
+
+        val registeredHandlerCaptor = ArgumentCaptor.forClass(SdkSandboxActivityHandler::class.java)
+        doReturn(Binder())
+            .`when`(sdkSandboxController).registerSdkSandboxActivityHandler(
+                registeredHandlerCaptor.capture())
+
+        val controllerCompat = SdkSandboxControllerCompat.from(context)
+        val handlerCompat = mock(SdkSandboxActivityHandlerCompat::class.java)
+
+        controllerCompat.registerSdkSandboxActivityHandler(handlerCompat)
+        verify(sdkSandboxController).registerSdkSandboxActivityHandler(
+            registeredHandlerCaptor.value)
+
+        val unregisteredHandlerCaptor = ArgumentCaptor.forClass(
+            SdkSandboxActivityHandler::class.java
+        )
+        controllerCompat.unregisterSdkSandboxActivityHandler(handlerCompat)
+        verify(sdkSandboxController).unregisterSdkSandboxActivityHandler(
+            unregisteredHandlerCaptor.capture())
+
+        assertThat(unregisteredHandlerCaptor.value).isEqualTo(registeredHandlerCaptor.value)
+    }
+
     private fun isSandboxControllerAvailable() =
         AdServicesInfo.isAtLeastV5()
+
+    // To capture non null arguments.
+
+    private fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
 }
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AdServicesInfo.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AdServicesInfo.kt
index 67e884b..3cc4ee9 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AdServicesInfo.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AdServicesInfo.kt
@@ -18,6 +18,7 @@
 
 import android.os.Build
 import android.os.ext.SdkExtensions
+import androidx.annotation.ChecksSdkIntAtLeast
 import androidx.annotation.DoNotInline
 import androidx.annotation.RequiresApi
 import androidx.annotation.RestrictTo
@@ -41,6 +42,10 @@
             Extensions30Impl.isAtLeastV5()
     }
 
+    @ChecksSdkIntAtLeast(codename = "UpsideDownCake")
+    fun isDeveloperPreview(): Boolean =
+        Build.VERSION.CODENAME.equals("UpsideDownCakePrivacySandbox")
+
     @RequiresApi(30)
     private object Extensions30Impl {
         @DoNotInline
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedInterfaceConverter.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedInterfaceConverter.kt
new file mode 100644
index 0000000..b28e5e3
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedInterfaceConverter.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.privacysandbox.sdkruntime.core
+
+import android.annotation.SuppressLint
+import android.os.IBinder
+import androidx.annotation.RestrictTo
+
+/**
+ * Temporary converter of [AppOwnedSdkSandboxInterfaceCompat] to platform
+ * AppOwnedSdkSandboxInterface and back.
+ *
+ * Could be used only with Developer Preview 8 build.
+ * Using reflection to call public methods / constructors.
+ *
+ * TODO(b/281397807) Should be removed as soon as prebuilt with new API will be available.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class AppOwnedInterfaceConverter {
+
+    private val appOwnedInterfaceClass = Class.forName(
+        "android.app.sdksandbox.AppOwnedSdkSandboxInterface"
+    )
+
+    private val appOwnedInterfaceConstructor = appOwnedInterfaceClass.getConstructor(
+        /* name      */ String::class.java,
+        /* version   */ Long::class.java,
+        /* interface */ IBinder::class.java
+    )
+
+    private val getNameMethod = appOwnedInterfaceClass.getMethod("getName")
+
+    private val getVersionMethod = appOwnedInterfaceClass.getMethod("getVersion")
+
+    private val getInterfaceMethod = appOwnedInterfaceClass.getMethod("getInterface")
+
+    @SuppressLint("BanUncheckedReflection") // calling public non restricted methods
+    fun toCompat(platformObject: Any): AppOwnedSdkSandboxInterfaceCompat {
+        val name = getNameMethod.invoke(platformObject) as String
+        val version = getVersionMethod.invoke(platformObject) as Long
+        val binder = getInterfaceMethod.invoke(platformObject) as IBinder
+        return AppOwnedSdkSandboxInterfaceCompat(name, version, binder)
+    }
+
+    fun toPlatform(compatObject: AppOwnedSdkSandboxInterfaceCompat): Any {
+        return appOwnedInterfaceConstructor.newInstance(
+            compatObject.getName(),
+            compatObject.getVersion(),
+            compatObject.getInterface()
+        )
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompat.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompat.kt
new file mode 100644
index 0000000..8a4b4cd
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/AppOwnedSdkSandboxInterfaceCompat.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.privacysandbox.sdkruntime.core
+
+import android.os.IBinder
+
+/**
+ * Represents a channel for an SDK in the sandbox process to interact with the app.
+ *
+ * The SDK and the app can agree on a binder interface to be implemented by the app and shared
+ * via an object of [AppOwnedSdkSandboxInterfaceCompat].
+ *
+ * The app registers the AppOwnedSdkSandboxInterfaces using SdkSandboxManagerCompat.
+ * The SDK can then query the list of registered interfaces using SdkSandboxControllerCompat.
+ *
+ * Once SDK has the [AppOwnedSdkSandboxInterfaceCompat] it wants to communicate with, it will have
+ * to cast the binder object from [getInterface] to the prearranged interface before initiating
+ * the communication.
+ */
+class AppOwnedSdkSandboxInterfaceCompat(
+    private val name: String,
+    private val version: Long,
+    private val binder: IBinder
+) {
+
+    /**
+     * Returns the name used to register the [AppOwnedSdkSandboxInterfaceCompat].
+     *
+     * App can register only one interface of given name.
+     */
+    fun getName(): String = name
+
+    /**
+     * Returns the version used to register the [AppOwnedSdkSandboxInterfaceCompat].
+     *
+     * A version may be chosen by an app, and used to communicate any updates the app makes to
+     * this implementation.
+     */
+    fun getVersion(): Long = version
+
+    /**
+     * Returns binder object associated with [AppOwnedSdkSandboxInterfaceCompat].
+     *
+     * The SDK and the app can agree on a binder interface to be implemented by the app and
+     * shared via this object.
+     *
+     * The SDK in the sandbox will have to cast the binder object received from this method to
+     * the agreed upon interface before using it.
+     */
+    fun getInterface(): IBinder = binder
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
index 18585d0..e124d2e3 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/Versions.kt
@@ -31,7 +31,7 @@
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
 object Versions {
 
-    const val API_VERSION = 2
+    const val API_VERSION = 4
 
     @JvmField
     var CLIENT_VERSION: Int? = null
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/ActivityHolder.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/ActivityHolder.kt
new file mode 100644
index 0000000..8832f0e
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/ActivityHolder.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.privacysandbox.sdkruntime.core.activity
+
+import android.app.Activity
+import androidx.activity.OnBackPressedDispatcher
+import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+
+/**
+ * A holder for the [Activity] created for SDK.
+ *
+ * This is passed to SDKs through [SdkSandboxActivityHandlerCompat.onActivityCreated] to notify SDKs
+ * about the created [Activity].
+ *
+ * SDK can add [LifecycleObserver]s into it to observe the [Activity] lifecycle state.
+ */
+interface ActivityHolder : LifecycleOwner {
+    /**
+     * The [Activity] created for SDK.
+     */
+    fun getActivity(): Activity
+
+    /**
+     * The [OnBackPressedDispatcher] for the created [Activity].
+     */
+    fun getOnBackPressedDispatcher(): OnBackPressedDispatcher
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/SdkSandboxActivityHandlerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/SdkSandboxActivityHandlerCompat.kt
new file mode 100644
index 0000000..b41250a
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/activity/SdkSandboxActivityHandlerCompat.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.privacysandbox.sdkruntime.core.activity
+
+import android.app.Activity
+import android.app.sdksandbox.sdkprovider.SdkSandboxActivityHandler
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+
+/**
+ * This is used to notify the SDK when an [Activity] is created for it.
+ *
+ * When an SDK wants to start an [Activity], it should register an implementation of this class by
+ * calling [SdkSandboxControllerCompat.registerSdkSandboxActivityHandler] that will return an
+ * [android.os.Binder] identifier for the registered [SdkSandboxControllerCompat].
+ *
+ * The SDK should be notified about the [Activity] creation through calling
+ * [SdkSandboxActivityHandlerCompat.onActivityCreated] which happens when the caller app calls
+ * `SdkSandboxManagerCompat#startSdkSandboxActivity(Activity, IBinder)` using the same
+ * [android.os.IBinder] identifier for the registered [SdkSandboxActivityHandlerCompat].
+ *
+ * @see SdkSandboxActivityHandler
+ */
+interface SdkSandboxActivityHandlerCompat {
+
+    /**
+     * Notifies SDK when an [Activity] gets created.
+     *
+     * This function is called synchronously from the main thread of the [Activity] that is getting
+     * created.
+     *
+     * SDK is expected to call [Activity.setContentView] to the passed [Activity] object to populate
+     * the view.
+     *
+     * @param activityHolder the [ActivityHolder] which holds the [Activity] which gets created
+     * @see SdkSandboxActivityHandler.onActivityCreated
+     */
+    fun onActivityCreated(activityHolder: ActivityHolder)
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
index 9575052..31494d2 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/SdkSandboxControllerCompat.kt
@@ -16,16 +16,24 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller
 
+import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
+import android.os.IBinder
 import androidx.annotation.Keep
+import androidx.annotation.OptIn
 import androidx.annotation.RestrictTo
 import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
+import androidx.core.os.BuildCompat
 import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
 import androidx.privacysandbox.sdkruntime.core.Versions
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.privacysandbox.sdkruntime.core.controller.impl.LocalImpl
 import androidx.privacysandbox.sdkruntime.core.controller.impl.NoOpImpl
 import androidx.privacysandbox.sdkruntime.core.controller.impl.PlatformImpl
+import androidx.privacysandbox.sdkruntime.core.controller.impl.PlatformUDCImpl
 import org.jetbrains.annotations.TestOnly
 
 /**
@@ -56,10 +64,56 @@
     fun getSandboxedSdks(): List<SandboxedSdkCompat> =
         controllerImpl.getSandboxedSdks()
 
+    /**
+     * Fetches all [AppOwnedSdkSandboxInterfaceCompat] that are registered by the app.
+     *
+     * @return List of all currently registered [AppOwnedSdkSandboxInterfaceCompat]
+     */
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        controllerImpl.getAppOwnedSdkSandboxInterfaces()
+
+    /**
+     * Returns an identifier for a [SdkSandboxActivityHandlerCompat] after registering it.
+     *
+     * This function registers an implementation of [SdkSandboxActivityHandlerCompat] created by
+     * an SDK and returns an [IBinder] which uniquely identifies the passed
+     * [SdkSandboxActivityHandlerCompat] object.
+     *
+     * @param handlerCompat is the [SdkSandboxActivityHandlerCompat] to register
+     * @return [IBinder] uniquely identify the passed [SdkSandboxActivityHandlerCompat]
+     * @see SdkSandboxController.registerSdkSandboxActivityHandler
+     */
+    fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+        IBinder = controllerImpl.registerSdkSandboxActivityHandler(handlerCompat)
+
+    /**
+     * Unregister an already registered [SdkSandboxActivityHandlerCompat].
+     *
+     * If the passed [SdkSandboxActivityHandlerCompat] is registered, it will be unregistered.
+     * Otherwise, it will do nothing.
+     *
+     * If the [IBinder] token of the unregistered handler used to start a [android.app.Activity],
+     * the [android.app.Activity] will fail to start.
+     *
+     * @param handlerCompat is the [SdkSandboxActivityHandlerCompat] to unregister.
+     * @see SdkSandboxController.unregisterSdkSandboxActivityHandler
+     */
+    fun unregisterSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat) =
+        controllerImpl.unregisterSdkSandboxActivityHandler(handlerCompat)
+
     /** @suppress */
     @RestrictTo(LIBRARY_GROUP)
     interface SandboxControllerImpl {
         fun getSandboxedSdks(): List<SandboxedSdkCompat>
+
+        fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat>
+
+        fun registerSdkSandboxActivityHandler(handlerCompat: SdkSandboxActivityHandlerCompat):
+            IBinder
+
+        fun unregisterSdkSandboxActivityHandler(
+            handlerCompat: SdkSandboxActivityHandlerCompat
+        )
     }
 
     companion object {
@@ -75,20 +129,16 @@
          */
         @JvmStatic
         fun from(context: Context): SdkSandboxControllerCompat {
-            val loadedLocally = Versions.CLIENT_VERSION != null
-            if (loadedLocally) {
+            val clientVersion = Versions.CLIENT_VERSION
+            if (clientVersion != null) {
                 val implFromClient = localImpl
                 if (implFromClient != null) {
-                    return SdkSandboxControllerCompat(implFromClient)
+                    return SdkSandboxControllerCompat(LocalImpl(implFromClient, clientVersion))
                 }
                 return SdkSandboxControllerCompat(NoOpImpl())
             }
-
-            if (AdServicesInfo.isAtLeastV5()) {
-                return SdkSandboxControllerCompat(PlatformImpl.from(context))
-            }
-
-            return SdkSandboxControllerCompat(NoOpImpl())
+            val platformImpl = PlatformImplFactory.create(context)
+            return SdkSandboxControllerCompat(platformImpl)
         }
 
         /**
@@ -112,4 +162,17 @@
             localImpl = null
         }
     }
+
+    private object PlatformImplFactory {
+        @OptIn(markerClass = [BuildCompat.PrereleaseSdkCheck::class])
+        fun create(context: Context): SandboxControllerImpl {
+            if (AdServicesInfo.isAtLeastV5()) {
+                if (BuildCompat.isAtLeastU() || AdServicesInfo.isDeveloperPreview()) {
+                    return PlatformUDCImpl.from(context)
+                }
+                return PlatformImpl.from(context)
+            }
+            return NoOpImpl()
+        }
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/AppOwnedSdkProvider.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/AppOwnedSdkProvider.kt
new file mode 100644
index 0000000..bef25e8
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/AppOwnedSdkProvider.kt
@@ -0,0 +1,79 @@
+/*
+ * 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.privacysandbox.sdkruntime.core.controller.impl
+
+import android.annotation.SuppressLint
+import android.app.sdksandbox.sdkprovider.SdkSandboxController
+import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
+import androidx.privacysandbox.sdkruntime.core.AppOwnedInterfaceConverter
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+
+/**
+ * Fetches all registered [AppOwnedSdkSandboxInterfaceCompat] from [SdkSandboxController].
+ */
+internal class AppOwnedSdkProvider private constructor(
+    private val providerImpl: ProviderImpl
+) {
+
+    fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        providerImpl.getAppOwnedSdkSandboxInterfaces()
+
+    private interface ProviderImpl {
+        fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat>
+    }
+
+    /**
+     * Implementation for cases when API not supported by [SdkSandboxController]
+     */
+    private class NoOpImpl : ProviderImpl {
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+            return emptyList()
+        }
+    }
+
+    /**
+     * Implementation for Developer Preview builds.
+     * Using reflection to call public methods / constructors.
+     * TODO(b/281397807) Replace reflection for method calls when new prebuilt will be available.
+     */
+    private class DeveloperPreviewImpl(
+        private val controller: SdkSandboxController
+    ) : ProviderImpl {
+
+        private val getAppOwnedSdkSandboxInterfacesMethod = controller.javaClass.getMethod(
+            "getAppOwnedSdkSandboxInterfaces",
+        )
+
+        private val converter: AppOwnedInterfaceConverter = AppOwnedInterfaceConverter()
+
+        @SuppressLint("BanUncheckedReflection") // calling public non restricted methods
+        override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+            val apiResult = getAppOwnedSdkSandboxInterfacesMethod.invoke(controller) as List<*>
+            return apiResult.map { converter.toCompat(it!!) }
+        }
+    }
+
+    companion object {
+        fun create(controller: SdkSandboxController): AppOwnedSdkProvider {
+            return if (AdServicesInfo.isDeveloperPreview()) {
+                AppOwnedSdkProvider(DeveloperPreviewImpl(controller))
+            } else {
+                AppOwnedSdkProvider(NoOpImpl())
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
new file mode 100644
index 0000000..f90237c2
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/LocalImpl.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.privacysandbox.sdkruntime.core.controller.impl
+
+import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+
+/**
+ * Wrapper for client provided implementation of [SdkSandboxControllerCompat].
+ * Checks client version to determine if method supported.
+ */
+internal class LocalImpl(
+    private val implFromClient: SdkSandboxControllerCompat.SandboxControllerImpl,
+    private val clientVersion: Int
+) : SdkSandboxControllerCompat.SandboxControllerImpl {
+    override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+        return implFromClient.getSandboxedSdks()
+    }
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> {
+        return if (clientVersion >= 4) {
+            implFromClient.getAppOwnedSdkSandboxInterfaces()
+        } else {
+            emptyList()
+        }
+    }
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        return implFromClient.registerSdkSandboxActivityHandler(handlerCompat)
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        if (clientVersion < 3) {
+            throw UnsupportedOperationException(
+                "Client library version doesn't support SdkActivities"
+            )
+        }
+        implFromClient.unregisterSdkSandboxActivityHandler(handlerCompat)
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
index cc0bfa3..cbe53ec 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/NoOpImpl.kt
@@ -16,7 +16,10 @@
 
 package androidx.privacysandbox.sdkruntime.core.controller.impl
 
+import android.os.IBinder
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 
 /**
@@ -24,4 +27,20 @@
  */
 internal class NoOpImpl : SdkSandboxControllerCompat.SandboxControllerImpl {
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        emptyList()
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ):
+        IBinder {
+        throw UnsupportedOperationException("Not supported")
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        throw UnsupportedOperationException("Not supported")
+    }
 }
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt
index ce2e035..7b487ec 100644
--- a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformImpl.kt
@@ -18,10 +18,13 @@
 
 import android.app.sdksandbox.sdkprovider.SdkSandboxController
 import android.content.Context
+import android.os.IBinder
 import android.os.ext.SdkExtensions.AD_SERVICES
 import androidx.annotation.RequiresApi
 import androidx.annotation.RequiresExtension
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
 import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
 import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
 
 /**
@@ -29,16 +32,33 @@
  */
 @RequiresApi(33)
 @RequiresExtension(extension = AD_SERVICES, version = 5)
-internal class PlatformImpl(
+internal open class PlatformImpl(
     private val controller: SdkSandboxController
 ) : SdkSandboxControllerCompat.SandboxControllerImpl {
 
+    private val appOwnedSdkProvider = AppOwnedSdkProvider.create(controller)
+
     override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
         return controller
             .sandboxedSdks
             .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
     }
 
+    override fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+        appOwnedSdkProvider.getAppOwnedSdkSandboxInterfaces()
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        throw UnsupportedOperationException("This API only available for devices run on Android U+")
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        throw UnsupportedOperationException("This API only available for devices run on Android U+")
+    }
+
     companion object {
         fun from(context: Context): PlatformImpl {
             val sdkSandboxController = context.getSystemService(SdkSandboxController::class.java)
diff --git a/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
new file mode 100644
index 0000000..fcae673
--- /dev/null
+++ b/privacysandbox/sdkruntime/sdkruntime-core/src/main/java/androidx/privacysandbox/sdkruntime/core/controller/impl/PlatformUDCImpl.kt
@@ -0,0 +1,137 @@
+/*
+ * 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.privacysandbox.sdkruntime.core.controller.impl
+
+import android.app.Activity
+import android.app.Application
+import android.app.sdksandbox.sdkprovider.SdkSandboxActivityHandler
+import android.app.sdksandbox.sdkprovider.SdkSandboxController
+import android.content.Context
+import android.os.Bundle
+import android.os.IBinder
+import android.os.ext.SdkExtensions
+import androidx.activity.OnBackPressedDispatcher
+import androidx.annotation.RequiresApi
+import androidx.annotation.RequiresExtension
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleRegistry
+import androidx.privacysandbox.sdkruntime.core.activity.ActivityHolder
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+
+/**
+ * Implementation that delegates to platform [SdkSandboxController] for Android U.
+ */
+@RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 5)
+@RequiresApi(34)
+internal class PlatformUDCImpl(
+    private val controller: SdkSandboxController
+) : PlatformImpl(controller) {
+
+    private val compatToPlatformMap =
+        hashMapOf<SdkSandboxActivityHandlerCompat, SdkSandboxActivityHandler>()
+
+    override fun registerSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ): IBinder {
+        synchronized(compatToPlatformMap) {
+            val platformHandler: SdkSandboxActivityHandler =
+                compatToPlatformMap[handlerCompat]
+                ?: SdkSandboxActivityHandler { platformActivity: Activity ->
+                    handlerCompat.onActivityCreated(ActivityHolderImpl(platformActivity))
+                }
+            val token = controller.registerSdkSandboxActivityHandler(platformHandler)
+            compatToPlatformMap[handlerCompat] = platformHandler
+            return token
+        }
+    }
+
+    override fun unregisterSdkSandboxActivityHandler(
+        handlerCompat: SdkSandboxActivityHandlerCompat
+    ) {
+        synchronized(compatToPlatformMap) {
+            val platformHandler: SdkSandboxActivityHandler =
+                compatToPlatformMap[handlerCompat] ?: return
+            controller.unregisterSdkSandboxActivityHandler(platformHandler)
+            compatToPlatformMap.remove(handlerCompat)
+        }
+    }
+
+    internal class ActivityHolderImpl(
+        private val platformActivity: Activity
+    ) : ActivityHolder {
+        private val dispatcher = OnBackPressedDispatcher {}
+        private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
+
+        init {
+            // TODO(b/276315438) Set android:enableOnBackInvokedCallback="true" when
+            //  creating the manifest file
+            dispatcher.setOnBackInvokedDispatcher(platformActivity.onBackInvokedDispatcher)
+            proxyLifeCycleEvents()
+        }
+
+        override fun getActivity(): Activity {
+            return platformActivity
+        }
+
+        override fun getOnBackPressedDispatcher(): OnBackPressedDispatcher {
+            return dispatcher
+        }
+
+        override val lifecycle: Lifecycle
+            get() = lifecycleRegistry
+
+        private fun proxyLifeCycleEvents() {
+            val callback = object : Application.ActivityLifecycleCallbacks {
+                override fun onActivityCreated(p0: Activity, p1: Bundle?) {
+                    lifecycleRegistry.currentState = Lifecycle.State.CREATED
+                }
+
+                override fun onActivityStarted(p0: Activity) {
+                    lifecycleRegistry.currentState = Lifecycle.State.STARTED
+                }
+
+                override fun onActivityResumed(p0: Activity) {
+                    lifecycleRegistry.currentState = Lifecycle.State.RESUMED
+                }
+
+                override fun onActivityPaused(p0: Activity) {
+                    lifecycleRegistry.currentState = Lifecycle.State.STARTED
+                }
+
+                override fun onActivityStopped(p0: Activity) {
+                    lifecycleRegistry.currentState = Lifecycle.State.CREATED
+                }
+
+                override fun onActivityDestroyed(p0: Activity) {
+                    lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
+                }
+
+                override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {
+                    // No need for proxying
+                }
+            }
+            platformActivity.registerActivityLifecycleCallbacks(callback)
+        }
+    }
+
+    companion object {
+        fun from(context: Context): PlatformImpl {
+            val sdkSandboxController = context.getSystemService(SdkSandboxController::class.java)
+            return PlatformUDCImpl(sdkSandboxController)
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-apipackager/build.gradle b/privacysandbox/tools/tools-apipackager/build.gradle
index 006779b..19089d3 100644
--- a/privacysandbox/tools/tools-apipackager/build.gradle
+++ b/privacysandbox/tools/tools-apipackager/build.gradle
@@ -15,8 +15,6 @@
  */
 
 import androidx.build.LibraryType
-import androidx.build.SdkHelperKt
-import androidx.build.SupportConfig
 
 plugins {
     id("AndroidXPlugin")
@@ -37,13 +35,6 @@
     testImplementation(project(":room:room-compiler-processing-testing"))
     testImplementation(libs.junit)
     testImplementation(libs.truth)
-
-    // TODO(b/281638337): Remove below dependency once SdkActivityLauncher stubs are removed
-    // Include android jar for compilation of generated sources.
-    testImplementation(fileTree(
-            dir: "${SdkHelperKt.getSdkPath(project)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
-            include: "android.jar"
-    ))
 }
 
 androidx {
diff --git a/privacysandbox/tools/tools-apipackager/src/test/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackagerTest.kt b/privacysandbox/tools/tools-apipackager/src/test/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackagerTest.kt
index eb4b128..ba20a08 100644
--- a/privacysandbox/tools/tools-apipackager/src/test/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackagerTest.kt
+++ b/privacysandbox/tools/tools-apipackager/src/test/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackagerTest.kt
@@ -208,7 +208,7 @@
 
     /** Compiles the given source file and returns a classpath with the results. */
     private fun compileAndReturnUnzippedPackagedClasspath(source: Source): File {
-        val result = compileAll(listOf(source), includeLibraryStubs = false)
+        val result = compileAll(listOf(source))
         assertThat(result).succeeds()
         assertThat(result.outputClasspath).hasSize(1)
 
diff --git a/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/CompilationTestHelper.kt b/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/CompilationTestHelper.kt
index 84dd495..46db8fff 100644
--- a/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/CompilationTestHelper.kt
+++ b/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/CompilationTestHelper.kt
@@ -41,15 +41,12 @@
         extraClasspath: List<File> = emptyList(),
         symbolProcessorProviders: List<SymbolProcessorProvider> = emptyList(),
         processorOptions: Map<String, String> = emptyMap(),
-        includeLibraryStubs: Boolean = true,
     ): TestCompilationResult {
         val tempDir = Files.createTempDirectory("compile").toFile().also { it.deleteOnExit() }
-        // TODO(b/281638337): Remove library stubs once SdkActivityLauncher is upstreamed
-        val fullSources = sources + if (includeLibraryStubs) libraryStubs else emptyList()
         return compile(
             tempDir,
             TestCompilationArguments(
-                sources = fullSources,
+                sources = sources,
                 classpath = extraClasspath,
                 symbolProcessorProviders = symbolProcessorProviders,
                 processorOptions = processorOptions,
diff --git a/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/LibraryStubs.kt b/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/LibraryStubs.kt
deleted file mode 100644
index f0caa9e..0000000
--- a/privacysandbox/tools/tools-testing/src/main/java/androidx/privacysandbox/tools/testing/LibraryStubs.kt
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * 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.privacysandbox.tools.testing
-
-import androidx.room.compiler.processing.util.Source
-
-private val syntheticUiLibraryStubs = listOf(
-    Source.kotlin(
-        "androidx/privacysandbox/ui/core/SandboxedUiAdapter.kt", """
-        |package androidx.privacysandbox.ui.core
-        |
-        |import android.os.IBinder
-        |
-        |interface SdkActivityLauncher {
-        |    suspend fun launchSdkActivity(sdkActivityHandlerToken: IBinder): Boolean
-        |}
-        |""".trimMargin()
-    ),
-    Source.kotlin(
-        "androidx/privacysandbox/ui/client/SdkActivityLaunchers.kt", """
-        |@file:JvmName("SdkActivityLaunchers")
-        |
-        |package androidx.privacysandbox.ui.client
-        |
-        |import android.os.Bundle
-        |import androidx.privacysandbox.ui.core.SdkActivityLauncher
-        |
-        |fun SdkActivityLauncher.toLauncherInfo(): Bundle {
-        |    TODO("Stub!")
-        |}
-        |""".trimMargin()
-    ),
-    Source.kotlin(
-        "androidx/privacysandbox/ui/provider/SdkActivityLauncherFactory.kt", """
-        |package androidx.privacysandbox.ui.provider
-        |
-        |import android.os.Bundle
-        |import androidx.privacysandbox.ui.core.SdkActivityLauncher
-        |
-        |object SdkActivityLauncherFactory {
-        |
-        |    @JvmStatic
-        |    @Suppress("UNUSED_PARAMETER")
-        |    fun fromLauncherInfo(launcherInfo: Bundle): SdkActivityLauncher {
-        |        TODO("Stub!")
-        |    }
-        |}""".trimMargin()
-    ),
-    Source.kotlin(
-        "androidx/core/os/BundleCompat.kt", """
-        |package androidx.core.os
-        |
-        |import android.os.IBinder
-        |import android.os.Bundle
-        |
-        |object BundleCompat {
-        |    @Suppress("UNUSED_PARAMETER")
-        |    fun getBinder(bundle: Bundle, key: String?): IBinder? {
-        |        TODO("Stub!")
-        |    }
-        |}
-        |""".trimMargin()
-    ),
-)
-
-private val syntheticAidlGeneratedCode = listOf(
-    Source.java(
-        "androidx/privacysandbox/ui/core/ISdkActivityLauncher", """
-        |package androidx.privacysandbox.ui.core;
-        |/** @hide */
-        |public interface ISdkActivityLauncher extends android.os.IInterface
-        |{
-        |  /** Default implementation for ISdkActivityLauncher. */
-        |  public static class Default implements androidx.privacysandbox.ui.core.ISdkActivityLauncher
-        |  {
-        |    @Override public void launchSdkActivity(android.os.IBinder sdkActivityHandlerToken, androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback callback) throws android.os.RemoteException
-        |    {
-        |    }
-        |    @Override
-        |    public android.os.IBinder asBinder() {
-        |      return null;
-        |    }
-        |  }
-        |  /** Local-side IPC implementation stub class. */
-        |  public static abstract class Stub extends android.os.Binder implements androidx.privacysandbox.ui.core.ISdkActivityLauncher
-        |  {
-        |    /** Construct the stub at attach it to the interface. */
-        |    public Stub()
-        |    {
-        |      this.attachInterface(this, DESCRIPTOR);
-        |    }
-        |    /**
-        |     * Cast an IBinder object into an androidx.privacysandbox.ui.core.ISdkActivityLauncher interface,
-        |     * generating a proxy if needed.
-        |     */
-        |    public static androidx.privacysandbox.ui.core.ISdkActivityLauncher asInterface(android.os.IBinder obj)
-        |    {
-        |      if ((obj==null)) {
-        |        return null;
-        |      }
-        |      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-        |      if (((iin!=null)&&(iin instanceof androidx.privacysandbox.ui.core.ISdkActivityLauncher))) {
-        |        return ((androidx.privacysandbox.ui.core.ISdkActivityLauncher)iin);
-        |      }
-        |      return new androidx.privacysandbox.ui.core.ISdkActivityLauncher.Stub.Proxy(obj);
-        |    }
-        |    @Override public android.os.IBinder asBinder()
-        |    {
-        |      return this;
-        |    }
-        |    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
-        |    {
-        |      java.lang.String descriptor = DESCRIPTOR;
-        |      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
-        |        data.enforceInterface(descriptor);
-        |      }
-        |      switch (code)
-        |      {
-        |        case INTERFACE_TRANSACTION:
-        |        {
-        |          reply.writeString(descriptor);
-        |          return true;
-        |        }
-        |      }
-        |      switch (code)
-        |      {
-        |        case TRANSACTION_launchSdkActivity:
-        |        {
-        |          android.os.IBinder _arg0;
-        |          _arg0 = data.readStrongBinder();
-        |          androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback _arg1;
-        |          _arg1 = androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback.Stub.asInterface(data.readStrongBinder());
-        |          this.launchSdkActivity(_arg0, _arg1);
-        |          break;
-        |        }
-        |        default:
-        |        {
-        |          return super.onTransact(code, data, reply, flags);
-        |        }
-        |      }
-        |      return true;
-        |    }
-        |    private static class Proxy implements androidx.privacysandbox.ui.core.ISdkActivityLauncher
-        |    {
-        |      private android.os.IBinder mRemote;
-        |      Proxy(android.os.IBinder remote)
-        |      {
-        |        mRemote = remote;
-        |      }
-        |      @Override public android.os.IBinder asBinder()
-        |      {
-        |        return mRemote;
-        |      }
-        |      public java.lang.String getInterfaceDescriptor()
-        |      {
-        |        return DESCRIPTOR;
-        |      }
-        |      @Override public void launchSdkActivity(android.os.IBinder sdkActivityHandlerToken, androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback callback) throws android.os.RemoteException
-        |      {
-        |        android.os.Parcel _data = android.os.Parcel.obtain();
-        |        try {
-        |          _data.writeInterfaceToken(DESCRIPTOR);
-        |          _data.writeStrongBinder(sdkActivityHandlerToken);
-        |          _data.writeStrongInterface(callback);
-        |          boolean _status = mRemote.transact(Stub.TRANSACTION_launchSdkActivity, _data, null, android.os.IBinder.FLAG_ONEWAY);
-        |        }
-        |        finally {
-        |          _data.recycle();
-        |        }
-        |      }
-        |    }
-        |    static final int TRANSACTION_launchSdkActivity = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
-        |  }
-        |  public static final java.lang.String DESCRIPTOR = "androidx.privacysandbox.ui.core.ISdkActivityLauncher";
-        |  public void launchSdkActivity(android.os.IBinder sdkActivityHandlerToken, androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback callback) throws android.os.RemoteException;
-        |}""".trimMargin()
-    ),
-    Source.java(
-        "androidx/privacysandbox/ui/core/ISdkActivityLauncherCallback", """
-        |package androidx.privacysandbox.ui.core;
-        |/** @hide */
-        |public interface ISdkActivityLauncherCallback extends android.os.IInterface
-        |{
-        |  /** Default implementation for ISdkActivityLauncherCallback. */
-        |  public static class Default implements androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback
-        |  {
-        |    @Override public void onLaunchAccepted(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException
-        |    {
-        |    }
-        |    @Override public void onLaunchRejected(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException
-        |    {
-        |    }
-        |    @Override public void onLaunchError(java.lang.String message) throws android.os.RemoteException
-        |    {
-        |    }
-        |    @Override
-        |    public android.os.IBinder asBinder() {
-        |      return null;
-        |    }
-        |  }
-        |  /** Local-side IPC implementation stub class. */
-        |  public static abstract class Stub extends android.os.Binder implements androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback
-        |  {
-        |    /** Construct the stub at attach it to the interface. */
-        |    public Stub()
-        |    {
-        |      this.attachInterface(this, DESCRIPTOR);
-        |    }
-        |    /**
-        |     * Cast an IBinder object into an androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback interface,
-        |     * generating a proxy if needed.
-        |     */
-        |    public static androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback asInterface(android.os.IBinder obj)
-        |    {
-        |      if ((obj==null)) {
-        |        return null;
-        |      }
-        |      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-        |      if (((iin!=null)&&(iin instanceof androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback))) {
-        |        return ((androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback)iin);
-        |      }
-        |      return new androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback.Stub.Proxy(obj);
-        |    }
-        |    @Override public android.os.IBinder asBinder()
-        |    {
-        |      return this;
-        |    }
-        |    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
-        |    {
-        |      java.lang.String descriptor = DESCRIPTOR;
-        |      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
-        |        data.enforceInterface(descriptor);
-        |      }
-        |      switch (code)
-        |      {
-        |        case INTERFACE_TRANSACTION:
-        |        {
-        |          reply.writeString(descriptor);
-        |          return true;
-        |        }
-        |      }
-        |      switch (code)
-        |      {
-        |        case TRANSACTION_onLaunchAccepted:
-        |        {
-        |          android.os.IBinder _arg0;
-        |          _arg0 = data.readStrongBinder();
-        |          this.onLaunchAccepted(_arg0);
-        |          break;
-        |        }
-        |        case TRANSACTION_onLaunchRejected:
-        |        {
-        |          android.os.IBinder _arg0;
-        |          _arg0 = data.readStrongBinder();
-        |          this.onLaunchRejected(_arg0);
-        |          break;
-        |        }
-        |        case TRANSACTION_onLaunchError:
-        |        {
-        |          java.lang.String _arg0;
-        |          _arg0 = data.readString();
-        |          this.onLaunchError(_arg0);
-        |          break;
-        |        }
-        |        default:
-        |        {
-        |          return super.onTransact(code, data, reply, flags);
-        |        }
-        |      }
-        |      return true;
-        |    }
-        |    private static class Proxy implements androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback
-        |    {
-        |      private android.os.IBinder mRemote;
-        |      Proxy(android.os.IBinder remote)
-        |      {
-        |        mRemote = remote;
-        |      }
-        |      @Override public android.os.IBinder asBinder()
-        |      {
-        |        return mRemote;
-        |      }
-        |      public java.lang.String getInterfaceDescriptor()
-        |      {
-        |        return DESCRIPTOR;
-        |      }
-        |      @Override public void onLaunchAccepted(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException
-        |      {
-        |        android.os.Parcel _data = android.os.Parcel.obtain();
-        |        try {
-        |          _data.writeInterfaceToken(DESCRIPTOR);
-        |          _data.writeStrongBinder(sdkActivityHandlerToken);
-        |          boolean _status = mRemote.transact(Stub.TRANSACTION_onLaunchAccepted, _data, null, android.os.IBinder.FLAG_ONEWAY);
-        |        }
-        |        finally {
-        |          _data.recycle();
-        |        }
-        |      }
-        |      @Override public void onLaunchRejected(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException
-        |      {
-        |        android.os.Parcel _data = android.os.Parcel.obtain();
-        |        try {
-        |          _data.writeInterfaceToken(DESCRIPTOR);
-        |          _data.writeStrongBinder(sdkActivityHandlerToken);
-        |          boolean _status = mRemote.transact(Stub.TRANSACTION_onLaunchRejected, _data, null, android.os.IBinder.FLAG_ONEWAY);
-        |        }
-        |        finally {
-        |          _data.recycle();
-        |        }
-        |      }
-        |      @Override public void onLaunchError(java.lang.String message) throws android.os.RemoteException
-        |      {
-        |        android.os.Parcel _data = android.os.Parcel.obtain();
-        |        try {
-        |          _data.writeInterfaceToken(DESCRIPTOR);
-        |          _data.writeString(message);
-        |          boolean _status = mRemote.transact(Stub.TRANSACTION_onLaunchError, _data, null, android.os.IBinder.FLAG_ONEWAY);
-        |        }
-        |        finally {
-        |          _data.recycle();
-        |        }
-        |      }
-        |    }
-        |    static final int TRANSACTION_onLaunchAccepted = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
-        |    static final int TRANSACTION_onLaunchRejected = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
-        |    static final int TRANSACTION_onLaunchError = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
-        |  }
-        |  public static final java.lang.String DESCRIPTOR = "androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback";
-        |  public void onLaunchAccepted(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException;
-        |  public void onLaunchRejected(android.os.IBinder sdkActivityHandlerToken) throws android.os.RemoteException;
-        |  public void onLaunchError(java.lang.String message) throws android.os.RemoteException;
-        |}""".trimMargin()
-    ),
-)
-
-val libraryStubs = syntheticUiLibraryStubs + syntheticAidlGeneratedCode
\ No newline at end of file
diff --git a/privacysandbox/ui/integration-tests/testaidl/build.gradle b/privacysandbox/ui/integration-tests/testaidl/build.gradle
index 88ca40c..0375687 100644
--- a/privacysandbox/ui/integration-tests/testaidl/build.gradle
+++ b/privacysandbox/ui/integration-tests/testaidl/build.gradle
@@ -22,8 +22,6 @@
 
 android {
     namespace 'androidx.privacysandbox.ui.integration.testaidl'
-    compileSdk 33
-    compileSdkExtension = 5
 
     defaultConfig {
         minSdk 33
diff --git a/privacysandbox/ui/integration-tests/testapp/build.gradle b/privacysandbox/ui/integration-tests/testapp/build.gradle
index 518a00a..a3d4c86 100644
--- a/privacysandbox/ui/integration-tests/testapp/build.gradle
+++ b/privacysandbox/ui/integration-tests/testapp/build.gradle
@@ -22,8 +22,6 @@
 
 android {
     namespace 'androidx.privacysandbox.ui.integration.testapp'
-    compileSdk 33
-    compileSdkExtension = 5
 
     defaultConfig {
         applicationId "androidx.privacysandbox.ui.integration.testapp"
diff --git a/privacysandbox/ui/integration-tests/testsdkprovider/build.gradle b/privacysandbox/ui/integration-tests/testsdkprovider/build.gradle
index 53365be..7a18717 100644
--- a/privacysandbox/ui/integration-tests/testsdkprovider/build.gradle
+++ b/privacysandbox/ui/integration-tests/testsdkprovider/build.gradle
@@ -22,8 +22,6 @@
 
 android {
     namespace 'androidx.privacysandbox.ui.integration.testsdkprovider'
-    compileSdk 33
-    compileSdkExtension = 5
 
     defaultConfig {
         applicationId "androidx.privacysandbox.ui.integration.testsdkprovider"
diff --git a/privacysandbox/ui/integration-tests/testsdkprovider/src/main/java/androidx/privacysandbox/ui/integration/testsdkprovider/SdkApi.kt b/privacysandbox/ui/integration-tests/testsdkprovider/src/main/java/androidx/privacysandbox/ui/integration/testsdkprovider/SdkApi.kt
index 2045f7c..2287d4a 100644
--- a/privacysandbox/ui/integration-tests/testsdkprovider/src/main/java/androidx/privacysandbox/ui/integration/testsdkprovider/SdkApi.kt
+++ b/privacysandbox/ui/integration-tests/testsdkprovider/src/main/java/androidx/privacysandbox/ui/integration/testsdkprovider/SdkApi.kt
@@ -107,12 +107,12 @@
     }
 
     private inner class TestView(context: Context) : View(context) {
-        override fun onDraw(canvas: Canvas?) {
+        override fun onDraw(canvas: Canvas) {
             super.onDraw(canvas)
 
             val paint = Paint()
             paint.textSize = 50F
-            canvas!!.drawColor(
+            canvas.drawColor(
                 Color.rgb((0..255).random(), (0..255).random(), (0..255).random())
             )
             canvas.drawText("Hey", 75F, 75F, paint)
diff --git a/privacysandbox/ui/ui-client/api/current.txt b/privacysandbox/ui/ui-client/api/current.txt
index ae23335..bc9a40d 100644
--- a/privacysandbox/ui/ui-client/api/current.txt
+++ b/privacysandbox/ui/ui-client/api/current.txt
@@ -1,11 +1,20 @@
 // Signature format: 4.0
 package androidx.privacysandbox.ui.client {
 
+  public interface LocalSdkActivityLauncher<T extends android.app.Activity & androidx.lifecycle.LifecycleOwner> extends androidx.privacysandbox.ui.core.SdkActivityLauncher {
+    method public void dispose();
+  }
+
   @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class SandboxedUiAdapterFactory {
     method public androidx.privacysandbox.ui.core.SandboxedUiAdapter createFromCoreLibInfo(android.os.Bundle coreLibInfo);
     field public static final androidx.privacysandbox.ui.client.SandboxedUiAdapterFactory INSTANCE;
   }
 
+  public final class SdkActivityLaunchers {
+    method public static <T extends android.app.Activity & androidx.lifecycle.LifecycleOwner> androidx.privacysandbox.ui.client.LocalSdkActivityLauncher<T> createSdkActivityLauncher(T, kotlin.jvm.functions.Function0<java.lang.Boolean> allowLaunch);
+    method public static android.os.Bundle toLauncherInfo(androidx.privacysandbox.ui.core.SdkActivityLauncher);
+  }
+
 }
 
 package androidx.privacysandbox.ui.client.view {
diff --git a/privacysandbox/ui/ui-client/api/restricted_current.txt b/privacysandbox/ui/ui-client/api/restricted_current.txt
index ae23335..bc9a40d 100644
--- a/privacysandbox/ui/ui-client/api/restricted_current.txt
+++ b/privacysandbox/ui/ui-client/api/restricted_current.txt
@@ -1,11 +1,20 @@
 // Signature format: 4.0
 package androidx.privacysandbox.ui.client {
 
+  public interface LocalSdkActivityLauncher<T extends android.app.Activity & androidx.lifecycle.LifecycleOwner> extends androidx.privacysandbox.ui.core.SdkActivityLauncher {
+    method public void dispose();
+  }
+
   @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public final class SandboxedUiAdapterFactory {
     method public androidx.privacysandbox.ui.core.SandboxedUiAdapter createFromCoreLibInfo(android.os.Bundle coreLibInfo);
     field public static final androidx.privacysandbox.ui.client.SandboxedUiAdapterFactory INSTANCE;
   }
 
+  public final class SdkActivityLaunchers {
+    method public static <T extends android.app.Activity & androidx.lifecycle.LifecycleOwner> androidx.privacysandbox.ui.client.LocalSdkActivityLauncher<T> createSdkActivityLauncher(T, kotlin.jvm.functions.Function0<java.lang.Boolean> allowLaunch);
+    method public static android.os.Bundle toLauncherInfo(androidx.privacysandbox.ui.core.SdkActivityLauncher);
+  }
+
 }
 
 package androidx.privacysandbox.ui.client.view {
diff --git a/privacysandbox/ui/ui-client/build.gradle b/privacysandbox/ui/ui-client/build.gradle
index 747c1d1..1dc67e0 100644
--- a/privacysandbox/ui/ui-client/build.gradle
+++ b/privacysandbox/ui/ui-client/build.gradle
@@ -25,7 +25,12 @@
 dependencies {
     api(libs.kotlinStdlib)
     api("androidx.annotation:annotation:1.1.0")
+
+    implementation("androidx.core:core:1.7.0")
+    implementation("androidx.lifecycle:lifecycle-common:2.2.0")
+    implementation project(path: ':privacysandbox:sdkruntime:sdkruntime-client')
     implementation project(path: ':privacysandbox:ui:ui-core')
+
     androidTestImplementation(project(":internal-testutils-runtime"))
     androidTestImplementation(libs.junit)
     androidTestImplementation(libs.kotlinStdlib)
@@ -34,11 +39,18 @@
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.truth)
+    androidTestImplementation(libs.espressoIntents)
+    androidTestImplementation(libs.espressoCore)
+    androidTestImplementation(libs.mockitoCore)
+    androidTestImplementation(libs.multidex)
     androidTestImplementation project(path: ':appcompat:appcompat')
 }
 
 android {
     namespace "androidx.privacysandbox.ui.client"
+    defaultConfig {
+        multiDexEnabled true
+    }
 }
 
 androidx {
diff --git a/privacysandbox/ui/ui-client/src/androidTest/AndroidManifest.xml b/privacysandbox/ui/ui-client/src/androidTest/AndroidManifest.xml
index e114f95..b2720e1 100644
--- a/privacysandbox/ui/ui-client/src/androidTest/AndroidManifest.xml
+++ b/privacysandbox/ui/ui-client/src/androidTest/AndroidManifest.xml
@@ -16,6 +16,7 @@
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
     <application android:supportsRtl="true"
+        android:name="androidx.multidex.MultiDexApplication"
         android:theme="@style/Theme.AppCompat">
     <activity
         android:name="androidx.privacysandbox.ui.client.test.UiLibActivity"
diff --git a/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/CreateSdkActivityLauncherTest.kt b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/CreateSdkActivityLauncherTest.kt
new file mode 100644
index 0000000..3b50998
--- /dev/null
+++ b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/CreateSdkActivityLauncherTest.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.privacysandbox.ui.client.test
+
+import android.app.Activity
+import android.app.Instrumentation.ActivityResult
+import android.content.Intent
+import android.os.Binder
+import android.os.Build
+import androidx.lifecycle.Lifecycle
+import androidx.privacysandbox.ui.client.createSdkActivityLauncher
+import androidx.test.espresso.intent.Intents.intended
+import androidx.test.espresso.intent.Intents.intending
+import androidx.test.espresso.intent.Intents.times
+import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
+import androidx.test.espresso.intent.rule.IntentsRule
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
+import androidx.testutils.withActivity
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.hamcrest.Matchers.`is`
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+class CreateSdkActivityLauncherTest {
+    @get:Rule
+    var activityScenarioRule = ActivityScenarioRule(UiLibActivity::class.java)
+
+    @get:Rule
+    var intentsRule = IntentsRule()
+
+    private val sdkSandboxActivityMatcher =
+        hasAction(`is`("android.app.sdksandbox.action.START_SANDBOXED_ACTIVITY"))
+
+    @Before
+    fun setUp() {
+        // Intercepts intent to start sandboxed activity and immediately return a result.
+        // This allows us to avoid loading and setting up an SDK just for checking if activities are
+        // launched.
+        intending(sdkSandboxActivityMatcher)
+            .respondWith(ActivityResult(Activity.RESULT_OK, Intent()))
+    }
+
+    @Test
+    fun returnedLauncher_launchesActivitiesWhenAllowed() = runBlocking {
+        val launcher = activityScenarioRule.withActivity { this.createSdkActivityLauncher { true } }
+
+        val result = launcher.launchSdkActivity(Binder())
+
+        assertThat(result).isTrue()
+        intended(sdkSandboxActivityMatcher, times(1))
+    }
+
+    @Test
+    fun returnedLauncher_rejectsActivityLaunchesAccordingToPredicate() = runBlocking {
+        val launcher =
+            activityScenarioRule.withActivity { this.createSdkActivityLauncher { false } }
+
+        val result = launcher.launchSdkActivity(Binder())
+
+        assertThat(result).isFalse()
+        intended(sdkSandboxActivityMatcher, times(0))
+    }
+
+    @Test
+    fun returnedLauncher_rejectsActivityLaunchesWhenDisposed() = runBlocking {
+        val launcher = activityScenarioRule.withActivity { this.createSdkActivityLauncher { true } }
+        launcher.dispose()
+
+        val result = launcher.launchSdkActivity(Binder())
+
+        assertThat(result).isFalse()
+        intended(sdkSandboxActivityMatcher, times(0))
+    }
+
+    @Test
+    fun returnedLauncher_disposeCanBeCalledMultipleTimes() = runBlocking {
+        val launcher = activityScenarioRule.withActivity { this.createSdkActivityLauncher { true } }
+        launcher.dispose()
+
+        val result = launcher.launchSdkActivity(Binder())
+        launcher.dispose()
+        launcher.dispose()
+
+        assertThat(result).isFalse()
+        intended(sdkSandboxActivityMatcher, times(0))
+    }
+
+    @Test
+    fun returnedLauncher_rejectsActivityLaunchesWhenHostActivityIsDestroyed() = runBlocking {
+        val launcher = activityScenarioRule.withActivity { this.createSdkActivityLauncher { true } }
+        activityScenarioRule.scenario.moveToState(Lifecycle.State.DESTROYED)
+
+        val result = launcher.launchSdkActivity(Binder())
+
+        assertThat(result).isFalse()
+        intended(sdkSandboxActivityMatcher, times(0))
+    }
+
+    @Test
+    fun returnedLauncher_rejectsActivityLaunchesWhenHostActivityWasAlreadyDestroyed() =
+        runBlocking {
+            val activity = activityScenarioRule.withActivity { this }
+            activityScenarioRule.scenario.moveToState(Lifecycle.State.DESTROYED)
+            val launcher = activity.createSdkActivityLauncher { true }
+
+            val result = launcher.launchSdkActivity(Binder())
+
+            assertThat(result).isFalse()
+            intended(sdkSandboxActivityMatcher, times(0))
+        }
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/SdkActivityLaunchers.kt b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/SdkActivityLaunchers.kt
new file mode 100644
index 0000000..ef932dd
--- /dev/null
+++ b/privacysandbox/ui/ui-client/src/main/java/androidx/privacysandbox/ui/client/SdkActivityLaunchers.kt
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+@file:JvmName("SdkActivityLaunchers")
+
+// TODO(b/282918396): Stop using app.BundleCompat and change it to os.BundleCompat when permission
+// issue is fixed.
+@file:Suppress("DEPRECATION")
+
+package androidx.privacysandbox.ui.client
+
+import android.app.Activity
+import android.os.Bundle
+import android.os.IBinder
+import androidx.core.app.BundleCompat
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.privacysandbox.sdkruntime.client.SdkSandboxManagerCompat
+import androidx.privacysandbox.ui.core.ISdkActivityLauncher
+import androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback
+import androidx.privacysandbox.ui.core.ProtocolConstants.sdkActivityLauncherBinderKey
+import androidx.privacysandbox.ui.core.SdkActivityLauncher
+import java.util.concurrent.atomic.AtomicReference
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Returns an SdkActivityLauncher that launches activities on behalf of an SDK by using this
+ * activity as a starting context.
+ *
+ * @param T the current activity from which new SDK activities will be launched. If this activity is
+ * destroyed any further SDK activity launches will simply be ignored.
+ * @param allowLaunch predicate called each time an activity is about to be launched by the
+ * SDK, the activity will only be launched if it returns true.
+ */
+fun <T> T.createSdkActivityLauncher(
+    allowLaunch: () -> Boolean
+): LocalSdkActivityLauncher<T>
+    where T : Activity, T : LifecycleOwner {
+    val cancellationJob = Job(parent = lifecycleScope.coroutineContext[Job])
+    val launcher = LocalSdkActivityLauncherImpl(
+        activity = this,
+        allowLaunch = allowLaunch,
+        onDispose = { cancellationJob.cancel() },
+    )
+    cancellationJob.invokeOnCompletion {
+        launcher.dispose()
+    }
+    return launcher
+}
+
+/**
+ * Returns a [Bundle] with the information necessary to recreate this launcher.
+ * Possibly in a different process.
+ */
+fun SdkActivityLauncher.toLauncherInfo(): Bundle {
+    val binderDelegate = SdkActivityLauncherBinderDelegate(this)
+    return Bundle().also { bundle ->
+        BundleCompat.putBinder(bundle, sdkActivityLauncherBinderKey, binderDelegate)
+    }
+}
+
+/**
+ * Local implementation of an SDK Activity launcher.
+ *
+ * It allows callers in the app process to dispose resources used to launch SDK activities.
+ */
+interface LocalSdkActivityLauncher<T> : SdkActivityLauncher where T : Activity, T : LifecycleOwner {
+    /**
+     * Clears references used to launch activities.
+     *
+     * After this method is called all further attempts to launch activities wil be rejected.
+     * Doesn't do anything if the launcher was already disposed of.
+     */
+    fun dispose()
+}
+
+private class LocalSdkActivityLauncherImpl<T>(
+    activity: T,
+    allowLaunch: () -> Boolean,
+    onDispose: () -> Unit
+) : LocalSdkActivityLauncher<T> where T : Activity, T : LifecycleOwner {
+
+    /** Internal state for [LocalSdkActivityLauncher], cleared when the launcher is disposed. */
+    private class LocalLauncherState<T>(
+        val activity: T,
+        val allowLaunch: () -> Boolean,
+        val sdkSandboxManager: SdkSandboxManagerCompat,
+        val onDispose: () -> Unit
+    ) where T : Activity, T : LifecycleOwner
+
+    private val stateReference: AtomicReference<LocalLauncherState<T>?> =
+        AtomicReference<LocalLauncherState<T>?>(
+        LocalLauncherState(
+            activity,
+            allowLaunch,
+            SdkSandboxManagerCompat.from(activity),
+            onDispose
+        )
+    )
+
+    override suspend fun launchSdkActivity(
+        sdkActivityHandlerToken: IBinder
+    ): Boolean {
+        val state = stateReference.get() ?: return false
+        return withContext(Dispatchers.Main.immediate) {
+            state.run {
+                allowLaunch().also { didAllowLaunch ->
+                    if (didAllowLaunch) {
+                        sdkSandboxManager.startSdkSandboxActivity(activity, sdkActivityHandlerToken)
+                    }
+                }
+            }
+        }
+    }
+
+    override fun dispose() {
+        stateReference.getAndSet(null)?.run {
+            onDispose()
+        }
+    }
+}
+
+private class SdkActivityLauncherBinderDelegate(private val launcher: SdkActivityLauncher) :
+    ISdkActivityLauncher.Stub() {
+
+    private val coroutineScope = CoroutineScope(Dispatchers.Main)
+
+    override fun launchSdkActivity(
+        sdkActivityHandlerToken: IBinder?,
+        callback: ISdkActivityLauncherCallback?
+    ) {
+        requireNotNull(sdkActivityHandlerToken)
+        requireNotNull(callback)
+
+        coroutineScope.launch {
+            val accepted = try {
+                launcher.launchSdkActivity(sdkActivityHandlerToken)
+            } catch (t: Throwable) {
+                callback.onLaunchError(t.message ?: "Unknown error launching SDK activity.")
+                return@launch
+            }
+
+            if (accepted) {
+                callback.onLaunchAccepted(sdkActivityHandlerToken)
+            } else {
+                callback.onLaunchRejected(sdkActivityHandlerToken)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-core/api/current.txt b/privacysandbox/ui/ui-core/api/current.txt
index 4154b4b..db32e1e 100644
--- a/privacysandbox/ui/ui-core/api/current.txt
+++ b/privacysandbox/ui/ui-core/api/current.txt
@@ -20,6 +20,10 @@
     method public void onSessionOpened(androidx.privacysandbox.ui.core.SandboxedUiAdapter.Session session);
   }
 
+  public interface SdkActivityLauncher {
+    method public suspend Object? launchSdkActivity(android.os.IBinder sdkActivityHandlerToken, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
   public final class SdkRuntimeUiLibVersions {
     method public int getClientVersion();
     property public final int clientVersion;
diff --git a/privacysandbox/ui/ui-core/api/restricted_current.txt b/privacysandbox/ui/ui-core/api/restricted_current.txt
index 4154b4b..db32e1e 100644
--- a/privacysandbox/ui/ui-core/api/restricted_current.txt
+++ b/privacysandbox/ui/ui-core/api/restricted_current.txt
@@ -20,6 +20,10 @@
     method public void onSessionOpened(androidx.privacysandbox.ui.core.SandboxedUiAdapter.Session session);
   }
 
+  public interface SdkActivityLauncher {
+    method public suspend Object? launchSdkActivity(android.os.IBinder sdkActivityHandlerToken, kotlin.coroutines.Continuation<? super java.lang.Boolean>);
+  }
+
   public final class SdkRuntimeUiLibVersions {
     method public int getClientVersion();
     property public final int clientVersion;
diff --git a/privacysandbox/ui/ui-core/lint-baseline.xml b/privacysandbox/ui/ui-core/lint-baseline.xml
index c6aa1c9..23022fb 100644
--- a/privacysandbox/ui/ui-core/lint-baseline.xml
+++ b/privacysandbox/ui/ui-core/lint-baseline.xml
@@ -37,4 +37,22 @@
             file="src/main/aidl/androidx/privacysandbox/ui/core/ISandboxedUiAdapter.aidl"/>
     </issue>
 
+    <issue
+        id="RequireUnstableAidlAnnotation"
+        message="Unstable AIDL files must be annotated with `@RequiresOptIn` marker"
+        errorLine1="oneway interface ISdkActivityLauncher {"
+        errorLine2="^">
+        <location
+            file="src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncher.aidl"/>
+    </issue>
+
+    <issue
+        id="RequireUnstableAidlAnnotation"
+        message="Unstable AIDL files must be annotated with `@RequiresOptIn` marker"
+        errorLine1="oneway interface ISdkActivityLauncherCallback {"
+        errorLine2="^">
+        <location
+            file="src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncherCallback.aidl"/>
+    </issue>
+
 </issues>
diff --git a/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncher.aidl b/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncher.aidl
new file mode 100644
index 0000000..76cfa3c
--- /dev/null
+++ b/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncher.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.privacysandbox.ui.core;
+
+import androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback;
+
+/* @hide */
+oneway interface ISdkActivityLauncher {
+  void launchSdkActivity(
+        in IBinder sdkActivityHandlerToken,
+        ISdkActivityLauncherCallback callback) = 1;
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncherCallback.aidl b/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncherCallback.aidl
new file mode 100644
index 0000000..22b7beb
--- /dev/null
+++ b/privacysandbox/ui/ui-core/src/main/aidl/androidx/privacysandbox/ui/core/ISdkActivityLauncherCallback.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.privacysandbox.ui.core;
+
+/* @hide */
+oneway interface ISdkActivityLauncherCallback {
+  void onLaunchAccepted(in IBinder sdkActivityHandlerToken) = 1;
+  void onLaunchRejected(in IBinder sdkActivityHandlerToken) = 2;
+  void onLaunchError(String message) = 3;
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/ProtocolConstants.kt b/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/ProtocolConstants.kt
new file mode 100644
index 0000000..5bff1c9
--- /dev/null
+++ b/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/ProtocolConstants.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.privacysandbox.ui.core
+
+import androidx.annotation.RestrictTo
+
+/**
+ * Constants shared between UI library artifacts to establish an IPC protocol across library
+ * versions. Adding new constants is allowed, but **never change the value of a constant**, or
+ * you'll break binary compatibility between UI library versions.
+ *
+ * @suppress
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+object ProtocolConstants {
+    const val sdkActivityLauncherBinderKey = "sdkActivityLauncherBinderKey"
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/SdkActivityLauncher.kt b/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/SdkActivityLauncher.kt
new file mode 100644
index 0000000..edd3008
--- /dev/null
+++ b/privacysandbox/ui/ui-core/src/main/java/androidx/privacysandbox/ui/core/SdkActivityLauncher.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.privacysandbox.ui.core
+
+import android.os.IBinder
+
+/**
+ * Interface that allows SDKs running in the Privacy Sandbox to launch activities.
+ *
+ * Apps can create launchers by calling
+ * [createActivityLauncher][androidx.privacysandbox.ui.client.createSdkActivityLauncher]
+ * from one of their activities.
+ *
+ * To send an [SdkActivityLauncher] to another process, they can call
+ * [toLauncherInfo][androidx.privacysandbox.ui.client.toLauncherInfo]
+ * and send the resulting bundle.
+ *
+ * SDKs can create launchers from an app-provided bundle by calling
+ * [createFromLauncherInfo][androidx.privacysandbox.ui.provider.SdkActivityLauncherFactory.createFromLauncherInfo].
+ */
+interface SdkActivityLauncher {
+
+    /**
+     * Tries to launch a new SDK activity using the given [sdkActivityHandlerToken],
+     * assumed to be registered in the [SdkSandboxControllerCompat][androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat].
+     *
+     * Returns true if the SDK activity intent was sent, false if the launch was rejected for any
+     * reason.
+     */
+    suspend fun launchSdkActivity(sdkActivityHandlerToken: IBinder): Boolean
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-provider/api/current.txt b/privacysandbox/ui/ui-provider/api/current.txt
index 20170b4..03fbefd 100644
--- a/privacysandbox/ui/ui-provider/api/current.txt
+++ b/privacysandbox/ui/ui-provider/api/current.txt
@@ -5,5 +5,10 @@
     method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static android.os.Bundle toCoreLibInfo(androidx.privacysandbox.ui.core.SandboxedUiAdapter, android.content.Context context);
   }
 
+  public final class SdkActivityLauncherFactory {
+    method public static androidx.privacysandbox.ui.core.SdkActivityLauncher fromLauncherInfo(android.os.Bundle launcherInfo);
+    field public static final androidx.privacysandbox.ui.provider.SdkActivityLauncherFactory INSTANCE;
+  }
+
 }
 
diff --git a/privacysandbox/ui/ui-provider/api/restricted_current.txt b/privacysandbox/ui/ui-provider/api/restricted_current.txt
index 20170b4..03fbefd 100644
--- a/privacysandbox/ui/ui-provider/api/restricted_current.txt
+++ b/privacysandbox/ui/ui-provider/api/restricted_current.txt
@@ -5,5 +5,10 @@
     method @RequiresApi(android.os.Build.VERSION_CODES.TIRAMISU) public static android.os.Bundle toCoreLibInfo(androidx.privacysandbox.ui.core.SandboxedUiAdapter, android.content.Context context);
   }
 
+  public final class SdkActivityLauncherFactory {
+    method public static androidx.privacysandbox.ui.core.SdkActivityLauncher fromLauncherInfo(android.os.Bundle launcherInfo);
+    field public static final androidx.privacysandbox.ui.provider.SdkActivityLauncherFactory INSTANCE;
+  }
+
 }
 
diff --git a/privacysandbox/ui/ui-provider/build.gradle b/privacysandbox/ui/ui-provider/build.gradle
index a89f128..3ff3156 100644
--- a/privacysandbox/ui/ui-provider/build.gradle
+++ b/privacysandbox/ui/ui-provider/build.gradle
@@ -25,7 +25,11 @@
 dependencies {
     api(libs.kotlinStdlib)
     api("androidx.annotation:annotation:1.1.0")
+
     implementation project(path: ':privacysandbox:ui:ui-core')
+    implementation("androidx.core:core:1.7.0")
+    implementation(libs.kotlinCoroutinesCore)
+
     androidTestImplementation(libs.junit)
     androidTestImplementation(libs.kotlinStdlib)
     androidTestImplementation(libs.testExtJunit)
diff --git a/privacysandbox/ui/ui-provider/src/main/java/androidx/privacysandbox/ui/provider/SdkActivityLauncherFactory.kt b/privacysandbox/ui/ui-provider/src/main/java/androidx/privacysandbox/ui/provider/SdkActivityLauncherFactory.kt
new file mode 100644
index 0000000..622a46f
--- /dev/null
+++ b/privacysandbox/ui/ui-provider/src/main/java/androidx/privacysandbox/ui/provider/SdkActivityLauncherFactory.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+// TODO(b/282918396): Stop using app.BundleCompat and change it to os.BundleCompat when permission
+// issue is fixed.
+@file:Suppress("DEPRECATION")
+
+package androidx.privacysandbox.ui.provider
+
+import android.os.Bundle
+import android.os.IBinder
+import androidx.core.app.BundleCompat
+import androidx.privacysandbox.ui.core.ISdkActivityLauncher
+import androidx.privacysandbox.ui.core.ISdkActivityLauncherCallback
+import androidx.privacysandbox.ui.core.ProtocolConstants.sdkActivityLauncherBinderKey
+import androidx.privacysandbox.ui.core.SdkActivityLauncher
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+object SdkActivityLauncherFactory {
+
+    /**
+     * Creates a [SdkActivityLauncher] using the given [launcherInfo] Bundle.
+     *
+     * You can create such a Bundle by calling [toLauncherInfo][androidx.privacysandbox.ui.client.toLauncherInfo].
+     * A [launcherInfo] is expected to have a valid SdkActivityLauncher Binder with
+     * `"sdkActivityLauncherBinderKey"` for a key, [IllegalArgumentException] is thrown otherwise.
+     */
+    @JvmStatic
+    fun fromLauncherInfo(launcherInfo: Bundle): SdkActivityLauncher {
+        val remote: ISdkActivityLauncher? = ISdkActivityLauncher.Stub.asInterface(
+            BundleCompat.getBinder(launcherInfo, sdkActivityLauncherBinderKey)
+        )
+        requireNotNull(remote) { "Invalid SdkActivityLauncher info bundle." }
+        return SdkActivityLauncherProxy(remote)
+    }
+
+    private class SdkActivityLauncherProxy(
+        private val remote: ISdkActivityLauncher
+    ) : SdkActivityLauncher {
+        override suspend fun launchSdkActivity(sdkActivityHandlerToken: IBinder): Boolean =
+            suspendCancellableCoroutine {
+                remote.launchSdkActivity(
+                    sdkActivityHandlerToken,
+                    object : ISdkActivityLauncherCallback.Stub() {
+                        override fun onLaunchAccepted(sdkActivityHandlerToken: IBinder?) {
+                            it.resume(true)
+                        }
+
+                        override fun onLaunchRejected(sdkActivityHandlerToken: IBinder?) {
+                            it.resume(false)
+                        }
+
+                        override fun onLaunchError(message: String?) {
+                            it.resumeWithException(RuntimeException(message))
+                        }
+                    })
+            }
+    }
+}
\ No newline at end of file
diff --git a/privacysandbox/ui/ui-tests/build.gradle b/privacysandbox/ui/ui-tests/build.gradle
index a675a27..cf66642 100644
--- a/privacysandbox/ui/ui-tests/build.gradle
+++ b/privacysandbox/ui/ui-tests/build.gradle
@@ -26,12 +26,14 @@
     implementation project(path: ':privacysandbox:ui:ui-core')
     implementation project(path: ':privacysandbox:ui:ui-client')
     implementation project(path: ':privacysandbox:ui:ui-provider')
+    implementation(libs.kotlinStdlib)
+
     androidTestImplementation(project(":internal-testutils-runtime"))
-    api(libs.kotlinStdlib)
     androidTestImplementation(libs.junit)
     androidTestImplementation(libs.kotlinStdlib)
     androidTestImplementation(libs.testExtJunit)
     androidTestImplementation(libs.testCore)
+    androidTestImplementation(libs.kotlinCoroutinesCore)
     androidTestImplementation(libs.testRunner)
     androidTestImplementation(libs.testRules)
     androidTestImplementation(libs.truth)
diff --git a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/activity/SdkActivityLauncherBundlingTest.kt b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/activity/SdkActivityLauncherBundlingTest.kt
new file mode 100644
index 0000000..6971f7c
--- /dev/null
+++ b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/activity/SdkActivityLauncherBundlingTest.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.privacysandbox.ui.tests.activity
+
+import android.os.Binder
+import android.os.IBinder
+import androidx.privacysandbox.ui.client.toLauncherInfo
+import androidx.privacysandbox.ui.core.SdkActivityLauncher
+import androidx.privacysandbox.ui.provider.SdkActivityLauncherFactory
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SdkActivityLauncherBundlingTest {
+
+    @Test
+    fun unbundledSdkActivityLauncher_launchesActivities(): Unit = runBlocking {
+        val launcher = TestSdkActivityLauncher()
+        val launcherInfo = launcher.toLauncherInfo()
+
+        val unbundledLauncher = SdkActivityLauncherFactory.fromLauncherInfo(launcherInfo)
+        val token = Binder()
+        val result = unbundledLauncher.launchSdkActivity(token)
+
+        assertThat(result).isTrue()
+        assertThat(launcher.tokensReceived).containsExactly(token)
+    }
+
+    @Test
+    fun unbundledSdkActivityLauncher_rejectsActivityLaunches(): Unit = runBlocking {
+        val launcher = TestSdkActivityLauncher()
+        launcher.allowActivityLaunches = false
+        val launcherInfo = launcher.toLauncherInfo()
+
+        val unbundledLauncher = SdkActivityLauncherFactory.fromLauncherInfo(launcherInfo)
+        val token = Binder()
+        val result = unbundledLauncher.launchSdkActivity(token)
+
+        assertThat(result).isFalse()
+        assertThat(launcher.tokensReceived).containsExactly(token)
+    }
+
+    class TestSdkActivityLauncher : SdkActivityLauncher {
+        var allowActivityLaunches: Boolean = true
+
+        var tokensReceived = mutableListOf<IBinder>()
+
+        override suspend fun launchSdkActivity(sdkActivityHandlerToken: IBinder):
+            Boolean {
+            tokensReceived.add(sdkActivityHandlerToken)
+            return allowActivityLaunches
+        }
+    }
+}
\ No newline at end of file
diff --git a/recyclerview/recyclerview/api/api_lint.ignore b/recyclerview/recyclerview/api/api_lint.ignore
index ee7fa16..463599f 100644
--- a/recyclerview/recyclerview/api/api_lint.ignore
+++ b/recyclerview/recyclerview/api/api_lint.ignore
@@ -161,12 +161,6 @@
     Internal field mLayoutManager must not be exposed
 
 
-InvalidNullabilityOverride: androidx.recyclerview.widget.RecyclerView#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.recyclerview.widget.RecyclerView#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
-    Invalid nullability on parameter `canvas` in method `drawChild`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.recyclerview.widget.RecyclerView#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #0:
     Invalid nullability on parameter `host` in method `dispatchPopulateAccessibilityEvent`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate.ItemDelegate#dispatchPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent) parameter #1:
@@ -551,6 +545,10 @@
     Missing nullability on parameter `container` in method `dispatchRestoreInstanceState`
 MissingNullability: androidx.recyclerview.widget.RecyclerView#dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>) parameter #0:
     Missing nullability on parameter `container` in method `dispatchSaveInstanceState`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
+MissingNullability: androidx.recyclerview.widget.RecyclerView#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
 MissingNullability: androidx.recyclerview.widget.RecyclerView#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
     Missing nullability on parameter `child` in method `drawChild`
 MissingNullability: androidx.recyclerview.widget.RecyclerView#findViewHolderForItemId(long):
@@ -573,6 +571,8 @@
     Missing nullability on method `getAccessibilityClassName` return
 MissingNullability: androidx.recyclerview.widget.RecyclerView#getChildViewHolder(android.view.View):
     Missing nullability on method `getChildViewHolder` return
+MissingNullability: androidx.recyclerview.widget.RecyclerView#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `onDraw`
 MissingNullability: androidx.recyclerview.widget.RecyclerView#onGenericMotionEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `event` in method `onGenericMotionEvent`
 MissingNullability: androidx.recyclerview.widget.RecyclerView#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
diff --git a/recyclerview/recyclerview/build.gradle b/recyclerview/recyclerview/build.gradle
index 8c7e013..2f52af1 100644
--- a/recyclerview/recyclerview/build.gradle
+++ b/recyclerview/recyclerview/build.gradle
@@ -8,7 +8,7 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.1.0")
-    api "androidx.core:core:1.7.0"
+    api(project(":core:core"))
     implementation("androidx.collection:collection:1.0.0")
     api("androidx.customview:customview:1.0.0")
     implementation("androidx.customview:customview-poolingcontainer:1.0.0")
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/GridLayoutManagerTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/GridLayoutManagerTest.java
index a1b18f0..efca5df 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/GridLayoutManagerTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/GridLayoutManagerTest.java
@@ -19,9 +19,14 @@
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_ACCESSIBILITY_FOCUS;
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION;
+import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION;
 import static androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL;
 import static androidx.recyclerview.widget.LinearLayoutManager.VERTICAL;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -30,20 +35,25 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.UiAutomation;
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.StateListDrawable;
 import android.os.Build;
 import android.os.Bundle;
+import android.util.Pair;
 import android.util.SparseIntArray;
 import android.util.StateSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.GridView;
 import android.widget.TextView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
 import androidx.core.view.AccessibilityDelegateCompat;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.test.annotation.UiThreadTest;
@@ -51,8 +61,6 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.SdkSuppress;
 
-import com.google.common.truth.Truth;
-
 import org.hamcrest.CoreMatchers;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -61,6 +69,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 @LargeTest
@@ -68,6 +77,9 @@
 public class GridLayoutManagerTest extends BaseGridLayoutManagerTest {
 
     private static final int[] SPAN_SIZES = new int[]{1, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 2};
+
+    private static final int DEFAULT_ACCESSIBILITY_EVENT_TIMEOUT_MILLIS = 5000;
+
     private final GridLayoutManager.SpanSizeLookup mSpanSizeLookupForSpanIndexTest =
             new GridLayoutManager.SpanSizeLookup() {
         @Override
@@ -964,8 +976,7 @@
         waitForFirstLayout(recyclerView);
 
         final AccessibilityNodeInfoCompat nodeInfo = AccessibilityNodeInfoCompat.obtain();
-        assertFalse(nodeInfo.getActionList().contains(
-                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION));
+        assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_TO_POSITION));
         mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -973,8 +984,7 @@
             }
         });
 
-        assertFalse(nodeInfo.getActionList().contains(
-                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION));
+        assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_TO_POSITION));
     }
 
     @Test
@@ -985,8 +995,7 @@
         waitForFirstLayout(recyclerView);
 
         final AccessibilityNodeInfoCompat nodeInfo = AccessibilityNodeInfoCompat.obtain();
-        assertFalse(nodeInfo.getActionList().contains(
-                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION));
+        assertFalse(nodeInfo.getActionList().contains(ACTION_SCROLL_TO_POSITION));
         mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
@@ -994,8 +1003,7 @@
             }
         });
 
-        assertTrue(nodeInfo.getActionList().contains(
-                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_TO_POSITION));
+        assertTrue(nodeInfo.getActionList().contains(ACTION_SCROLL_TO_POSITION));
     }
 
     @Test
@@ -1102,6 +1110,935 @@
         assertEquals(((TextView) mGlm.getChildAt(0)).getText(), "Item (6)");
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    public void onInitializeAccessibilityNodeInfo_addActionScrollInDirection_notAddedWithEmptyList()
+            throws Throwable {
+        mRecyclerView = setupBasic(new Config(2, 0));
+        final AccessibilityNodeInfoCompat nodeInfo = AccessibilityNodeInfoCompat.obtain();
+
+        assertThat(nodeInfo.getActionList()).doesNotContain(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+
+        mActivityRule.runOnUiThread(
+                () -> mRecyclerView.getLayoutManager().onInitializeAccessibilityNodeInfo(nodeInfo));
+
+        assertThat(nodeInfo.getActionList()).doesNotContain(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    public void onInitializeAccessibilityNodeInfo_addActionScrollInDirection_withOneItemList()
+            throws Throwable {
+        mRecyclerView = setupBasic(new Config(2, 1));
+        final AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain();
+
+        assertThat(node.getActionList()).doesNotContain(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+
+        mActivityRule.runOnUiThread(
+                () -> mRecyclerView.getLayoutManager().onInitializeAccessibilityNodeInfo(node));
+
+        assertThat(node.getActionList()).doesNotContain(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @Test
+    public void onInitializeAccessibilityNodeInfo_addActionScrollInDirection_withMoreThanOneItem()
+            throws Throwable {
+
+        mRecyclerView = setupBasic(new Config(2, 2));
+        final AccessibilityNodeInfoCompat node = AccessibilityNodeInfoCompat.obtain();
+
+        assertThat(node.getActionList()).doesNotContain(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+
+        mActivityRule.runOnUiThread(
+                () -> mRecyclerView.getLayoutManager().onInitializeAccessibilityNodeInfo(node));
+
+        assertThat(node.getActionList()).contains(
+                AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_withoutSpecifyingDirection()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(6, HORIZONTAL);
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        final boolean[] returnValue = {false};
+        mActivityRule.runOnUiThread(
+                () -> {
+                    returnValue[0] = mRecyclerView.getLayoutManager().performAccessibilityAction(
+                            ACTION_SCROLL_IN_DIRECTION.getId(), null);
+                });
+        assertThat(returnValue[0]).isFalse();
+        assertThat(mGlm.mRowWithAccessibilityFocus).isEqualTo(-1);
+        assertThat(mGlm.mColumnWithAccessibilityFocus).isEqualTo(-1);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_withInvalidDirection()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(6, HORIZONTAL);
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndFail(-1, Pair.create(-1, -1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_withoutSettingAccessibilityFocus()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        // Return value of this call is not used.
+        setUpGridLayoutManagerAccessibilityTest(6, HORIZONTAL);
+        runScrollInDirectionAndFail(View.FOCUS_RIGHT, Pair.create(-1, -1));
+
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_vertical_scrollTargetOnTheSameRow()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (3)",
+                Pair.create(0, 2));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_vertical_scrollTargetOnTheNextRow()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   5
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (4)",
+                Pair.create(1, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_vertical_traversingThroughASpan()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        mRecyclerView = setupBasic(new Config(4, 4));
+        mGlm.setOrientation(VERTICAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 1) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   2   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (2)" ,
+                Pair.create(0, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (3)" ,
+                Pair.create(0, 3));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_vertical_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   5
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(4));
+        runScrollInDirectionAndFail(View.FOCUS_RIGHT, Pair.create(1, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_horizontal_scrollTargetOnTheSameRow()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (4)" ,
+                Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_horizontal_traversingThroughASpan()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(8, HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 4) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   4   6
+        2   5   7
+        3   5   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (5)" ,
+                Pair.create(2, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(4));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (8)" ,
+                Pair.create(2, 2));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_horizontal_withWrapAround()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(8, HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 0) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   3   6
+        1   4   7
+        2   5   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(5));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (1)" ,
+                Pair.create(1, 0));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_RIGHT, "Item (4)" ,
+                Pair.create(1, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusRight_horizontal_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndFail(View.FOCUS_RIGHT);
+        assertThat(mGlm.mRowWithAccessibilityFocus).isEqualTo(2);
+        assertThat(mGlm.mColumnWithAccessibilityFocus).isEqualTo(0);
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_vertical_scrollTargetOnTheSameRow()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (1)",
+                Pair.create(0, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_vertical_scrollTargetOnAPreviousRow()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   5
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (3)",
+                Pair.create(0, 2));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_vertical_traversingThroughASpan()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(4, VERTICAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 1) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   2   2
+        3   4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (2)",
+                Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_vertical_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   5
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndFail(View.FOCUS_LEFT, Pair.create(0, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_horizontal_scrollTargetOnTheSameRow()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(4));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (2)" ,
+                Pair.create(1, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_horizontal_traversingThroughASpan()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(8, HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 4) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   4   6
+        2   5   7
+        3   5   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(7));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (5)" ,
+                Pair.create(2, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(4));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (3)" ,
+                Pair.create(2, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_horizontal_withWrapAround()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(8, HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 6) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   4   7
+        2   5   7
+        3   6   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (7)" ,
+                Pair.create(1, 2));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(6));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_LEFT, "Item (5)" ,
+                Pair.create(1, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusLeft_horizontal_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndFail(View.FOCUS_LEFT, Pair.create(0, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_vertical_scrollTargetOnTheSameColumn()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (1)",
+                Pair.create(0, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_vertical_traversingThroughASpan()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        mRecyclerView = setupBasic(new Config(3, 8));
+        mGlm.setOrientation(VERTICAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 3) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   4   5
+        6   7   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(6));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (4)" ,
+                Pair.create(1, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (2)" ,
+                Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_vertical_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndFail(View.FOCUS_UP, Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_horizontal_scrollTargetOnTheSameColumn()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (1)" ,
+                Pair.create(0, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_horizontal_traversingThroughASpan()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        mRecyclerView = setupBasic(new Config(4, 9));
+        mGlm.setOrientation(HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 5) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   5   8
+        2   6   9
+        3   6
+        4   7
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(6));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (6)" ,
+                Pair.create(2, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(5));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_UP, "Item (5)" ,
+                Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusUp_horizontal_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndFail(View.FOCUS_UP, Pair.create(0, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_vertical_scrollTargetOnTheSameColumn()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(0));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (4)", Pair.create(1,
+                0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_vertical_traversingThroughASpan()
+            throws Throwable {
+
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        mRecyclerView = setupBasic(new Config(3, 8));
+        mGlm.setOrientation(VERTICAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 3) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   2   3
+        4   4   5
+        6   7   8
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (4)" ,
+                Pair.create(1, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (7)" ,
+                Pair.create(2, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_vertical_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android version.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(4, VERTICAL);
+        /*
+        This generates the following grid:
+        1   2   3
+        4
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndFail(View.FOCUS_DOWN, Pair.create(0, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(3));
+        runScrollInDirectionAndFail(View.FOCUS_DOWN, Pair.create(1, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_horizontal_scrollTargetOnTheSameColumn()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(1));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (3)" ,
+                Pair.create(2, 0));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_horizontal_traversingThroughASpan()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        mRecyclerView = setupBasic(new Config(4, 9));
+        mGlm.setOrientation(HORIZONTAL);
+        mGlm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+            @Override
+            public int getSpanSize(int position) {
+                if (position == 5) {
+                    return 2;
+                }
+                return 1;
+            }
+        });
+        waitForFirstLayout(mRecyclerView);
+        /*
+        This generates the following grid:
+        1   5   8
+        2   6   9
+        3   6
+        4   7
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(4));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (6)" ,
+                Pair.create(1, 1));
+
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(5));
+        runScrollInDirectionAndSucceed(uiAutomation, View.FOCUS_DOWN, "Item (7)" ,
+                Pair.create(3, 1));
+    }
+
+    @Test
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    public void performActionScrollInDirection_focusDown_horizontal_withoutAvailableTarget()
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpGridLayoutManagerAccessibilityTest(5, HORIZONTAL);
+        /*
+        This generates the following grid:
+        1   4
+        2   5
+        3
+        */
+        setAccessibilityFocus(uiAutomation, mGlm.getChildAt(2));
+        runScrollInDirectionAndFail(View.FOCUS_DOWN, Pair.create(2, 0));
+    }
+
+    /**
+     * Verifies that a scroll successfully occurs in the specified {@code direction}.
+     *
+     * @param uiAutomation  UiAutomation instance.
+     * @param direction The direction of the scroll.
+     * @param scrollTargetText The text of the view targeted by the scroll.
+     * @throws TimeoutException Exception thrown when an action times out.
+     */
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    private void runScrollInDirectionAndSucceed(UiAutomation uiAutomation, int direction,
+            String scrollTargetText)
+            throws TimeoutException {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final boolean[] returnValue = {false};
+        AccessibilityEvent awaitedEvent = uiAutomation.executeAndWaitForEvent(
+                () -> mActivityRule.runOnUiThread(() -> {
+                    returnValue[0] =
+                            mRecyclerView.getLayoutManager().performAccessibilityAction(
+                                    ACTION_SCROLL_IN_DIRECTION.getId(),
+                                    bundleWithDirectionArg(direction));
+                }),
+                event -> event.getEventType() == AccessibilityEvent.TYPE_VIEW_TARGETED_BY_SCROLL,
+                DEFAULT_ACCESSIBILITY_EVENT_TIMEOUT_MILLIS);
+
+        assertThat(scrollTargetText).isEqualTo(awaitedEvent.getSource().getText());
+        assertThat(returnValue[0]).isTrue();
+    }
+
+    /**
+     * Verifies that a scroll successfully occurs in the specified {@code direction} and that the
+     * values of {@code mRowIndexForAccessibility} and {@code mColumnIndexForAccessibility} are
+     * currectly set.
+     *
+     * @param uiAutomation  UiAutomation instance.
+     * @param direction The direction of the scroll.
+     * @param scrollTargetText The text of the view targeted by the scroll.
+     * @param rowColumn The values for the row and column with accessibility focus.
+     *
+     * @throws TimeoutException Exception thrown when an action times out.
+     */
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    private void runScrollInDirectionAndSucceed(UiAutomation uiAutomation, int direction,
+            String scrollTargetText, Pair<Integer, Integer> rowColumn)
+            throws TimeoutException {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        runScrollInDirectionAndSucceed(uiAutomation, direction, scrollTargetText);
+        assertThat(mGlm.mRowWithAccessibilityFocus).isEqualTo(rowColumn.first);
+        assertThat(mGlm.mColumnWithAccessibilityFocus).isEqualTo(rowColumn.second);
+    }
+
+    /**
+     * Verifies that a scroll does not occur in the specified {@code direction}.
+     *
+     * @param direction The direction of the scroll.
+     */
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    private void runScrollInDirectionAndFail(int direction) {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final boolean[] returnValue = {false};
+
+        mActivityRule.runOnUiThread(
+                () -> {
+                    returnValue[0] = mRecyclerView.getLayoutManager().performAccessibilityAction(
+                            ACTION_SCROLL_IN_DIRECTION.getId(), bundleWithDirectionArg(direction));
+                });
+
+        assertThat(returnValue[0]).isFalse();
+    }
+
+    /**
+     * Verifies that a scroll does not occur in the specified {@code direction}.
+     *
+     * @param direction The direction of the scroll.
+     * @param rowColumn The values for the row and column with accessibility focus.
+     */
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    private void runScrollInDirectionAndFail(int direction, Pair<Integer, Integer> rowColumn) {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final boolean[] returnValue = {false};
+
+        mActivityRule.runOnUiThread(
+                () -> {
+                    returnValue[0] = mRecyclerView.getLayoutManager().performAccessibilityAction(
+                            ACTION_SCROLL_IN_DIRECTION.getId(), bundleWithDirectionArg(direction));
+                });
+
+        assertThat(returnValue[0]).isFalse();
+        assertThat(mGlm.mRowWithAccessibilityFocus).isEqualTo(rowColumn.first);
+        assertThat(mGlm.mColumnWithAccessibilityFocus).isEqualTo(rowColumn.second);
+    }
+
+    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+    @NonNull
+    private UiAutomation setUpGridLayoutManagerAccessibilityTest(int itemCount, int orientation)
+            throws Throwable {
+        // TODO(b/267511848): suppress to LOLLIPOP once U constants are finalized and available in
+        //  earlier android versions.
+
+        final UiAutomation uiAutomation = setUpAndReturnUiAutomation();
+        setUpRecyclerViewAndGridLayoutManager(itemCount, orientation);
+        waitForFirstLayout(mRecyclerView);
+        return uiAutomation;
+    }
+
+    private Bundle bundleWithDirectionArg(int direction) {
+        Bundle bundle = new Bundle();
+        bundle.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_DIRECTION_INT, direction);
+        return bundle;
+    }
+
+    @NonNull
+    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
+    private UiAutomation setUpAndReturnUiAutomation() {
+        UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        final AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
+        info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE;
+        uiAutomation.setServiceInfo(info);
+        return uiAutomation;
+    }
+
+    private void setAccessibilityFocus(UiAutomation uiAutomation, View source)
+            throws TimeoutException {
+        AccessibilityEvent awaitedEvent = null;
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            awaitedEvent = uiAutomation.executeAndWaitForEvent(
+                    () -> {
+                        try {
+                            mActivityRule.runOnUiThread(() -> source.performAccessibilityAction(
+                                    ACTION_ACCESSIBILITY_FOCUS.getId(), null));
+                        } catch (Throwable throwable) {
+                            throwable.printStackTrace();
+                        }
+                    },
+                    event -> event.getEventType()
+                            == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED,
+                    DEFAULT_ACCESSIBILITY_EVENT_TIMEOUT_MILLIS);
+            assertThat(awaitedEvent.getSource().isAccessibilityFocused()).isTrue();
+        }
+    }
+
+    private void setUpRecyclerViewAndGridLayoutManager(int itemCount, int orientation)
+            throws Throwable {
+        mRecyclerView = setupBasic(new Config(3, itemCount));
+        mGlm.setOrientation(orientation);
+    }
+
     public GridLayoutManager.LayoutParams ensureGridLp(View view) {
         ViewGroup.LayoutParams lp = view.getLayoutParams();
         GridLayoutManager.LayoutParams glp;
@@ -1638,7 +2575,7 @@
         rv.setLayoutParams(new ViewGroup.LayoutParams(500, 500));
         mAdapter.setFullSpan(0);
         waitForFirstLayout(rv);
-        Truth.assertThat(getPositionToSpanIndexMapping()).containsExactly(
+        assertThat(getPositionToSpanIndexMapping()).containsExactly(
                 0, 0,
                 1, 0,
                 2, 1,
@@ -1656,7 +2593,7 @@
             }
         });
         waitForAnimations(10);
-        Truth.assertThat(getPositionToSpanIndexMapping()).containsExactly(
+        assertThat(getPositionToSpanIndexMapping()).containsExactly(
                 0, 0,
                 1, 0,
                 2, 1,
@@ -1669,7 +2606,7 @@
         // 3 4
         // 5 6
         // 7
-        Truth.assertThat(getPositionToSpanIndexMapping()).containsExactly(
+        assertThat(getPositionToSpanIndexMapping()).containsExactly(
                 3, 0,
                 4, 1,
                 5, 0,
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
index 6eeb355..a6d44ad 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewAccessibilityTest.java
@@ -19,9 +19,11 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 
 import android.os.Build;
+import android.os.Bundle;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -33,12 +35,17 @@
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.test.filters.SmallTest;
 
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -220,7 +227,7 @@
         hScrolledFwd.set(false);
         vScrolledFwd.set(false);
         performAccessibilityAction(delegateCompat, recyclerView,
-                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
         assertEquals(mHorizontalScrollBefore, hScrolledBack.get());
         assertEquals(mVerticalScrollBefore, vScrolledBack.get());
         assertEquals(false, hScrolledFwd.get());
@@ -231,7 +238,7 @@
         hScrolledFwd.set(false);
         vScrolledFwd.set(false);
         performAccessibilityAction(delegateCompat, recyclerView,
-                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
         assertEquals(false, hScrolledBack.get());
         assertEquals(false, vScrolledBack.get());
         assertEquals(mHorizontalScrollAfter, hScrolledFwd.get());
@@ -293,64 +300,8 @@
         AtomicInteger hScrolledOffset = new AtomicInteger(0);
         AtomicInteger vScrolledOffset = new AtomicInteger(0);
 
-        final RecyclerView recyclerView = new RecyclerView(getActivity()) {
-            @Override
-            void smoothScrollBy(@Px int dx, @Px int dy, @Nullable Interpolator interpolator,
-                    int duration, boolean withNestedScrolling) {
-                // Overrides duration to 0 to stop segmentation to get the complete scroll distance.
-                int overrideDuration = 0;
-                super.smoothScrollBy(dx, dy, interpolator, overrideDuration, withNestedScrolling);
-            }
-
-            @Override
-            public boolean canScrollHorizontally(int direction) {
-                return true;
-            }
-
-            @Override
-            public boolean canScrollVertically(int direction) {
-                return true;
-            }
-        };
-        final TestAdapter adapter = new TestAdapter(10);
-
-        recyclerView.setAdapter(adapter);
-        recyclerView.setLayoutManager(new TestLayoutManager() {
-            @Override
-            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
-                layoutRange(recycler, 0, 5);
-            }
-
-            @Override
-            public RecyclerView.LayoutParams generateDefaultLayoutParams() {
-                return new RecyclerView.LayoutParams(-1, -1);
-            }
-
-            @Override
-            public boolean canScrollVertically() {
-                return true;
-            }
-
-            @Override
-            public boolean canScrollHorizontally() {
-                return true;
-            }
-
-            @Override
-            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
-                    RecyclerView.State state) {
-                hScrolledOffset.set(dx);
-                return 0;
-            }
-
-            @Override
-            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
-                    RecyclerView.State state) {
-                vScrolledOffset.set(dy);
-                return 0;
-            }
-        });
-        setRecyclerView(recyclerView);
+        final RecyclerView recyclerView =
+                setUpAndReturnRecyclerViewForScrollActionTest(hScrolledOffset, vScrolledOffset);
         final RecyclerViewAccessibilityDelegate delegateCompat = recyclerView
                 .getCompatAccessibilityDelegate();
         final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
@@ -371,12 +322,12 @@
         int width = recyclerView.getWidth();
         int height = recyclerView.getHeight();
         performAccessibilityAction(delegateCompat, recyclerView,
-                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
         assertEquals(-width, hScrolledOffset.get());
         assertEquals(-height, vScrolledOffset.get());
 
         performAccessibilityAction(delegateCompat, recyclerView,
-                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
         assertEquals(width, hScrolledOffset.get());
         assertEquals(height, vScrolledOffset.get());
 
@@ -392,12 +343,12 @@
             getInstrumentation().waitForIdleSync();
 
             performAccessibilityAction(delegateCompat, recyclerView,
-                    AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
+                    AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, null);
             assertEquals(-halfWidth, hScrolledOffset.get());
             assertEquals(-halfHeight, vScrolledOffset.get());
 
             performAccessibilityAction(delegateCompat, recyclerView,
-                    AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
+                    AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, null);
             assertEquals(halfWidth, hScrolledOffset.get());
             assertEquals(halfHeight, vScrolledOffset.get());
         } finally {
@@ -407,13 +358,259 @@
         }
     }
 
+    @Ignore("b/283754680")
+    @Test
+    public void performGranularScrolling_changesTheScrollAmount()
+            throws Throwable {
+        AtomicInteger hScrolledOffset = new AtomicInteger(0);
+        AtomicInteger vScrolledOffset = new AtomicInteger(0);
+        final RecyclerView recyclerView = setUpAndReturnRecyclerViewForScrollActionTest(
+                hScrolledOffset, vScrolledOffset);
+        final RecyclerViewAccessibilityDelegate delegateCompat = recyclerView
+                .getCompatAccessibilityDelegate();
+        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+
+        mActivityRule.runOnUiThread(
+                () -> delegateCompat.onInitializeAccessibilityNodeInfo(recyclerView, info));
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(info.isGranularScrollingSupported());
+
+        int width = recyclerView.getWidth();
+        int height = recyclerView.getHeight();
+        Bundle args = new Bundle();
+        float scrollAmount = .5F;
+        args.putFloat(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT,
+                scrollAmount);
+
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, args);
+        int w = (int) (width * scrollAmount);
+        int h = (int) (height * scrollAmount);
+        assertEquals(-w, hScrolledOffset.get());
+        assertEquals(-h, vScrolledOffset.get());
+
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, args);
+        w = (int) (width * scrollAmount);
+        h = (int) (height * scrollAmount);
+        assertEquals(w, hScrolledOffset.get());
+        assertEquals(h, vScrolledOffset.get());
+    }
+
+    @Ignore("b/283754680")
+    @Test
+    public void performGranularScrolling_withDefaultOrUndefinedValues_scrollsByOneScreen()
+            throws Throwable {
+        AtomicInteger hScrolledOffset = new AtomicInteger(0);
+        AtomicInteger vScrolledOffset = new AtomicInteger(0);
+        final RecyclerView recyclerView = setUpAndReturnRecyclerViewForScrollActionTest(
+                hScrolledOffset, vScrolledOffset);
+        final RecyclerViewAccessibilityDelegate delegateCompat = recyclerView
+                .getCompatAccessibilityDelegate();
+        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+
+        mActivityRule.runOnUiThread(
+                () -> delegateCompat.onInitializeAccessibilityNodeInfo(recyclerView, info));
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(info.isGranularScrollingSupported());
+
+        int width = recyclerView.getWidth();
+        int height = recyclerView.getHeight();
+        Bundle args = new Bundle();
+        args.putFloat(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT, 1F);
+
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, args);
+        assertEquals(-width, hScrolledOffset.get());
+        assertEquals(-height, vScrolledOffset.get());
+
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, args);
+        assertEquals(width, hScrolledOffset.get());
+        assertEquals(height, vScrolledOffset.get());
+
+        args.putFloat(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT, 0F);
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, args);
+        assertEquals(-width, hScrolledOffset.get());
+        assertEquals(-height, vScrolledOffset.get());
+
+        performAccessibilityAction(delegateCompat, recyclerView,
+                AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, args);
+        assertEquals(width, hScrolledOffset.get());
+        assertEquals(height, vScrolledOffset.get());
+    }
+
+    @Test
+    public void performGranularScrolling_withANegativeValue_throwsException()
+            throws Throwable {
+
+        final RecyclerView recyclerView = setUpAndReturnRecyclerViewForScrollActionTest(
+                new AtomicInteger(0),
+                new AtomicInteger(0));
+        final RecyclerViewAccessibilityDelegate delegateCompat = recyclerView
+                .getCompatAccessibilityDelegate();
+        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+
+        mActivityRule.runOnUiThread(
+                () -> delegateCompat.onInitializeAccessibilityNodeInfo(recyclerView, info));
+        getInstrumentation().waitForIdleSync();
+
+        Bundle args = new Bundle();
+        args.putFloat(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT, -1F);
+
+        // Note: this assumes that debug assertions are enabled in tests (but not in production).
+        assertThrows(IllegalArgumentException.class,
+                () -> performAccessibilityAction(delegateCompat, recyclerView,
+                        AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD, args));
+
+        assertThrows(IllegalArgumentException.class,
+                () -> performAccessibilityAction(delegateCompat, recyclerView,
+                        AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD, args));
+    }
+
+    @Test
+    public void performScrollActions_withGranularScrollingForwardToInfinity_scrollsToTheEnd()
+            throws Throwable {
+        final CountDownLatch scrollListenerLatch = new CountDownLatch(1);
+        final RecyclerView recyclerView = createRecyclerViewAndAdapter();
+        setLayoutManagerWithSmoothScrollToPosition(recyclerView, scrollListenerLatch,
+                recyclerView.mAdapter.getItemCount() - 1);
+        setRecyclerView(recyclerView);
+        runScrollToInfinityTest(recyclerView, AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD,
+                scrollListenerLatch);
+    }
+
+    @Test
+    public void performScrollActions_withGranularScrollingBackwardToInfinity_scrollsToTheBeginning()
+            throws Throwable {
+        final CountDownLatch scrollListenerLatch = new CountDownLatch(1);
+        final RecyclerView recyclerView = createRecyclerViewAndAdapter();
+        setLayoutManagerWithSmoothScrollToPosition(recyclerView, scrollListenerLatch, 0);
+        setRecyclerView(recyclerView);
+        runScrollToInfinityTest(recyclerView, AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD,
+                scrollListenerLatch);
+    }
+
+    private void runScrollToInfinityTest(RecyclerView recyclerView, int action,
+            CountDownLatch scrollListenerLatch) throws Throwable {
+        final RecyclerViewAccessibilityDelegate delegateCompat = recyclerView
+                .getCompatAccessibilityDelegate();
+        final AccessibilityNodeInfoCompat info = AccessibilityNodeInfoCompat.obtain();
+
+        mActivityRule.runOnUiThread(
+                () -> delegateCompat.onInitializeAccessibilityNodeInfo(recyclerView, info));
+        getInstrumentation().waitForIdleSync();
+
+        Bundle args = new Bundle();
+        args.putFloat(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT,
+                Float.POSITIVE_INFINITY);
+
+        boolean result = performAccessibilityAction(delegateCompat, recyclerView, action, args);
+
+        assertTrue(result);
+        MatcherAssert.assertThat(scrollListenerLatch.await(2, TimeUnit.SECONDS),
+                CoreMatchers.is(true));
+    }
+
+    private RecyclerView setUpAndReturnRecyclerViewForScrollActionTest(
+            AtomicInteger hScrolledOffset, AtomicInteger vScrolledOffset) throws Throwable {
+        final RecyclerView recyclerView = createRecyclerViewAndAdapter();
+        setLayoutManager(recyclerView, hScrolledOffset, vScrolledOffset);
+        setRecyclerView(recyclerView);
+        return recyclerView;
+    }
+
+    private RecyclerView createRecyclerViewAndAdapter() {
+        final RecyclerView recyclerView = new RecyclerView(getActivity()) {
+            @Override
+            void smoothScrollBy(@Px int dx, @Px int dy, @Nullable Interpolator interpolator,
+                    int duration, boolean withNestedScrolling) {
+                // Overrides duration to 0 to stop segmentation to get the complete scroll distance.
+                int overrideDuration = 0;
+                super.smoothScrollBy(dx, dy, interpolator, overrideDuration, withNestedScrolling);
+            }
+
+            @Override
+            public boolean canScrollHorizontally(int direction) {
+                return true;
+            }
+
+            @Override
+            public boolean canScrollVertically(int direction) {
+                return true;
+            }
+        };
+
+        final TestAdapter adapter = new TestAdapter(100);
+        recyclerView.setAdapter(adapter);
+        return recyclerView;
+    }
+
+    private void setLayoutManager(RecyclerView recyclerView, AtomicInteger hScrolledOffset,
+            AtomicInteger vScrolledOffset) {
+        recyclerView.setLayoutManager(new TestLayoutManager() {
+            @Override
+            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+                layoutRange(recycler, 0, 100);
+            }
+
+            @Override
+            public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+                return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100);
+            }
+
+            @Override
+            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
+                    RecyclerView.State state) {
+                hScrolledOffset.set(dx);
+                return 0;
+            }
+
+            @Override
+            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
+                    RecyclerView.State state) {
+                vScrolledOffset.set(dy);
+                return 0;
+            }
+        });
+    }
+
+    private void setLayoutManagerWithSmoothScrollToPosition(RecyclerView recyclerView,
+            CountDownLatch scrollListenerLatch, int scrollTargetPosition) {
+        recyclerView.setLayoutManager(new TestLayoutManager() {
+            @Override
+            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+                layoutRange(recycler, 0, 100);
+            }
+
+            @Override
+            public RecyclerView.LayoutParams generateDefaultLayoutParams() {
+                return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 100);
+            }
+
+            @Override
+            public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
+                    int position) {
+                // RecyclerView delegates the specifics of smooth scrolling to its layout
+                // managers. Here, we don't check for any specific scroll behavior; instead, we just
+                // verify that this method runs with the specified scroll target position.
+                if (position == scrollTargetPosition) {
+                    scrollListenerLatch.countDown();
+                }
+            }
+        });
+    }
+
     boolean performAccessibilityAction(final AccessibilityDelegateCompat delegate,
-            final RecyclerView recyclerView, final int action) throws Throwable {
+            final RecyclerView recyclerView, final int action, final Bundle args) throws Throwable {
         final boolean[] result = new boolean[1];
         mActivityRule.runOnUiThread(new Runnable() {
             @Override
             public void run() {
-                result[0] = delegate.performAccessibilityAction(recyclerView, action, null);
+                result[0] = delegate.performAccessibilityAction(recyclerView, action, args);
             }
         });
         getInstrumentation().waitForIdleSync();
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewPrefetchTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewPrefetchTest.java
index 6ad0fc8..291e4af 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewPrefetchTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewPrefetchTest.java
@@ -25,6 +25,7 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.SdkSuppress;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -88,6 +89,7 @@
         return mRecyclerView.mRecycler.mCachedViews;
     }
 
+    @Ignore("b/285199733")
     @Test
     public void prefetchTest() throws Throwable {
         RecyclerView recyclerView = new RecyclerView(getActivity());
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java
index f043bf6..7bf62a9 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/GridLayoutManager.java
@@ -17,19 +17,31 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseIntArray;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.GridView;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
 
 /**
  * A {@link RecyclerView.LayoutManager} implementations that lays out items in a grid.
@@ -42,6 +54,14 @@
     private static final boolean DEBUG = false;
     private static final String TAG = "GridLayoutManager";
     public static final int DEFAULT_SPAN_COUNT = -1;
+    private static final int INVALID_POSITION = -1;
+
+    private static final Set<Integer> sSupportedDirectionsForActionScrollInDirection =
+            Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
+                    View.FOCUS_LEFT,
+                    View.FOCUS_RIGHT,
+                    View.FOCUS_UP,
+                    View.FOCUS_DOWN)));
 
     /**
      * Span size have been changed but we've not done a new layout calculation.
@@ -67,6 +87,43 @@
     private boolean mUsingSpansToEstimateScrollBarDimensions;
 
     /**
+     * Used to track the position of the target node brought on screen by
+     * {@code ACTIONS_SCROLL_IN_DIRECTION} so that a {@code TYPE_VIEW_TARGETED_BY_SCROLL} event can
+     * be emitted.
+     */
+    private int mPositionTargetedByScrollInDirection = INVALID_POSITION;
+
+    /**
+     * Stores the index of the row with accessibility focus for use with
+     * {@link  AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}.
+     * This may include a position that is spanned by a grid child. For example, in the following
+     * grid...
+     * 0  3  4
+     * 1  3  5
+     * 2  3  6
+     * ...the child at adapter position 3 (which spans three rows) could have a row index of either
+     * 0, 1, or 2, and the choice may depend on which row of the grid previously had
+     * accessibility focus. Note that for single span cells, the row index stored here should be
+     * the same as the value returned by {@code getRowIndex()}.
+     */
+    int mRowWithAccessibilityFocus = INVALID_POSITION;
+
+    /**
+     * Stores the index of the column with accessibility focus for use with
+     * {@link  AccessibilityNodeInfoCompat.AccessibilityActionCompat#ACTION_SCROLL_IN_DIRECTION}.
+     * This may include a position that is spanned by a grid child. For example, in the following
+     * grid...
+     * 0  1  2
+     * 3  3  3
+     * 4  5  6
+     * ... the child at adapter position 3 (which spans three columns) could have a column index
+     * of either 0, 1, or 2, and the choice may depend on which column of the grid previously had
+     * accessibility focus. Note that for single span cells, the column index stored here should be
+     * the same as the value returned by {@code getColumnIndex()}.
+     */
+    int mColumnWithAccessibilityFocus = INVALID_POSITION;
+
+    /**
      * Constructor used when layout manager is set in XML by RecyclerView attribute
      * "layoutManager". If spanCount is not specified in the XML, it defaults to a
      * single column.
@@ -175,11 +232,123 @@
         // and list via CollectionInfos, but an almost empty grid may be incorrectly identified
         // as a list.
         info.setClassName(GridView.class.getName());
+
+        if (mRecyclerView.mAdapter != null && mRecyclerView.mAdapter.getItemCount() > 1) {
+            info.addAction(AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION);
+        }
     }
 
     @Override
     boolean performAccessibilityAction(int action, @Nullable Bundle args) {
-        if (action == android.R.id.accessibilityActionScrollToPosition) {
+        // TODO (267511848): when U constants are finalized:
+        //  - convert if/else blocks to switch statement
+        //  - remove SDK check
+        //  - remove the -1 check (this check makes accessibilityActionScrollInDirection
+        //  no-op for < 34; see action definition in AccessibilityNodeInfoCompat.java).
+        if (action == AccessibilityActionCompat.ACTION_SCROLL_IN_DIRECTION.getId()
+                && action != -1) {
+            final View viewWithAccessibilityFocus = findChildWithAccessibilityFocus();
+            if (viewWithAccessibilityFocus == null) {
+                // TODO(b/268487724#comment2): handle rare cases when the requesting service does
+                //  not place accessibility focus on a child. Consider scrolling forward/backward?
+                return false;
+            }
+
+            // Direction must be specified.
+            if (args == null) {
+                return false;
+            }
+
+            final int direction = args.getInt(
+                    AccessibilityNodeInfo.ACTION_ARGUMENT_DIRECTION_INT, INVALID_POSITION);
+
+            if (!sSupportedDirectionsForActionScrollInDirection.contains(direction)) {
+                if (DEBUG) {
+                    Log.w(TAG, "Direction equals " + direction
+                            + "which is unsupported when using ACTION_SCROLL_IN_DIRECTION");
+                }
+                return false;
+            }
+
+            RecyclerView.ViewHolder vh =
+                    mRecyclerView.getChildViewHolder(viewWithAccessibilityFocus);
+            if (vh == null) {
+                if (DEBUG) {
+                    throw new RuntimeException(
+                            "viewHolder is null for " + viewWithAccessibilityFocus);
+                }
+                return false;
+            }
+
+            int startingAdapterPosition = vh.getAbsoluteAdapterPosition();
+            int startingRow = getRowIndex(startingAdapterPosition);
+            int startingColumn = getColumnIndex(startingAdapterPosition);
+
+            if (startingRow < 0 || startingColumn < 0) {
+                if (DEBUG) {
+                    throw new RuntimeException("startingRow equals " + startingRow + ", and "
+                            + "startingColumn equals " + startingColumn + ", and neither can be "
+                            + "less than 0.");
+                }
+                return false;
+            }
+
+            if (hasAccessibilityFocusChanged(startingAdapterPosition)) {
+                mRowWithAccessibilityFocus = startingRow;
+                mColumnWithAccessibilityFocus = startingColumn;
+            }
+
+            int scrollTargetPosition;
+
+            int row = (mRowWithAccessibilityFocus == INVALID_POSITION) ? startingRow
+                    : mRowWithAccessibilityFocus;
+            int column = (mColumnWithAccessibilityFocus == INVALID_POSITION)
+                    ? startingColumn : mColumnWithAccessibilityFocus;
+
+            switch (direction) {
+                case View.FOCUS_LEFT:
+                    scrollTargetPosition = findScrollTargetPositionOnTheLeft(row, column,
+                            startingAdapterPosition);
+                    break;
+                case View.FOCUS_RIGHT:
+                    scrollTargetPosition =
+                            findScrollTargetPositionOnTheRight(row, column,
+                                    startingAdapterPosition);
+                    break;
+                case View.FOCUS_UP:
+                    scrollTargetPosition = findScrollTargetPositionAbove(row, column,
+                            startingAdapterPosition);
+                    break;
+                case View.FOCUS_DOWN:
+                    scrollTargetPosition = findScrollTargetPositionBelow(row, column,
+                            startingAdapterPosition);
+                    break;
+                default:
+                    return false;
+            }
+
+            if (scrollTargetPosition == INVALID_POSITION
+                    && mOrientation == RecyclerView.HORIZONTAL) {
+                // TODO (b/268487724): handle RTL.
+                // Handle case in grids with horizontal orientation where the scroll target is on
+                // a different row.
+                if (direction == View.FOCUS_LEFT) {
+                    scrollTargetPosition = findPositionOfLastItemOnARowAboveForHorizontalGrid(
+                            startingRow);
+                } else if (direction == View.FOCUS_RIGHT) {
+                    scrollTargetPosition = findPositionOfFirstItemOnARowBelowForHorizontalGrid(
+                            startingRow);
+                }
+            }
+
+            if (scrollTargetPosition != INVALID_POSITION) {
+                scrollToPosition(scrollTargetPosition);
+                mPositionTargetedByScrollInDirection = scrollTargetPosition;
+                return true;
+            }
+
+            return false;
+        } else if (action == android.R.id.accessibilityActionScrollToPosition) {
             final int noRow = -1;
             final int noColumn = -1;
             if (args != null) {
@@ -228,6 +397,439 @@
         return super.performAccessibilityAction(action, args);
     }
 
+    private int findScrollTargetPositionOnTheRight(int startingRow, int startingColumn,
+            int startingAdapterPosition) {
+        int scrollTargetPosition = INVALID_POSITION;
+        for (int i = startingAdapterPosition + 1; i < getItemCount(); i++) {
+            int currentRow = getRowIndex(i);
+            int currentColumn = getColumnIndex(i);
+
+            if (currentRow < 0 || currentColumn < 0) {
+                if (DEBUG) {
+                    throw new RuntimeException("currentRow equals " + currentRow + ", and "
+                            + "currentColumn equals " + currentColumn + ", and neither can be "
+                            + "less than 0.");
+                }
+                return INVALID_POSITION;
+            }
+
+            if (mOrientation == VERTICAL) {
+                /*
+                 * For grids with vertical orientation...
+                 * 1   2   3
+                 * 4   5   5
+                 * 6   7
+                 * ... the scroll target may lie on the same or a following row.
+                 */
+                // TODO (b/268487724): handle RTL.
+                if ((currentRow == startingRow && currentColumn > startingColumn)
+                        || (currentRow > startingRow)) {
+                    mRowWithAccessibilityFocus = currentRow;
+                    mColumnWithAccessibilityFocus = currentColumn;
+                    return i;
+                }
+            } else { // HORIZONTAL
+                /*
+                 * For grids with horizontal orientation, the scroll target may span multiple
+                 * rows. For example, in this grid...
+                 * 1   4   6
+                 * 2   5   7
+                 * 3   5   8
+                 * ... moving from 3 to 5 is considered staying on the "same row" because 5 spans
+                 *  multiple rows and the row indices for 5 include 3's row.
+                 */
+                if (currentColumn > startingColumn && getRowIndices(i).contains(startingRow)) {
+                    // Note: mRowWithAccessibilityFocus not updated since the scroll target is on
+                    // the same row.
+                    mColumnWithAccessibilityFocus = currentColumn;
+                    return i;
+                }
+            }
+        }
+
+        return scrollTargetPosition;
+    }
+
+    private int findScrollTargetPositionOnTheLeft(int startingRow, int startingColumn,
+            int startingAdapterPosition) {
+        int scrollTargetPosition = INVALID_POSITION;
+        for (int i = startingAdapterPosition - 1; i >= 0; i--) {
+            int currentRow = getRowIndex(i);
+            int currentColumn = getColumnIndex(i);
+
+            if (currentRow < 0 || currentColumn < 0) {
+                if (DEBUG) {
+                    throw new RuntimeException("currentRow equals " + currentRow + ", and "
+                            + "currentColumn equals " + currentColumn + ", and neither can be "
+                            + "less than 0.");
+                }
+                return INVALID_POSITION;
+            }
+
+            if (mOrientation == VERTICAL) {
+                /*
+                 * For grids with vertical orientation...
+                 * 1   2   3
+                 * 4   5   5
+                 * 6   7
+                 * ... the scroll target may lie on the same or a preceding row.
+                 */
+                // TODO (b/268487724): handle RTL.
+                if ((currentRow == startingRow && currentColumn < startingColumn)
+                        || (currentRow < startingRow)) {
+                    scrollTargetPosition = i;
+                    mRowWithAccessibilityFocus = currentRow;
+                    mColumnWithAccessibilityFocus = currentColumn;
+                    break;
+                }
+            } else { // HORIZONTAL
+                /*
+                 * For grids with horizontal orientation, the scroll target may span multiple
+                 * rows. For example, in this grid...
+                 * 1   4   6
+                 * 2   5   7
+                 * 3   5   8
+                 * ... moving from 8 to 5 or from 7 to 5 is considered staying on the "same row"
+                 * because the row indices for 5 include 8's and 7's row.
+                 */
+                if (getRowIndices(i).contains(startingRow) && currentColumn < startingColumn) {
+                    // Note: mRowWithAccessibilityFocus not updated since the scroll target is on
+                    // the same row.
+                    mColumnWithAccessibilityFocus = currentColumn;
+                    return i;
+                }
+            }
+        }
+        return scrollTargetPosition;
+    }
+
+    private int findScrollTargetPositionAbove(int startingRow, int startingColumn,
+            int startingAdapterPosition) {
+        int scrollTargetPosition = INVALID_POSITION;
+        for (int i = startingAdapterPosition - 1; i >= 0; i--) {
+            int currentRow = getRowIndex(i);
+            int currentColumn = getColumnIndex(i);
+
+            if (currentRow < 0 || currentColumn < 0) {
+                if (DEBUG) {
+                    throw new RuntimeException("currentRow equals " + currentRow + ", and "
+                            + "currentColumn equals " + currentColumn + ", and neither can be "
+                            + "less than 0.");
+                }
+                return INVALID_POSITION;
+            }
+
+            if (mOrientation == VERTICAL) {
+                /*
+                 * The scroll target may span multiple columns. For example, in this grid...
+                 * 1   2   3
+                 * 4   4   5
+                 * 6   7
+                 * ... moving from 7 to 4 interprets as staying in second column, and moving from
+                 * 6 to 4 interprets as staying in the first column.
+                 */
+                if (currentRow < startingRow && getColumnIndices(i).contains(startingColumn)) {
+                    scrollTargetPosition = i;
+                    mRowWithAccessibilityFocus = currentRow;
+                    // Note: mColumnWithAccessibilityFocus not updated since the scroll target is on
+                    // the same column.
+                    break;
+                }
+            } else { // HORIZONTAL
+                /*
+                 * The scroll target may span multiple rows. In this grid...
+                 * 1   4
+                 * 2   5
+                 * 2
+                 * 3
+                 * ... 2 spans two rows and moving up from 3 to 2 interprets moving to the third
+                 * row.
+                 */
+                if (currentRow < startingRow && currentColumn == startingColumn) {
+                    Set<Integer> rowIndices = getRowIndices(i);
+                    scrollTargetPosition = i;
+                    mRowWithAccessibilityFocus = Collections.max(rowIndices);
+                    // Note: mColumnWithAccessibilityFocus not updated since the scroll target is on
+                    // the same column.
+                    break;
+                }
+            }
+        }
+        return scrollTargetPosition;
+    }
+
+    private int findScrollTargetPositionBelow(int startingRow, int startingColumn,
+            int startingAdapterPosition) {
+        int scrollTargetPosition = INVALID_POSITION;
+        for (int i = startingAdapterPosition + 1; i < getItemCount(); i++) {
+            int currentRow = getRowIndex(i);
+            int currentColumn = getColumnIndex(i);
+
+            if (currentRow < 0 || currentColumn < 0) {
+                if (DEBUG) {
+                    throw new RuntimeException("currentRow equals " + currentRow + ", and "
+                            + "currentColumn equals " + currentColumn + ", and neither can be "
+                            + "less than 0.");
+                }
+                return INVALID_POSITION;
+            }
+
+            if (mOrientation == VERTICAL) {
+                /*
+                 * The scroll target may span multiple columns. For example, in this grid...
+                 * 1   2   3
+                 * 4   4   5
+                 * 6   7
+                 * ... moving from 2 to 4 interprets as staying in second column, and moving from
+                 * 1 to 4 interprets as staying in the first column.
+                 */
+                if ((currentRow > startingRow) && (currentColumn == startingColumn
+                        || getColumnIndices(i).contains(startingColumn))) {
+                    scrollTargetPosition = i;
+                    mRowWithAccessibilityFocus = currentRow;
+                    break;
+                }
+            } else { // HORIZONTAL
+                /*
+                 * The scroll target may span multiple rows. In this grid...
+                 * 1   4
+                 * 2   5
+                 * 2
+                 * 3
+                 * ... 2 spans two rows and moving down from 1 to 2 interprets moving to the second
+                 * row.
+                 */
+                if (currentRow > startingRow && currentColumn == startingColumn) {
+                    scrollTargetPosition = i;
+                    mRowWithAccessibilityFocus = getRowIndex(i);
+                    break;
+                }
+            }
+        }
+        return scrollTargetPosition;
+    }
+
+    @SuppressWarnings("ConstantConditions") // For the spurious NPE warning related to getting a
+        // value from a map using one of the map keys.
+    int findPositionOfLastItemOnARowAboveForHorizontalGrid(int startingRow) {
+        if (startingRow < 0) {
+            if (DEBUG) {
+                throw new RuntimeException(
+                        "startingRow equals " + startingRow + ". It cannot be less than zero");
+            }
+            return INVALID_POSITION;
+        }
+
+        if (mOrientation == VERTICAL) {
+            // This only handles cases of grids with horizontal orientation.
+            if (DEBUG) {
+                Log.w(TAG, "You should not "
+                        + "use findPositionOfLastItemOnARowAboveForHorizontalGrid(...) with grids "
+                        + "with VERTICAL orientation");
+            }
+            return INVALID_POSITION;
+        }
+
+        // Map where the keys are row numbers and values are the adapter positions of the last
+        // item in each row. This map is used to locate a scroll target on a previous row in grids
+        // with horizontal orientation. In this example...
+        // 1   4   7
+        // 2   5   8
+        // 3   6
+        // ... the generated map - {2 -> 5, 1 -> 7, 0 -> 6} - can be used to scroll from,
+        // say, "2" (adapter position 1) in the second row to "7" (adapter position 6) in the
+        // preceding row.
+        //
+        // Sometimes cells span multiple rows. In this example:
+        // 1   4   7
+        // 2   5   7
+        // 3   6   8
+        // ... the generated map - {0 -> 6, 1 -> 6, 2 -> 7} - can be used to scroll left from,
+        // say, "3" (adapter position 2) in the third row to "7" (adapter position 6) on the
+        // second row, and then to "5" (adapter position 4).
+        Map<Integer, Integer> rowToLastItemPositionMap = new TreeMap<>(Collections.reverseOrder());
+        for (int position = 0; position < getItemCount(); position++) {
+            Set<Integer> rows = getRowIndices(position);
+            for (int row: rows) {
+                if (row < 0) {
+                    if (DEBUG) {
+                        throw new RuntimeException(
+                                "row equals " + row + ". It cannot be less than zero");
+                    }
+                    return INVALID_POSITION;
+                }
+                rowToLastItemPositionMap.put(row, position);
+            }
+        }
+
+        for (int row : rowToLastItemPositionMap.keySet()) {
+            if (row < startingRow) {
+                int scrollTargetPosition = rowToLastItemPositionMap.get(row);
+                mRowWithAccessibilityFocus = row;
+                mColumnWithAccessibilityFocus = getColumnIndex(scrollTargetPosition);
+                return scrollTargetPosition;
+            }
+        }
+        return INVALID_POSITION;
+    }
+
+    @SuppressWarnings("ConstantConditions") // For the spurious NPE warning related to getting a
+        // value from a map using one of the map keys.
+    int findPositionOfFirstItemOnARowBelowForHorizontalGrid(int startingRow) {
+        if (startingRow < 0) {
+            if (DEBUG) {
+                throw new RuntimeException(
+                        "startingRow equals " + startingRow + ". It cannot be less than zero");
+            }
+            return INVALID_POSITION;
+        }
+
+        if (mOrientation == VERTICAL) {
+            // This only handles cases of grids with horizontal orientation.
+            if (DEBUG) {
+                Log.w(TAG, "You should not "
+                        + "use findPositionOfFirstItemOnARowBelowForHorizontalGrid(...) with grids "
+                        + "with VERTICAL orientation");
+            }
+            return INVALID_POSITION;
+        }
+
+        // Map where the keys are row numbers and values are the adapter positions of the first
+        // item in each row. This map is used to locate a scroll target on a following row in grids
+        // with horizontal orientation. In this example:
+        // 1   4   7
+        // 2   5   8
+        // 3   6
+        // ... the generated map - {0 -> 0, 1 -> 1, 2 -> 2} - can be used to scroll from, say,
+        // "7" (adapter position 6) in the first row to "2" (adapter position 1) in the next row.
+        // Sometimes cells span multiple rows. In this example:
+        // 1   3   6
+        // 1   4   7
+        // 2   5   8
+        // ... the generated map - {0 -> 0, 1 -> 0, 2 -> 1} - can be used to scroll right from,
+        // say, "6" (adapter position 5) in the first row to "1" (adapter position 0) on the
+        // second row, and then to "4" (adapter position 3).
+        Map<Integer, Integer> rowToFirstItemPositionMap = new TreeMap<>();
+        for (int position = 0; position < getItemCount(); position++) {
+            Set<Integer> rows = getRowIndices(position);
+            for (int row : rows) {
+                if (row < 0) {
+                    if (DEBUG) {
+                        throw new RuntimeException(
+                                "row equals " + row + ". It cannot be less than zero");
+                    }
+                    return INVALID_POSITION;
+                }
+                // We only care about the first item on each row.
+                if (!rowToFirstItemPositionMap.containsKey(row)) {
+                    rowToFirstItemPositionMap.put(row, position);
+                }
+            }
+        }
+
+        for (int row : rowToFirstItemPositionMap.keySet()) {
+            if (row > startingRow) {
+                int scrollTargetPosition = rowToFirstItemPositionMap.get(row);
+                mRowWithAccessibilityFocus = row;
+                mColumnWithAccessibilityFocus = 0;
+                return scrollTargetPosition;
+            }
+        }
+        return INVALID_POSITION;
+    }
+
+    /**
+     * Returns the row index associated with a position. If the item at this position spans multiple
+     * rows, it returns the first row index. To get all row indices for a position, use
+     * {@link #getRowIndices(int)}.
+     */
+    private int getRowIndex(int position) {
+        return mOrientation == VERTICAL ? getSpanGroupIndex(mRecyclerView.mRecycler,
+                mRecyclerView.mState, position) : getSpanIndex(mRecyclerView.mRecycler,
+                mRecyclerView.mState, position);
+    }
+
+    /**
+     * Returns the column index associated with a position. If the item at this position spans
+     * multiple columns, it returns the first column index. To get all column indices, use
+     * {@link #getColumnIndices(int)}.
+     */
+    private int getColumnIndex(int position) {
+        return mOrientation == HORIZONTAL ? getSpanGroupIndex(mRecyclerView.mRecycler,
+                mRecyclerView.mState, position) : getSpanIndex(mRecyclerView.mRecycler,
+                mRecyclerView.mState, position);
+    }
+
+    /**
+     * Returns the row indices for a cell associated with {@code position}. For example, in this
+     * grid...
+     * 0   2   3
+     * 1   2   4
+     * ... the rows for the view at position 2 will be [0, 1] and the rows for position 3 will be
+     * [0].
+     */
+    private Set<Integer> getRowIndices(int position) {
+        return getRowOrColumnIndices(getRowIndex(position), position);
+    }
+
+    /**
+     * Returns the column indices for a cell associated with {@code position}. For example, in this
+     * grid...
+     * 0   1
+     * 2   2
+     * 3   4
+     * ... the columns for the view at position 2 will be [0, 1] and the columns for position 3
+     * will be [0].
+     */
+    private Set<Integer> getColumnIndices(int position) {
+        return getRowOrColumnIndices(getColumnIndex(position), position);
+    }
+
+    private Set<Integer> getRowOrColumnIndices(int rowOrColumnIndex, int position) {
+        Set<Integer> indices = new HashSet<>();
+        int spanSize = getSpanSize(mRecyclerView.mRecycler, mRecyclerView.mState, position);
+        for (int i = rowOrColumnIndex;  i <  rowOrColumnIndex + spanSize; i++) {
+            indices.add(i);
+        }
+        return indices;
+    }
+
+    @Nullable
+    private View findChildWithAccessibilityFocus() {
+        View child = null;
+        // SDK check needed for View#isAccessibilityFocused()
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            boolean childFound = false;
+            int i;
+            for (i = 0; i < getChildCount(); i++) {
+                if (Api21Impl.isAccessibilityFocused(Objects.requireNonNull(getChildAt(i)))) {
+                    childFound = true;
+                    break;
+                }
+            }
+            if (childFound) {
+                child = getChildAt(i);
+            }
+        }
+        return child;
+    }
+
+    /**
+     * Returns true if the values stored in {@link #mRowWithAccessibilityFocus} and
+     * {@link #mColumnWithAccessibilityFocus} are not correct for the view at
+     * {@code adapterPosition}.
+     *
+     * Note that for cells that span multiple rows or multiple columns, {@link
+     * #mRowWithAccessibilityFocus} and {@link #mColumnWithAccessibilityFocus} can be set to more
+     * than one of several values. Accessibility focus is considered unchanged if any of the
+     * possible row values for a cell are the same as {@link #mRowWithAccessibilityFocus} and any
+     * of the possible column values are the same as {@link #mColumnWithAccessibilityFocus}.
+     */
+    private boolean hasAccessibilityFocusChanged(int adapterPosition) {
+        return !getRowIndices(adapterPosition).contains(mRowWithAccessibilityFocus)
+                || !getColumnIndices(adapterPosition).contains(mColumnWithAccessibilityFocus);
+    }
+
     @Override
     public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
         if (state.isPreLayout()) {
@@ -244,6 +846,19 @@
     public void onLayoutCompleted(RecyclerView.State state) {
         super.onLayoutCompleted(state);
         mPendingSpanCountChange = false;
+        if (mPositionTargetedByScrollInDirection != INVALID_POSITION) {
+            View viewTargetedByScrollInDirection = findViewByPosition(
+                    mPositionTargetedByScrollInDirection);
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
+                    && viewTargetedByScrollInDirection != null) {
+                // Send event after the scroll associated with ACTION_SCROLL_IN_DIRECTION (see
+                // performAccessibilityAction()) concludes and layout completes. Accessibility
+                // services can listen for this event and change UI state as needed.
+                viewTargetedByScrollInDirection.sendAccessibilityEvent(
+                        AccessibilityEvent.TYPE_VIEW_TARGETED_BY_SCROLL);
+                mPositionTargetedByScrollInDirection = INVALID_POSITION;
+            }
+        }
     }
 
     private void clearPreLayoutSpanMappingCache() {
@@ -1506,4 +2121,17 @@
             return mSpanSize;
         }
     }
+
+
+    @RequiresApi(21)
+    private static class Api21Impl {
+        private Api21Impl() {
+            // This class is not instantiable.
+        }
+
+        @DoNotInline
+        static boolean isAccessibilityFocused(@NonNull View view) {
+            return view.isAccessibilityFocused();
+        }
+    }
 }
\ No newline at end of file
diff --git a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
index b908dc3..8c5c4ea 100644
--- a/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
+++ b/recyclerview/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
@@ -11307,10 +11307,12 @@
             if (mRecyclerView.canScrollVertically(-1) || mRecyclerView.canScrollHorizontally(-1)) {
                 info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD);
                 info.setScrollable(true);
+                info.setGranularScrollingSupported(true);
             }
             if (mRecyclerView.canScrollVertically(1) || mRecyclerView.canScrollHorizontally(1)) {
                 info.addAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD);
                 info.setScrollable(true);
+                info.setGranularScrollingSupported(true);
             }
             final AccessibilityNodeInfoCompat.CollectionInfoCompat collectionInfo =
                     AccessibilityNodeInfoCompat.CollectionInfoCompat
@@ -11505,6 +11507,7 @@
                 height = rect.height();
                 width = rect.width();
             }
+
             switch (action) {
                 case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
                     if (mRecyclerView.canScrollVertically(-1)) {
@@ -11523,9 +11526,54 @@
                     }
                     break;
             }
+
             if (vScroll == 0 && hScroll == 0) {
                 return false;
             }
+
+            float granularScrollAmount = 1F; // The default value.
+
+            if (args != null) {
+                granularScrollAmount = args.getFloat(
+                        AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT, 1F);
+                if (granularScrollAmount < 0) {
+                    if (sDebugAssertionsEnabled) {
+                        throw new IllegalArgumentException(
+                                "attempting to use ACTION_ARGUMENT_SCROLL_AMOUNT_FLOAT with a "
+                                        + "negative value (" + granularScrollAmount + ")");
+                    }
+                    return false;
+                }
+            }
+
+            if (Float.compare(granularScrollAmount, Float.POSITIVE_INFINITY) == 0) {
+                // Assume that the client wants to scroll as far as possible. For
+                // ACTION_SCROLL_BACKWARD, this means scrolling to the beginning of the collection.
+                // For ACTION_SCROLL_FORWARD, this means scrolling to the end of the collection.
+
+                if (mRecyclerView.mAdapter == null) {
+                    return false;
+                }
+                switch (action) {
+                    case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD:
+                        mRecyclerView.smoothScrollToPosition(0);
+                        break;
+                    case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD:
+                        mRecyclerView.smoothScrollToPosition(
+                                mRecyclerView.mAdapter.getItemCount() - 1);
+                        break;
+                }
+                return true;
+            }
+
+            // No adjustments needed to scroll values if granular scroll amount is 1F, which is
+            // the default, or 0F, which is undefined.
+            if (Float.compare(1F, granularScrollAmount) != 0 && Float.compare(0F,
+                    granularScrollAmount) != 0) {
+                hScroll = (int) (hScroll * granularScrollAmount);
+                vScroll = (int) (vScroll * granularScrollAmount);
+            }
+
             mRecyclerView.smoothScrollBy(hScroll, vScroll, null, UNDEFINED_DURATION, true);
             return true;
         }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
index 6bcc71f..70a827c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
@@ -96,25 +96,21 @@
     // KSP may improve that later and if not, we can improve it in Room
     // TODO: https://issuetracker.google.com/issues/168639183
     val qualified = qualifiedName?.asString() ?: return ERROR_JTYPE_NAME
+    val pkg = getNormalizedPackageName()
 
     // Note: To match KAPT behavior, a type annotated with @JvmInline is only replaced with the
     // underlying type if the inline type is used directly (e.g. MyInlineType) rather than in the
     // type args of another type, (e.g. List<MyInlineType>).
-    val isInline = isAnnotationPresent(JvmInline::class) || modifiers.contains(Modifier.INLINE)
-    val isOriginalType =
-        typeResolutionContext.originalType?.declaration?.qualifiedName?.asString() == qualified
-    if (!isInline || isOriginalType) {
-        resolver.mapToJvmSignature(this).let { jvmSignature ->
-            if (!jvmSignature.isNullOrBlank()) {
-                return jvmSignature.typeNameFromJvmSignature()
-            }
+    val isInlineUsedDirectly =
+        (isAnnotationPresent(JvmInline::class) || modifiers.contains(Modifier.INLINE)) &&
+            typeResolutionContext.originalType?.declaration?.qualifiedName?.asString() == qualified
+    if (pkg == "kotlin" || pkg.startsWith("kotlin.") || isInlineUsedDirectly) {
+        val jvmSignature = resolver.mapToJvmSignature(this)
+        if (!jvmSignature.isNullOrBlank()) {
+            return jvmSignature.typeNameFromJvmSignature()
         }
     }
 
-    // fallback to custom generation, it is very likely that this is an unresolved type
-    // get the package name first, it might throw for invalid types, hence we use
-    // safeGetPackageName
-    val pkg = getNormalizedPackageName()
     // using qualified name and pkg, figure out the short names.
     val shortNames = if (pkg == "") {
         qualified
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
index 338d041..94cd21f 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
@@ -118,15 +118,16 @@
     }
 
     private fun KSTypeWrapper.replaceSuspendFunctionTypes(): KSTypeWrapper {
+        val newArguments = arguments.map { it.replaceSuspendFunctionTypes() }
         return if (!newType.isSuspendFunctionType) {
-            this
+            replace(newArguments)
         } else {
             val newKSType = newType.replaceSuspendFunctionTypes(resolver)
             val newType = KSTypeWrapper(resolver, newKSType)
             replaceType(newKSType).replace(
                 buildList {
-                    addAll(arguments.dropLast(1))
-                    val originalArg = arguments.last()
+                    addAll(newArguments.dropLast(1))
+                    val originalArg = newArguments.last()
                     val continuationArg = newType.arguments[newType.arguments.lastIndex - 1]
                     add(
                         continuationArg.replace(
@@ -144,6 +145,11 @@
         }
     }
 
+    private fun KSTypeArgumentWrapper.replaceSuspendFunctionTypes(): KSTypeArgumentWrapper {
+        val type = type ?: return this
+        return replace(type.replaceSuspendFunctionTypes(), variance)
+    }
+
     private fun KSTypeWrapper.resolveWildcards(
         scope: KSTypeVarianceResolverScope?
     ) = if (scope == null) {
@@ -367,7 +373,11 @@
 ) {
     val declaration = newType.declaration
 
+    @OptIn(KspExperimental::class)
     val arguments: List<KSTypeArgumentWrapper> by lazy {
+        if (resolver.isJavaRawType(newType)) {
+            return@lazy emptyList()
+        }
         val arguments = newTypeArguments ?: newType.arguments.indices.map { i ->
             KSTypeArgumentWrapper(
                 originalTypeArg = newType.arguments[i],
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
index 1081550..2807df12 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
@@ -98,7 +98,7 @@
     override val filer: XFiler = KspFiler(codeGenerator, messager)
 
     val commonTypes
-        get() = CommonTypes(resolver)
+        get() = CommonTypes()
 
     val voidType
         get() = KspVoidType(
@@ -308,15 +308,7 @@
         return returnType(type1).isSameType(returnType(type2))
     }
 
-    class CommonTypes(resolver: Resolver) {
-        val nullableInt by lazy {
-            resolver.builtIns.intType.makeNullable()
-        }
-        val nullableLong by lazy {
-            resolver.builtIns.longType.makeNullable()
-        }
-        val nullableByte by lazy {
-            resolver.builtIns.byteType.makeNullable()
-        }
+    inner class CommonTypes() {
+        val anyType: XType = requireType("kotlin.Any")
     }
 }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index 54e64ab..2e724a5 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -94,17 +94,19 @@
         if (isInterface()) {
             // interfaces don't have super classes (they do have super types)
             null
+        } else if (this == env.commonTypes.anyType.typeElement) {
+            null
         } else {
-            declaration.superTypes.firstOrNull {
-                val type =
-                    it.resolve().declaration as? KSClassDeclaration ?: return@firstOrNull false
-                type.classKind == ClassKind.CLASS
-            }?.let {
-                env.wrap(
-                    ksType = it.resolve(),
-                    allowPrimitives = false
-                )
-            }
+            declaration.superTypes
+                .map { it.resolve() }
+                .singleOrNull {
+                    (it.declaration as? KSClassDeclaration)?.classKind == ClassKind.CLASS
+                }?.let {
+                    env.wrap(
+                        ksType = it,
+                        allowPrimitives = false
+                    )
+                } ?: env.commonTypes.anyType
         }
     }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index 079024d..d2822e3 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -232,6 +232,55 @@
     }
 
     @Test
+    fun superTypeWithNoSuperClass() {
+        runTest(
+            sources = listOf(
+                Source.kotlin(
+                    "foo.bar.KotlinClass.kt",
+                    """
+                    package foo.bar
+                    class KotlinClass
+                    class KotlinClassWithInterface : KotlinInterface
+                    interface KotlinInterface
+                    """.trimIndent()
+                ),
+                Source.java(
+                    "foo.bar.JavaClass",
+                    """
+                    package foo.bar;
+                    class JavaClass {}
+                    class JavaClassWithInterface implements JavaInterface {}
+                    interface JavaInterface {}
+                    """.trimIndent()
+                )
+            )
+        ) { invocation ->
+            invocation.processingEnv.requireTypeElement("foo.bar.KotlinClass").let {
+                assertThat(it.superClass?.asTypeName()).isEqualTo(XTypeName.ANY_OBJECT)
+            }
+            invocation.processingEnv.requireTypeElement("foo.bar.KotlinClassWithInterface").let {
+                assertThat(it.superClass?.asTypeName()).isEqualTo(XTypeName.ANY_OBJECT)
+            }
+            invocation.processingEnv.requireTypeElement("foo.bar.JavaClass").let {
+                assertThat(it.superClass?.asTypeName()).isEqualTo(XTypeName.ANY_OBJECT)
+            }
+            invocation.processingEnv.requireTypeElement("foo.bar.JavaClassWithInterface").let {
+                assertThat(it.superClass?.asTypeName()).isEqualTo(XTypeName.ANY_OBJECT)
+            }
+        }
+    }
+
+    @Test
+    fun superTypeOfAny() {
+        runTest(sources = listOf()) { invocation ->
+            val any = invocation.processingEnv.requireTypeElement(Any::class)
+            val obj = invocation.processingEnv.requireTypeElement(Object::class)
+            assertThat(any.superClass).isNull()
+            assertThat(obj.superClass).isNull()
+        }
+    }
+
+    @Test
     fun superInterfaces() {
         val src = Source.kotlin(
             "foo.kt",
@@ -2089,6 +2138,24 @@
         }
     }
 
+    @Test
+    fun testClassNameWithDollarSign() {
+        runTest(
+            sources = listOf(
+                Source.java(
+                    "test.MyClass\$Foo",
+                    """
+                    package test;
+                    class MyClass${'$'}Foo {}
+                    """.trimIndent()
+                )
+            )
+        ) { invocation ->
+            val subject = invocation.processingEnv.requireTypeElement("test.MyClass\$Foo")
+            assertThat(subject.asClassName().canonicalName).isEqualTo("test.MyClass\$Foo")
+        }
+    }
+
     /**
      * it is good to exclude methods coming from Object when testing as they differ between KSP
      * and KAPT but irrelevant for Room.
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index babbadec..27d4d87 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -1563,6 +1563,68 @@
     }
 
     @Test
+    fun rawTypeNames() {
+        val src = Source.java(
+            "test.Subject",
+            """
+            package test;
+            import java.util.Set;
+            @SuppressWarnings("rawtypes")
+            class Subject {
+                Foo foo;
+                Foo<Foo> fooFoo;
+                Foo<Foo<Foo>> fooFooFoo;
+                Bar<Foo, Foo> barFooFoo;
+            }
+            class Foo<T> {}
+            class Bar<T1, T2> {}
+            """.trimIndent()
+        )
+        runProcessorTest(sources = listOf(src)) { invocation ->
+            fun assertHasTypeName(type: XType, expectedTypeName: String) {
+                assertThat(type.asTypeName().java.toString()).isEqualTo(expectedTypeName)
+                if (invocation.isKsp) {
+                    assertThat(type.asTypeName().kotlin.toString()).isEqualTo(expectedTypeName)
+                }
+            }
+
+            val subject = invocation.processingEnv.requireTypeElement("test.Subject")
+            assertHasTypeName(subject.getDeclaredField("foo").type, "test.Foo")
+            assertHasTypeName(subject.getDeclaredField("fooFoo").type, "test.Foo<test.Foo>")
+            assertHasTypeName(
+                subject.getDeclaredField("fooFooFoo").type, "test.Foo<test.Foo<test.Foo>>")
+            assertHasTypeName(
+                subject.getDeclaredField("barFooFoo").type, "test.Bar<test.Foo, test.Foo>")
+
+            // Test manually wrapping raw type using XProcessingEnv#getDeclaredType()
+            subject.getDeclaredField("foo").type.let { foo ->
+                val fooTypeElement = invocation.processingEnv.requireTypeElement("test.Foo")
+                val fooFoo: XType = invocation.processingEnv.getDeclaredType(fooTypeElement, foo)
+                assertHasTypeName(fooFoo, "test.Foo<test.Foo>")
+
+                val fooFooFoo: XType =
+                    invocation.processingEnv.getDeclaredType(fooTypeElement, fooFoo)
+                assertHasTypeName(fooFooFoo, "test.Foo<test.Foo<test.Foo>>")
+
+                val barTypeElement = invocation.processingEnv.requireTypeElement("test.Bar")
+                val barFooFoo: XType =
+                    invocation.processingEnv.getDeclaredType(barTypeElement, foo, foo)
+                assertHasTypeName(barFooFoo, "test.Bar<test.Foo, test.Foo>")
+            }
+
+            // Test manually unwrapping a type with a raw type argument:
+            subject.getDeclaredField("fooFoo").type.let { fooFoo ->
+                assertHasTypeName(fooFoo.typeArguments.single(), "test.Foo")
+            }
+            subject.getDeclaredField("barFooFoo").type.let { barFooFoo ->
+                assertThat(barFooFoo.typeArguments).hasSize(2)
+                assertHasTypeName(barFooFoo.typeArguments[0], "test.Foo")
+                assertHasTypeName(barFooFoo.typeArguments[1], "test.Foo")
+            }
+        }
+    }
+
+    @Test
     fun hasAnnotationWithPackage() {
         val kotlinSrc = Source.kotlin(
             "KotlinClass.kt",
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
index 2cf13ff..db85cce 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
@@ -181,6 +181,7 @@
                 typealias MySuspendLambdaAlias5 = suspend (List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>
                 typealias MySuspendLambdaAlias6 = suspend (List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>
                 typealias MySuspendLambdaAlias7 = suspend (List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>
+                typealias MySuspendLambdaAlias8 = List<suspend (List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>>
                 typealias JSW = JvmSuppressWildcards
                 typealias JW = JvmWildcard
                 typealias MyLambdaTypeAlias = (@JvmWildcard MyType) -> @JvmWildcard MyType
@@ -378,6 +379,18 @@
                         fun method58(
                             param: MyGeneric<out MyGenericOut<MyGenericOut<MyInterface>>>
                         ): MyGeneric<out MyGenericOut<MyGenericOut<MyInterface>>> = TODO()
+                        fun method59(
+                            param: MyGeneric<suspend () -> Unit>
+                        ): MyGeneric<suspend () -> Unit> = TODO()
+                        fun method60(
+                            param: MyGenericIn<suspend () -> Unit>
+                        ): MyGenericIn<suspend () -> Unit> = TODO()
+                        fun method61(
+                            param: MyGenericOut<suspend () -> Unit>
+                        ): MyGenericOut<suspend () -> Unit> = TODO()
+                        fun method62(
+                            param: MyGenericOut<suspend (MyGenericOut<suspend () -> Unit>) -> MyGenericOut<suspend () -> Unit>>
+                        ): MyGenericOut<suspend (MyGenericOut<suspend () -> Unit>) -> MyGenericOut<suspend () -> Unit>> = TODO()
                     }
                 """.trimIndent()
             ), listOf("Subject")
@@ -570,6 +583,7 @@
                     fun suspendLambda5(param: MySuspendLambdaAlias5): MySuspendLambdaAlias5 = TODO()
                     fun suspendLambda6(param: MySuspendLambdaAlias6): MySuspendLambdaAlias6 = TODO()
                     fun suspendLambda7(param: MySuspendLambdaAlias7): MySuspendLambdaAlias7 = TODO()
+                    fun suspendLambda8(param: MySuspendLambdaAlias8): MySuspendLambdaAlias8 = TODO()
                     @JSW fun suspendLambda1WithJSW(param: MySuspendLambdaAlias1): MySuspendLambdaAlias1 = TODO()
                     @JSW fun suspendLambda2WithJSW(param: MySuspendLambdaAlias2): MySuspendLambdaAlias2 = TODO()
                     @JSW fun suspendLambda3WithJSW(param: MySuspendLambdaAlias3): MySuspendLambdaAlias3 = TODO()
@@ -577,6 +591,7 @@
                     @JSW fun suspendLambda5WithJSW(param: MySuspendLambdaAlias5): MySuspendLambdaAlias5 = TODO()
                     @JSW fun suspendLambda6WithJSW(param: MySuspendLambdaAlias6): MySuspendLambdaAlias6 = TODO()
                     @JSW fun suspendLambda7WithJSW(param: MySuspendLambdaAlias7): MySuspendLambdaAlias7 = TODO()
+                    @JSW fun suspendLambda8WithJSW(param: MySuspendLambdaAlias8): MySuspendLambdaAlias8 = TODO()
                 }
                 """.trimIndent()
             ), listOf(className)
diff --git a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt b/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
index 57e13f0..149b5f5 100644
--- a/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
+++ b/room/room-runtime-lint/src/main/java/androidx/room/lint/CursorKotlinUseIssueDetector.kt
@@ -16,8 +16,7 @@
 
 package androidx.room.lint
 
-import com.android.tools.lint.checks.VersionChecks.Companion.isPrecededByVersionCheckExit
-import com.android.tools.lint.checks.VersionChecks.Companion.isWithinVersionCheckConditional
+import com.android.tools.lint.detector.api.ApiConstraint
 import com.android.tools.lint.detector.api.Category
 import com.android.tools.lint.detector.api.Detector
 import com.android.tools.lint.detector.api.Implementation
@@ -64,10 +63,8 @@
         }
         // If the call is within an SDK_INT check, then its OK
         if (
-            @Suppress("DEPRECATION") // b/262915639
-            VersionChecks.isWithinVersionCheckConditional(context, node, 16) ||
-            @Suppress("DEPRECATION") // b/262915639
-            VersionChecks.isPrecededByVersionCheckExit(context, node, 16)
+            VersionChecks.isWithinVersionCheckConditional(context, node, ApiConstraint.get(16)) ||
+            VersionChecks.isPrecededByVersionCheckExit(context, node, ApiConstraint.get(16))
         ) {
             return
         }
diff --git a/room/room-rxjava2/lint-baseline.xml b/room/room-rxjava2/lint-baseline.xml
index 02e92c5..656b9b3 100644
--- a/room/room-rxjava2/lint-baseline.xml
+++ b/room/room-rxjava2/lint-baseline.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
-
     <issue
         id="UnknownNullness"
         message="Unknown nullability; explicitly declare as `@Nullable` or `@NonNull` to improve Kotlin interoperability; see https://developer.android.com/kotlin/interop#nullability_annotations"
diff --git a/samples/MediaRoutingDemo/src/main/AndroidManifest.xml b/samples/MediaRoutingDemo/src/main/AndroidManifest.xml
index 25e7453..bb037aa 100644
--- a/samples/MediaRoutingDemo/src/main/AndroidManifest.xml
+++ b/samples/MediaRoutingDemo/src/main/AndroidManifest.xml
@@ -41,6 +41,7 @@
             android:label="@string/main_activity_label">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.media.action.TRANSFER_MEDIA"/>
                 <category android:name="com.example.androidx.SAMPLE_CODE" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -68,6 +69,17 @@
             </intent-filter>
         </activity>
 
+        <activity
+            android:name=".activities.RouteListingPreferenceActivity"
+            android:configChanges="orientation|screenSize"
+            android:exported="false"
+            android:label="Route Listing Preference">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.androidx.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".activities.systemrouting.SystemRoutingActivity"
             android:exported="false" />
 
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/RoutesManager.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/RoutesManager.java
index 7e69d77..f4d1b6f 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/RoutesManager.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/RoutesManager.java
@@ -23,17 +23,23 @@
 import static com.example.androidx.mediarouting.data.RouteItem.PlaybackType.REMOTE;
 import static com.example.androidx.mediarouting.data.RouteItem.VolumeHandling.VARIABLE;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.core.os.BuildCompat;
 import androidx.mediarouter.media.MediaRouter;
 import androidx.mediarouter.media.MediaRouterParams;
+import androidx.mediarouter.media.RouteListingPreference;
 
+import com.example.androidx.mediarouting.activities.MainActivity;
 import com.example.androidx.mediarouting.data.RouteItem;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -42,6 +48,7 @@
 public final class RoutesManager {
 
     private static final String VARIABLE_VOLUME_BASIC_ROUTE_ID = "variable_basic";
+    private static final String SENDER_DRIVEN_BASIC_ROUTE_ID = "sender_driven_route";
     private static final int VOLUME_MAX = 25;
     private static final int VOLUME_DEFAULT = 5;
 
@@ -51,12 +58,18 @@
     private final Map<String, RouteItem> mRouteItems;
     private boolean mDynamicRoutingEnabled;
     private DialogType mDialogType;
+    private final MediaRouter mMediaRouter;
+    private boolean mRouteListingPreferenceEnabled;
+    private boolean mRouteListingSystemOrderingPreferred;
+    private List<RouteListingPreferenceItemHolder> mRouteListingPreferenceItems;
 
     private RoutesManager(Context context) {
         mContext = context;
         mDynamicRoutingEnabled = true;
         mDialogType = DialogType.OUTPUT_SWITCHER;
         mRouteItems = new HashMap<>();
+        mRouteListingPreferenceItems = Collections.emptyList();
+        mMediaRouter = MediaRouter.getInstance(context);
         initTestRoutes();
     }
 
@@ -113,6 +126,76 @@
         mRouteItems.put(routeItem.getId(), routeItem);
     }
 
+    /**
+     * Returns whether route listing preference is enabled.
+     *
+     * @see #setRouteListingPreferenceEnabled
+     */
+    public boolean isRouteListingPreferenceEnabled() {
+        return mRouteListingPreferenceEnabled;
+    }
+
+    /**
+     * Sets whether the use of route listing preference is enabled or not.
+     *
+     * <p>If route listing preference is enabled, the route listing preference configuration for
+     * this app is maintained following the item list provided via {@link
+     * #setRouteListingPreferenceItems}. Otherwise, if route listing preference is disabled, the
+     * route listing preference for this app is set to null.
+     *
+     * <p>Does not affect the system's state if called on a device running API 33 or older.
+     */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    public void setRouteListingPreferenceEnabled(boolean routeListingPreferenceEnabled) {
+        mRouteListingPreferenceEnabled = routeListingPreferenceEnabled;
+        onRouteListingPreferenceChanged();
+    }
+
+    /** Returns whether the system ordering for route listing is preferred. */
+    public boolean getRouteListingSystemOrderingPreferred() {
+        return mRouteListingSystemOrderingPreferred;
+    }
+
+    /**
+     * Sets whether to prefer the system ordering for route listing.
+     *
+     * <p>True means that the ordering for route listing is the one in the {@link #getRouteItems()}
+     * list. If false, the ordering of said list is ignored, and the system uses its builtin
+     * ordering for the items.
+     *
+     * <p>Does not affect the system's state if called on a device running API 33 or older.
+     */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    public void setRouteListingSystemOrderingPreferred(
+            boolean routeListingSystemOrderringPreferred) {
+            mRouteListingSystemOrderingPreferred = routeListingSystemOrderringPreferred;
+        onRouteListingPreferenceChanged();
+    }
+
+    /**
+     * The current list of route listing preference items, as set via {@link
+     * #setRouteListingPreferenceItems}.
+     */
+    @NonNull
+    public List<RouteListingPreferenceItemHolder> getRouteListingPreferenceItems() {
+        return mRouteListingPreferenceItems;
+    }
+
+    /**
+     * Sets the route listing preference items.
+     *
+     * <p>Does not affect the system's state if called on a device running API 33 or older.
+     *
+     * @see #setRouteListingPreferenceEnabled
+     */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    public void setRouteListingPreferenceItems(
+            @NonNull List<RouteListingPreferenceItemHolder> preference) {
+            mRouteListingPreferenceItems =
+                    Collections.unmodifiableList(new ArrayList<>(preference));
+        onRouteListingPreferenceChanged();
+    }
+
     /** Changes the media router dialog type with the type stored in {@link RoutesManager} */
     public void reloadDialogType() {
         MediaRouter mediaRouter = MediaRouter.getInstance(mContext.getApplicationContext());
@@ -191,10 +274,58 @@
         r4.setVolume(VOLUME_DEFAULT);
         r4.setCanDisconnect(true);
 
+        RouteItem r5 = new RouteItem();
+        r5.setId(SENDER_DRIVEN_BASIC_ROUTE_ID + "1");
+        r5.setName(r.getString(R.string.sender_driven_route_name1));
+        r5.setDescription(r.getString(R.string.sample_route_description));
+        r5.setControlFilter(BASIC);
+        r5.setDeviceType(TV);
+        r5.setPlaybackStream(MUSIC);
+        r5.setPlaybackType(REMOTE);
+        r5.setVolumeHandling(VARIABLE);
+        r5.setVolumeMax(VOLUME_MAX);
+        r5.setVolume(VOLUME_DEFAULT);
+        r5.setCanDisconnect(true);
+        r5.setSenderDriven(true);
+
+        RouteItem r6 = new RouteItem();
+        r6.setId(SENDER_DRIVEN_BASIC_ROUTE_ID + "2");
+        r6.setName(r.getString(R.string.sender_driven_route_name2));
+        r6.setDescription(r.getString(R.string.sample_route_description));
+        r6.setControlFilter(BASIC);
+        r6.setDeviceType(TV);
+        r6.setPlaybackStream(MUSIC);
+        r6.setPlaybackType(REMOTE);
+        r6.setVolumeHandling(VARIABLE);
+        r6.setVolumeMax(VOLUME_MAX);
+        r6.setVolume(VOLUME_DEFAULT);
+        r6.setCanDisconnect(true);
+        r6.setSenderDriven(true);
+
         mRouteItems.put(r1.getId(), r1);
         mRouteItems.put(r2.getId(), r2);
         mRouteItems.put(r3.getId(), r3);
         mRouteItems.put(r4.getId(), r4);
+        mRouteItems.put(r5.getId(), r5);
+        mRouteItems.put(r6.getId(), r6);
+    }
+
+    private void onRouteListingPreferenceChanged() {
+        RouteListingPreference routeListingPreference = null;
+        if (mRouteListingPreferenceEnabled) {
+            ArrayList<RouteListingPreference.Item> items = new ArrayList<>();
+            for (RouteListingPreferenceItemHolder item : mRouteListingPreferenceItems) {
+                items.add(item.mItem);
+            }
+            routeListingPreference =
+                    new RouteListingPreference.Builder()
+                            .setItems(items)
+                            .setLinkedItemComponentName(
+                                    new ComponentName(mContext, MainActivity.class))
+                            .setUseSystemOrdering(mRouteListingSystemOrderingPreferred)
+                            .build();
+        }
+        mMediaRouter.setRouteListingPreference(routeListingPreference);
     }
 
     public enum DialogType {
@@ -202,4 +333,38 @@
         DYNAMIC_GROUP,
         OUTPUT_SWITCHER
     }
+
+    /**
+     * Holds a {@link RouteListingPreference.Item} and the associated route's name.
+     *
+     * <p>Convenient pair-like class for populating UI elements, ensuring we have an associated
+     * route name for each route listing preference item even after the corresponding route no
+     * longer exists.
+     */
+    public static final class RouteListingPreferenceItemHolder {
+
+        @NonNull public final RouteListingPreference.Item mItem;
+        @NonNull public final String mRouteName;
+
+        public RouteListingPreferenceItemHolder(
+                @NonNull RouteListingPreference.Item item, @NonNull String routeName) {
+            mItem = item;
+            mRouteName = routeName;
+        }
+
+        /** Returns the name of the corresponding route. */
+        @Override
+        @NonNull
+        public String toString() {
+            return mRouteName;
+        }
+
+        /**
+         * Returns whether the contained {@link RouteListingPreference.Item} has the given {@code
+         * flag} set.
+         */
+        public boolean hasFlag(int flag) {
+            return (mItem.getFlags() & flag) == flag;
+        }
+    }
 }
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/AddEditRouteActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/AddEditRouteActivity.java
index 7741f9f..aed9f13 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/AddEditRouteActivity.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/AddEditRouteActivity.java
@@ -16,6 +16,8 @@
 
 package com.example.androidx.mediarouting.activities;
 
+import static com.example.androidx.mediarouting.ui.UiUtils.setUpEnumBasedSpinner;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,17 +26,14 @@
 import android.os.IBinder;
 import android.text.Editable;
 import android.text.TextWatcher;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.EditText;
-import android.widget.Spinner;
 import android.widget.Switch;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.util.Consumer;
 
 import com.example.androidx.mediarouting.R;
 import com.example.androidx.mediarouting.RoutesManager;
@@ -49,7 +48,6 @@
     private ServiceConnection mConnection;
     private RoutesManager mRoutesManager;
     private RouteItem mRouteItem;
-    private Switch mCanDisconnectSwitch;
 
     /** Launches the activity. */
     public static void launchActivity(@NonNull Context context, @Nullable String routeId) {
@@ -75,8 +73,6 @@
             mRouteItem = RouteItem.copyOf(mRouteItem);
         }
 
-        mCanDisconnectSwitch = findViewById(R.id.cam_disconnect_switch);
-
         setUpViews();
     }
 
@@ -149,19 +145,19 @@
                 String.valueOf(mRouteItem.getVolumeMax()),
                 mewVolumeMax -> mRouteItem.setVolumeMax(Integer.parseInt(mewVolumeMax)));
 
-        setUpCanDisconnectSwitch();
+        setUpSwitch(
+                findViewById(R.id.can_disconnect_switch),
+                mRouteItem.isCanDisconnect(),
+                newValue -> mRouteItem.setCanDisconnect(newValue));
+
+        setUpSwitch(
+                findViewById(R.id.is_sender_driven_switch),
+                mRouteItem.isSenderDriven(),
+                newValue -> mRouteItem.setSenderDriven(newValue));
 
         setUpSaveButton();
     }
 
-    private void setUpCanDisconnectSwitch() {
-        mCanDisconnectSwitch.setChecked(mRouteItem.isCanDisconnect());
-        mCanDisconnectSwitch.setOnCheckedChangeListener(
-                (compoundButton, b) -> {
-                    mRouteItem.setCanDisconnect(b);
-                });
-    }
-
     private void setUpSaveButton() {
         Button saveButton = findViewById(R.id.save_button);
         saveButton.setOnClickListener(
@@ -172,10 +168,14 @@
                 });
     }
 
+    private static void setUpSwitch(Switch switchWidget, boolean currentValue,
+            Consumer<Boolean> propertySetter) {
+        switchWidget.setChecked(currentValue);
+        switchWidget.setOnCheckedChangeListener((compoundButton, b) -> propertySetter.accept(b));
+    }
+
     private static void setUpEditText(
-            EditText editText,
-            String currentValue,
-            RoutePropertySetter<String> routePropertySetter) {
+            EditText editText, String currentValue, Consumer<String> propertySetter) {
         editText.setText(currentValue);
         editText.addTextChangedListener(
                 new TextWatcher() {
@@ -185,7 +185,7 @@
 
                     @Override
                     public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
-                        routePropertySetter.accept(charSequence.toString());
+                        propertySetter.accept(charSequence.toString());
                     }
 
                     @Override
@@ -193,36 +193,6 @@
                 });
     }
 
-    private static void setUpEnumBasedSpinner(
-            Context context,
-            Spinner spinner,
-            Enum<?> anEnum,
-            RoutePropertySetter<Enum<?>> routePropertySetter) {
-        Enum<?>[] enumValues = anEnum.getDeclaringClass().getEnumConstants();
-        ArrayAdapter<Enum<?>> adapter =
-                new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, enumValues);
-        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        spinner.setAdapter(adapter);
-        spinner.setSelection(anEnum.ordinal());
-
-        spinner.setOnItemSelectedListener(
-                new AdapterView.OnItemSelectedListener() {
-                    @Override
-                    public void onItemSelected(
-                            AdapterView<?> adapterView, View view, int i, long l) {
-                        routePropertySetter.accept(
-                                anEnum.getDeclaringClass().getEnumConstants()[i]);
-                    }
-
-                    @Override
-                    public void onNothingSelected(AdapterView<?> adapterView) {}
-                });
-    }
-
-    private interface RoutePropertySetter<T> {
-        void accept(T value);
-    }
-
     private class ProviderServiceConnection implements ServiceConnection {
 
         @Override
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
index 3558f3a..9247677 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/MainActivity.java
@@ -45,6 +45,7 @@
 import android.widget.TabHost;
 import android.widget.TabHost.TabSpec;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import androidx.annotation.DoNotInline;
 import androidx.annotation.NonNull;
@@ -66,6 +67,7 @@
 import androidx.mediarouter.media.MediaRouter.ProviderInfo;
 import androidx.mediarouter.media.MediaRouter.RouteInfo;
 import androidx.mediarouter.media.MediaRouterParams;
+import androidx.mediarouter.media.RouteListingPreference;
 
 import com.example.androidx.mediarouting.MyMediaRouteControllerDialog;
 import com.example.androidx.mediarouting.R;
@@ -82,6 +84,7 @@
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.io.File;
+import java.util.List;
 
 /**
  * Demonstrates how to use the {@link MediaRouter} API to build an application that allows the user
@@ -269,6 +272,10 @@
         mSessionManager.setCallback(new SampleSessionManagerCallback());
 
         updateUi();
+
+        if (RouteListingPreference.ACTION_TRANSFER_MEDIA.equals(getIntent().getAction())) {
+            showMediaTransferToast();
+        }
     }
 
     @Override
@@ -333,6 +340,26 @@
         requestPostNotificationsPermission();
     }
 
+    private void showMediaTransferToast() {
+        String routeId = getIntent().getStringExtra(RouteListingPreference.EXTRA_ROUTE_ID);
+        List<RouteInfo> routes = mMediaRouter.getRoutes();
+        String requestedRouteName = null;
+        for (RouteInfo route : routes) {
+            if (route.getId().equals(routeId)) {
+                requestedRouteName = route.getName();
+                break;
+            }
+        }
+        String stringToDisplay =
+                requestedRouteName != null
+                        ? "Transfer requested to " + requestedRouteName
+                        : "Transfer requested to unknown route: " + routeId;
+
+        // TODO(b/266561322): Replace the toast with a Dialog that allows the user to either
+        // transfer playback to the requested route, or dismiss the intent.
+        Toast.makeText(/* context= */ this, stringToDisplay, Toast.LENGTH_LONG).show();
+    }
+
     private void requestDisplayOverOtherAppsPermission() {
         // Need overlay permission for emulating remote display.
         if (Build.VERSION.SDK_INT >= 23 && !Api23Impl.canDrawOverlays(this)) {
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/RouteListingPreferenceActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/RouteListingPreferenceActivity.java
new file mode 100644
index 0000000..308d3c8
--- /dev/null
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/RouteListingPreferenceActivity.java
@@ -0,0 +1,478 @@
+/*
+ * 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 com.example.androidx.mediarouting.activities;
+
+import static androidx.mediarouter.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION;
+import static androidx.mediarouter.media.RouteListingPreference.Item.FLAG_ONGOING_SESSION_MANAGED;
+import static androidx.mediarouter.media.RouteListingPreference.Item.FLAG_SUGGESTED;
+import static androidx.mediarouter.media.RouteListingPreference.Item.SUBTEXT_CUSTOM;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.os.BuildCompat;
+import androidx.mediarouter.media.MediaRouter;
+import androidx.mediarouter.media.RouteListingPreference;
+import androidx.recyclerview.widget.ItemTouchHelper;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.example.androidx.mediarouting.R;
+import com.example.androidx.mediarouting.RoutesManager;
+import com.example.androidx.mediarouting.RoutesManager.RouteListingPreferenceItemHolder;
+import com.example.androidx.mediarouting.ui.UiUtils;
+import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/** Allows the user to manage the route listing preference of this app. */
+public class RouteListingPreferenceActivity extends AppCompatActivity {
+
+    private RoutesManager mRoutesManager;
+    private RecyclerView mRouteListingPreferenceRecyclerView;
+
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (!BuildCompat.isAtLeastU()) {
+            Toast.makeText(
+                            /* context= */ this,
+                            "Route Listing Preference requires Android U+",
+                            Toast.LENGTH_LONG)
+                    .show();
+            finish();
+            return;
+        }
+
+        setContentView(R.layout.activity_route_listing_preference);
+
+        mRoutesManager = RoutesManager.getInstance(/* context= */ this);
+
+        Switch preferSystemOrderingSwitch = findViewById(R.id.prefer_system_ordering_switch);
+        preferSystemOrderingSwitch.setChecked(
+                mRoutesManager.getRouteListingSystemOrderingPreferred());
+        preferSystemOrderingSwitch.setOnCheckedChangeListener(
+                (unusedButton, isChecked) -> {
+                    mRoutesManager.setRouteListingSystemOrderingPreferred(isChecked);
+                });
+        preferSystemOrderingSwitch.setEnabled(mRoutesManager.isRouteListingPreferenceEnabled());
+
+        Switch enableRouteListingPreferenceSwitch =
+                findViewById(R.id.enable_route_listing_preference_switch);
+        enableRouteListingPreferenceSwitch.setChecked(
+                mRoutesManager.isRouteListingPreferenceEnabled());
+        enableRouteListingPreferenceSwitch.setOnCheckedChangeListener(
+                (unusedButton, isChecked) -> {
+                    mRoutesManager.setRouteListingPreferenceEnabled(isChecked);
+                    preferSystemOrderingSwitch.setEnabled(isChecked);
+                });
+
+        mRouteListingPreferenceRecyclerView =
+                findViewById(R.id.route_listing_preference_recycler_view);
+        new ItemTouchHelper(new RecyclerViewCallback())
+                .attachToRecyclerView(mRouteListingPreferenceRecyclerView);
+        mRouteListingPreferenceRecyclerView.setLayoutManager(
+                new LinearLayoutManager(/* context= */ this));
+        mRouteListingPreferenceRecyclerView.setHasFixedSize(true);
+        mRouteListingPreferenceRecyclerView.setAdapter(
+                new RouteListingPreferenceRecyclerViewAdapter());
+
+        FloatingActionButton newRouteButton =
+                findViewById(R.id.new_route_listing_preference_item_button);
+        newRouteButton.setOnClickListener(
+                view ->
+                        setUpRouteListingPreferenceItemEditionDialog(
+                                mRoutesManager.getRouteListingPreferenceItems().size()));
+    }
+
+    private void setUpRouteListingPreferenceItemEditionDialog(int itemPositionInList) {
+        List<RouteListingPreferenceItemHolder> routeListingPreference =
+                mRoutesManager.getRouteListingPreferenceItems();
+        List<MediaRouter.RouteInfo> routesWithNoAssociatedListingPreferenceItem =
+                getRoutesWithNoAssociatedListingPreferenceItem();
+        if (itemPositionInList == routeListingPreference.size()
+                && routesWithNoAssociatedListingPreferenceItem.isEmpty()) {
+            Toast.makeText(/* context= */ this, "No (more) routes available", Toast.LENGTH_LONG)
+                    .show();
+            return;
+        }
+        View dialogView =
+                getLayoutInflater()
+                        .inflate(R.layout.route_listing_preference_item_dialog, /* root= */ null);
+
+        Spinner routeSpinner = dialogView.findViewById(R.id.rlp_item_dialog_route_name_spinner);
+        List<RouteListingPreferenceItemHolder> spinnerEntries = new ArrayList<>();
+
+        Spinner selectionBehaviorSpinner =
+                dialogView.findViewById(R.id.rlp_item_dialog_selection_behavior_spinner);
+        UiUtils.setUpEnumBasedSpinner(
+                /* context= */ this,
+                selectionBehaviorSpinner,
+                RouteListingPreferenceItemSelectionBehavior.SELECTION_BEHAVIOR_TRANSFER,
+                (unused) -> {});
+
+        CheckBox ongoingSessionCheckBox =
+                dialogView.findViewById(R.id.rlp_item_dialog_ongoing_session_checkbox);
+        CheckBox sessionManagedCheckBox =
+                dialogView.findViewById(R.id.rlp_item_dialog_session_managed_checkbox);
+        CheckBox suggestedRouteCheckBox =
+                dialogView.findViewById(R.id.rlp_item_dialog_suggested_checkbox);
+
+        Spinner subtextSpinner = dialogView.findViewById(R.id.rlp_item_dialog_subtext_spinner);
+        UiUtils.setUpEnumBasedSpinner(
+                /* context= */ this,
+                subtextSpinner,
+                RouteListingPreferenceItemSubtext.SUBTEXT_NONE,
+                (unused) -> {});
+
+        if (itemPositionInList < routeListingPreference.size()) {
+            RouteListingPreferenceItemHolder itemHolder =
+                    routeListingPreference.get(itemPositionInList);
+            spinnerEntries.add(itemHolder);
+            int selectionBehaviorOrdinalIndex =
+                    RouteListingPreferenceItemSelectionBehavior.fromConstant(
+                                    itemHolder.mItem.getSelectionBehavior())
+                            .ordinal();
+            selectionBehaviorSpinner.setSelection(selectionBehaviorOrdinalIndex);
+            ongoingSessionCheckBox.setChecked(itemHolder.hasFlag(FLAG_ONGOING_SESSION));
+            sessionManagedCheckBox.setChecked(itemHolder.hasFlag(FLAG_ONGOING_SESSION_MANAGED));
+            suggestedRouteCheckBox.setChecked(itemHolder.hasFlag(FLAG_SUGGESTED));
+            int subtextOrdinalIndex =
+                    RouteListingPreferenceItemSubtext.fromConstant(itemHolder.mItem.getSubText())
+                            .ordinal();
+            subtextSpinner.setSelection(subtextOrdinalIndex);
+        }
+        for (MediaRouter.RouteInfo routeInfo : routesWithNoAssociatedListingPreferenceItem) {
+            spinnerEntries.add(
+                    new RouteListingPreferenceItemHolder(
+                            new RouteListingPreference.Item.Builder(routeInfo.getId()).build(),
+                            routeInfo.getName()));
+        }
+        routeSpinner.setAdapter(
+                new ArrayAdapter<>(
+                        /* context= */ this, android.R.layout.simple_spinner_item, spinnerEntries));
+
+        AlertDialog editRlpItemDialog =
+                new AlertDialog.Builder(this)
+                        .setView(dialogView)
+                        .setPositiveButton(
+                                "Accept",
+                                (unusedDialog, unusedWhich) -> {
+                                    RouteListingPreferenceItemHolder item =
+                                            (RouteListingPreferenceItemHolder)
+                                                    routeSpinner.getSelectedItem();
+                                    RouteListingPreferenceItemSelectionBehavior selectionBehavior =
+                                            (RouteListingPreferenceItemSelectionBehavior)
+                                                    selectionBehaviorSpinner.getSelectedItem();
+                                    int flags = 0;
+                                    flags |=
+                                            ongoingSessionCheckBox.isChecked()
+                                                    ? FLAG_ONGOING_SESSION
+                                                    : 0;
+                                    flags |=
+                                            sessionManagedCheckBox.isChecked()
+                                                    ? FLAG_ONGOING_SESSION_MANAGED
+                                                    : 0;
+                                    flags |=
+                                            suggestedRouteCheckBox.isChecked() ? FLAG_SUGGESTED : 0;
+                                    RouteListingPreferenceItemSubtext subtext =
+                                            (RouteListingPreferenceItemSubtext)
+                                                    subtextSpinner.getSelectedItem();
+                                    onEditRlpItemDialogAccepted(
+                                            item.mItem.getRouteId(),
+                                            item.mRouteName,
+                                            selectionBehavior.mConstant,
+                                            flags,
+                                            subtext.mConstant,
+                                            itemPositionInList);
+                                })
+                        .setNegativeButton("Dismiss", (unusedDialog, unusedWhich) -> {})
+                        .create();
+
+        editRlpItemDialog.show();
+    }
+
+    private void onEditRlpItemDialogAccepted(
+            String routeId,
+            String routeName,
+            int selectionBehavior,
+            int flags,
+            int subtext,
+            int itemPositionInList) {
+        ArrayList<RouteListingPreferenceItemHolder> newRouteListingPreference =
+                new ArrayList<>(mRoutesManager.getRouteListingPreferenceItems());
+        RecyclerView.Adapter<?> adapter = mRouteListingPreferenceRecyclerView.getAdapter();
+        RouteListingPreference.Item.Builder newItemBuilder =
+                new RouteListingPreference.Item.Builder(routeId)
+                        .setFlags(flags)
+                        .setSelectionBehavior(selectionBehavior)
+                        .setSubText(subtext);
+        if (subtext == SUBTEXT_CUSTOM) {
+            newItemBuilder.setCustomSubtextMessage("A custom subtext");
+        }
+        RouteListingPreference.Item newItem = newItemBuilder.build();
+        RouteListingPreferenceItemHolder newItemAndNamePair =
+                new RouteListingPreferenceItemHolder(newItem, routeName);
+        if (itemPositionInList < newRouteListingPreference.size()) {
+            newRouteListingPreference.set(itemPositionInList, newItemAndNamePair);
+            adapter.notifyItemChanged(itemPositionInList);
+        } else {
+            newRouteListingPreference.add(newItemAndNamePair);
+            adapter.notifyItemInserted(itemPositionInList);
+        }
+        mRoutesManager.setRouteListingPreferenceItems(newRouteListingPreference);
+    }
+
+    @NonNull
+    private ImmutableList<MediaRouter.RouteInfo> getRoutesWithNoAssociatedListingPreferenceItem() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            return ImmutableList.of();
+        }
+        Set<String> routesWithAssociatedRouteListingPreferenceItem = new HashSet<>();
+        for (RouteListingPreferenceItemHolder element :
+                mRoutesManager.getRouteListingPreferenceItems()) {
+            String routeId = element.mItem.getRouteId();
+            routesWithAssociatedRouteListingPreferenceItem.add(routeId);
+        }
+
+        ImmutableList.Builder<MediaRouter.RouteInfo> resultBuilder = ImmutableList.builder();
+        for (MediaRouter.RouteInfo route : MediaRouter.getInstance(this).getRoutes()) {
+            if (!routesWithAssociatedRouteListingPreferenceItem.contains(route.getId())) {
+                resultBuilder.add(route);
+            }
+        }
+        return resultBuilder.build();
+    }
+
+    private class RecyclerViewCallback extends ItemTouchHelper.SimpleCallback {
+
+        private static final int INDEX_UNSET = -1;
+
+        private int mDraggingFromPosition;
+        private int mDraggingToPosition;
+
+        private RecyclerViewCallback() {
+            super(
+                    ItemTouchHelper.UP | ItemTouchHelper.DOWN,
+                    ItemTouchHelper.START | ItemTouchHelper.END);
+            mDraggingFromPosition = INDEX_UNSET;
+            mDraggingToPosition = INDEX_UNSET;
+        }
+
+        @Override
+        public boolean onMove(
+                @NonNull RecyclerView recyclerView,
+                @NonNull RecyclerView.ViewHolder origin,
+                @NonNull RecyclerView.ViewHolder target) {
+            int fromPosition = origin.getBindingAdapterPosition();
+            int toPosition = target.getBindingAdapterPosition();
+            if (mDraggingFromPosition == INDEX_UNSET) {
+                // A drag has started, but we wait for the clearView() call to update the route
+                // listing preference.
+                mDraggingFromPosition = fromPosition;
+            }
+            mDraggingToPosition = toPosition;
+            recyclerView.getAdapter().notifyItemMoved(fromPosition, toPosition);
+            return false;
+        }
+
+        @Override
+        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
+            ArrayList<RouteListingPreferenceItemHolder> newRouteListingPreference =
+                    new ArrayList<>(mRoutesManager.getRouteListingPreferenceItems());
+            int itemPosition = viewHolder.getBindingAdapterPosition();
+            newRouteListingPreference.remove(itemPosition);
+            mRoutesManager.setRouteListingPreferenceItems(newRouteListingPreference);
+            viewHolder.getBindingAdapter().notifyItemRemoved(itemPosition);
+        }
+
+        @Override
+        public void clearView(
+                @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
+            super.clearView(recyclerView, viewHolder);
+            if (mDraggingFromPosition != INDEX_UNSET) {
+                ArrayList<RouteListingPreferenceItemHolder> newRouteListingPreference =
+                        new ArrayList<>(mRoutesManager.getRouteListingPreferenceItems());
+                newRouteListingPreference.add(
+                        mDraggingToPosition,
+                        newRouteListingPreference.remove(mDraggingFromPosition));
+                mRoutesManager.setRouteListingPreferenceItems(newRouteListingPreference);
+            }
+            mDraggingFromPosition = INDEX_UNSET;
+            mDraggingToPosition = INDEX_UNSET;
+        }
+    }
+
+    private class RouteListingPreferenceRecyclerViewAdapter
+            extends RecyclerView.Adapter<RecyclerViewItemViewHolder> {
+        @NonNull
+        @Override
+        public RecyclerViewItemViewHolder onCreateViewHolder(
+                @NonNull ViewGroup parent, int viewType) {
+            TextView textView =
+                    (TextView)
+                            LayoutInflater.from(parent.getContext())
+                                    .inflate(
+                                            android.R.layout.simple_list_item_1,
+                                            parent,
+                                            /* attachToRoot= */ false);
+            return new RecyclerViewItemViewHolder(textView);
+        }
+
+        @Override
+        public void onBindViewHolder(@NonNull RecyclerViewItemViewHolder holder, int position) {
+            holder.mTextView.setText(
+                    mRoutesManager.getRouteListingPreferenceItems().get(position).mRouteName);
+        }
+
+        @Override
+        public int getItemCount() {
+            return mRoutesManager.getRouteListingPreferenceItems().size();
+        }
+    }
+
+    private class RecyclerViewItemViewHolder extends RecyclerView.ViewHolder
+            implements View.OnClickListener {
+
+        public final TextView mTextView;
+
+        private RecyclerViewItemViewHolder(TextView textView) {
+            super(textView);
+            mTextView = textView;
+            textView.setOnClickListener(this);
+        }
+
+        @Override
+        public void onClick(View view) {
+            setUpRouteListingPreferenceItemEditionDialog(getBindingAdapterPosition());
+        }
+    }
+
+    private enum RouteListingPreferenceItemSelectionBehavior {
+        SELECTION_BEHAVIOR_NONE(RouteListingPreference.Item.SELECTION_BEHAVIOR_NONE, "None"),
+        SELECTION_BEHAVIOR_TRANSFER(
+                RouteListingPreference.Item.SELECTION_BEHAVIOR_TRANSFER, "Transfer"),
+        SELECTION_BEHAVIOR_GO_TO_APP(
+                RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP, "Go to app");
+
+        public final int mConstant;
+        public final String mHumanReadableString;
+
+        RouteListingPreferenceItemSelectionBehavior(
+                int constant, @NonNull String humanReadableString) {
+            mConstant = constant;
+            mHumanReadableString = humanReadableString;
+        }
+
+        @NonNull
+        @Override
+        public String toString() {
+            return mHumanReadableString;
+        }
+
+        public static RouteListingPreferenceItemSelectionBehavior fromConstant(int constant) {
+            switch (constant) {
+                case RouteListingPreference.Item.SELECTION_BEHAVIOR_NONE:
+                    return SELECTION_BEHAVIOR_NONE;
+                case RouteListingPreference.Item.SELECTION_BEHAVIOR_TRANSFER:
+                    return SELECTION_BEHAVIOR_TRANSFER;
+                case RouteListingPreference.Item.SELECTION_BEHAVIOR_GO_TO_APP:
+                    return SELECTION_BEHAVIOR_GO_TO_APP;
+                default:
+                    throw new IllegalArgumentException("Illegal selection behavior: " + constant);
+            }
+        }
+    }
+
+    private enum RouteListingPreferenceItemSubtext {
+        SUBTEXT_NONE(RouteListingPreference.Item.SUBTEXT_NONE, "None"),
+        SUBTEXT_ERROR_UNKNOWN(RouteListingPreference.Item.SUBTEXT_ERROR_UNKNOWN, "Unknown error"),
+        SUBTEXT_SUBSCRIPTION_REQUIRED(
+                RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED, "Subscription required"),
+        SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED(
+                RouteListingPreference.Item.SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED,
+                "Downloaded content disallowed"),
+        SUBTEXT_AD_ROUTING_DISALLOWED(
+                RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED, "Ad in progress"),
+        SUBTEXT_DEVICE_LOW_POWER(
+                RouteListingPreference.Item.SUBTEXT_DEVICE_LOW_POWER, "Device in low power mode"),
+        SUBTEXT_UNAUTHORIZED(RouteListingPreference.Item.SUBTEXT_UNAUTHORIZED, "Unauthorized"),
+        SUBTEXT_TRACK_UNSUPPORTED(
+                RouteListingPreference.Item.SUBTEXT_TRACK_UNSUPPORTED, "Track unsupported"),
+        SUBTEXT_CUSTOM(
+                RouteListingPreference.Item.SUBTEXT_CUSTOM, "Custom text (placeholder value)");
+
+        public final int mConstant;
+        @NonNull public final String mHumanReadableString;
+
+        RouteListingPreferenceItemSubtext(int constant, @NonNull String humanReadableString) {
+            mConstant = constant;
+            mHumanReadableString = humanReadableString;
+        }
+
+        @NonNull
+        @Override
+        public String toString() {
+            return mHumanReadableString;
+        }
+
+        public static RouteListingPreferenceItemSubtext fromConstant(int constant) {
+            switch (constant) {
+                case RouteListingPreference.Item.SUBTEXT_NONE:
+                    return SUBTEXT_NONE;
+                case RouteListingPreference.Item.SUBTEXT_ERROR_UNKNOWN:
+                    return SUBTEXT_ERROR_UNKNOWN;
+                case RouteListingPreference.Item.SUBTEXT_SUBSCRIPTION_REQUIRED:
+                    return SUBTEXT_SUBSCRIPTION_REQUIRED;
+                case RouteListingPreference.Item.SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED:
+                    return SUBTEXT_DOWNLOADED_CONTENT_ROUTING_DISALLOWED;
+                case RouteListingPreference.Item.SUBTEXT_AD_ROUTING_DISALLOWED:
+                    return SUBTEXT_AD_ROUTING_DISALLOWED;
+                case RouteListingPreference.Item.SUBTEXT_DEVICE_LOW_POWER:
+                    return SUBTEXT_DEVICE_LOW_POWER;
+                case RouteListingPreference.Item.SUBTEXT_UNAUTHORIZED:
+                    return SUBTEXT_UNAUTHORIZED;
+                case RouteListingPreference.Item.SUBTEXT_TRACK_UNSUPPORTED:
+                    return SUBTEXT_TRACK_UNSUPPORTED;
+                case RouteListingPreference.Item.SUBTEXT_CUSTOM:
+                    return SUBTEXT_CUSTOM;
+                default:
+                    throw new IllegalArgumentException("Illegal subtext constant: " + constant);
+            }
+        }
+    }
+}
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/SettingsActivity.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/SettingsActivity.java
index 42b5973..2db33b8 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/SettingsActivity.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/activities/SettingsActivity.java
@@ -26,6 +26,7 @@
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.Button;
 import android.widget.Spinner;
 import android.widget.Switch;
 
@@ -93,6 +94,13 @@
             }
         };
 
+        Button goToRouteListingPreferenceButton =
+                findViewById(R.id.go_to_route_listing_preference_button);
+        goToRouteListingPreferenceButton.setOnClickListener(
+                unusedView -> {
+                    startActivity(new Intent(this, RouteListingPreferenceActivity.class));
+                });
+
         RecyclerView routeList = findViewById(R.id.routes_recycler_view);
         routeList.setLayoutManager(new LinearLayoutManager(/* context= */ this));
         mRoutesAdapter = new RoutesAdapter(mRoutesManager.getRouteItems(), routeItemListener);
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/data/RouteItem.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/data/RouteItem.java
index eb034ed..5ac47e3 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/data/RouteItem.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/data/RouteItem.java
@@ -17,9 +17,9 @@
 package com.example.androidx.mediarouting.data;
 
 import android.media.AudioManager;
-import android.media.MediaRouter;
 
 import androidx.annotation.NonNull;
+import androidx.mediarouter.media.MediaRouter;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -40,6 +40,7 @@
     private int mVolumeMax;
     private DeviceType mDeviceType;
     private List<String> mGroupMemberIds;
+    private boolean mIsSenderDriven;
 
     public RouteItem() {
         this.mId = UUID.randomUUID().toString();
@@ -54,6 +55,7 @@
         this.mDeviceType = DeviceType.UNKNOWN;
         this.mCanDisconnect = false;
         this.mGroupMemberIds = new ArrayList<>();
+        this.mIsSenderDriven = false;
     }
 
     public RouteItem(
@@ -68,7 +70,8 @@
             int volume,
             int volumeMax,
             @NonNull DeviceType deviceType,
-            @NonNull List<String> groupMemberIds) {
+            @NonNull List<String> groupMemberIds,
+            boolean isSenderDriven) {
         mId = id;
         mName = name;
         mDescription = description;
@@ -81,6 +84,7 @@
         mVolumeMax = volumeMax;
         mDeviceType = deviceType;
         mGroupMemberIds = groupMemberIds;
+        mIsSenderDriven = isSenderDriven;
     }
 
     /** Returns a deep copy of an existing {@link RouteItem}. */
@@ -98,7 +102,8 @@
                 routeItem.getVolume(),
                 routeItem.getVolumeMax(),
                 routeItem.getDeviceType(),
-                routeItem.getGroupMemberIds());
+                routeItem.getGroupMemberIds(),
+                routeItem.isSenderDriven());
     }
 
     public enum ControlFilter {
@@ -150,6 +155,14 @@
         TV(MediaRouter.RouteInfo.DEVICE_TYPE_TV),
         SPEAKER(MediaRouter.RouteInfo.DEVICE_TYPE_SPEAKER),
         BLUETOOTH(MediaRouter.RouteInfo.DEVICE_TYPE_BLUETOOTH),
+        AUDIO_VIDEO_RECEIVER(MediaRouter.RouteInfo.DEVICE_TYPE_AUDIO_VIDEO_RECEIVER),
+        TABLET(MediaRouter.RouteInfo.DEVICE_TYPE_TABLET),
+        TABLET_DOCKED(MediaRouter.RouteInfo.DEVICE_TYPE_TABLET_DOCKED),
+        COMPUTER(MediaRouter.RouteInfo.DEVICE_TYPE_COMPUTER),
+        GAME_CONSOLE(MediaRouter.RouteInfo.DEVICE_TYPE_GAME_CONSOLE),
+        CAR(MediaRouter.RouteInfo.DEVICE_TYPE_CAR),
+        SMARTWATCH(MediaRouter.RouteInfo.DEVICE_TYPE_SMARTWATCH),
+        GROUP(MediaRouter.RouteInfo.DEVICE_TYPE_GROUP),
         UNKNOWN(MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN);
 
         public final int mIntConstant;
@@ -263,4 +276,12 @@
     public void setGroupMemberIds(@NonNull List<String> groupMemberIds) {
         mGroupMemberIds = groupMemberIds;
     }
+
+    public boolean isSenderDriven() {
+        return mIsSenderDriven;
+    }
+
+    public void setSenderDriven(boolean isSenderDriven) {
+        mIsSenderDriven = isSenderDriven;
+    }
 }
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/providers/SampleDynamicGroupMediaRouteProvider.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/providers/SampleDynamicGroupMediaRouteProvider.java
index daa2699..47ffed2 100644
--- a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/providers/SampleDynamicGroupMediaRouteProvider.java
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/providers/SampleDynamicGroupMediaRouteProvider.java
@@ -224,11 +224,17 @@
             mGroupDescriptor = groupRouteBuilder.build();
             mTvSelectedCount = countTvFromRoute(mGroupDescriptor);
 
-            // Initialize DynamicRouteDescriptor with all the route descriptors.
+            RoutesManager routesManager = RoutesManager.getInstance(getContext());
+
+            // Initialize DynamicRouteDescriptor with all the non-sender-driven descriptors.
             List<MediaRouteDescriptor> routeDescriptors = getDescriptor().getRoutes();
             if (routeDescriptors != null && !routeDescriptors.isEmpty()) {
                 for (MediaRouteDescriptor descriptor: routeDescriptors) {
                     String routeId = descriptor.getId();
+                    RouteItem item = routesManager.getRouteWithId(routeId);
+                    if (item != null && item.isSenderDriven()) {
+                        continue;
+                    }
                     boolean selected = memberIds.contains(routeId);
                     DynamicRouteDescriptor.Builder builder =
                             new DynamicRouteDescriptor.Builder(descriptor)
diff --git a/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/ui/UiUtils.java b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/ui/UiUtils.java
new file mode 100644
index 0000000..7d3ff97
--- /dev/null
+++ b/samples/MediaRoutingDemo/src/main/java/com/example/androidx/mediarouting/ui/UiUtils.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.example.androidx.mediarouting.ui;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+import androidx.annotation.NonNull;
+import androidx.core.util.Consumer;
+
+/** Contains utility methods related to UI management. */
+public final class UiUtils {
+
+    /**
+     * Populates the given {@link Spinner} using an {@link Enum} and its possible values.
+     *
+     * @param context The context in which the spinner is to be inflated.
+     * @param spinner The {@link Spinner} to populate.
+     * @param anEnum The initially selected value.
+     * @param selectionConsumer A consumer to invoke when an element is selected.
+     */
+    public static void setUpEnumBasedSpinner(
+            @NonNull Context context,
+            @NonNull Spinner spinner,
+            @NonNull Enum<?> anEnum,
+            @NonNull Consumer<Enum<?>> selectionConsumer) {
+        Enum<?>[] enumValues = anEnum.getDeclaringClass().getEnumConstants();
+        ArrayAdapter<Enum<?>> adapter =
+                new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, enumValues);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        spinner.setAdapter(adapter);
+        spinner.setSelection(anEnum.ordinal());
+
+        spinner.setOnItemSelectedListener(
+                new AdapterView.OnItemSelectedListener() {
+                    @Override
+                    public void onItemSelected(
+                            AdapterView<?> adapterView, View view, int i, long l) {
+                        selectionConsumer.accept(anEnum.getDeclaringClass().getEnumConstants()[i]);
+                    }
+
+                    @Override
+                    public void onNothingSelected(AdapterView<?> adapterView) {}
+                });
+    }
+
+    private UiUtils() {
+        // Prevent instantiation.
+    }
+}
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/activity_add_edit_route.xml b/samples/MediaRoutingDemo/src/main/res/layout/activity_add_edit_route.xml
index 8511ab9..58e0d57 100644
--- a/samples/MediaRoutingDemo/src/main/res/layout/activity_add_edit_route.xml
+++ b/samples/MediaRoutingDemo/src/main/res/layout/activity_add_edit_route.xml
@@ -263,7 +263,7 @@
                 android:padding="4dp">
 
                 <Switch
-                    android:id="@+id/cam_disconnect_switch"
+                    android:id="@+id/can_disconnect_switch"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:layout_alignParentEnd="true"
@@ -281,6 +281,31 @@
 
             </RelativeLayout>
 
+            <RelativeLayout
+                android:layout_width="match_parent"
+                android:layout_height="50dp"
+                android:layout_margin="12dp"
+                android:padding="4dp">
+
+                <Switch
+                    android:id="@+id/is_sender_driven_switch"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout_alignParentEnd="true"
+                    android:layout_alignParentRight="true"
+                    android:layout_centerVertical="true" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_alignParentLeft="true"
+                    android:layout_alignParentStart="true"
+                    android:layout_centerVertical="true"
+                    android:gravity="center"
+                    android:text="@string/is_sender_driven_switch_label" />
+
+            </RelativeLayout>
+
             <Button
                 android:id="@+id/save_button"
                 android:layout_height="wrap_content"
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/activity_route_listing_preference.xml b/samples/MediaRoutingDemo/src/main/res/layout/activity_route_listing_preference.xml
new file mode 100644
index 0000000..b932051
--- /dev/null
+++ b/samples/MediaRoutingDemo/src/main/res/layout/activity_route_listing_preference.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Enable Route Listing Preference" />
+
+        <Switch
+            android:id="@+id/enable_route_listing_preference_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Prefer system ordering" />
+
+        <Switch
+            android:id="@+id/prefer_system_ordering_switch"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/route_listing_preference_recycler_view"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_weight="1" />
+
+        <com.google.android.material.floatingactionbutton.FloatingActionButton
+            android:id="@+id/new_route_listing_preference_item_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_margin="20dp"
+            android:padding="0dp"
+            app:srcCompat="@drawable/ic_add" />
+
+    </RelativeLayout>
+</LinearLayout>
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/activity_settings.xml b/samples/MediaRoutingDemo/src/main/res/layout/activity_settings.xml
index 5193b7c..2572fc6 100644
--- a/samples/MediaRoutingDemo/src/main/res/layout/activity_settings.xml
+++ b/samples/MediaRoutingDemo/src/main/res/layout/activity_settings.xml
@@ -29,6 +29,12 @@
             android:layout_height="wrap_content"
             android:text="@string/settings_activity_show_system_routes" />
 
+        <Button
+            android:id="@+id/go_to_route_listing_preference_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Route listing preference"/>
+
         <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="50dp"
@@ -123,4 +129,4 @@
         android:padding="0dp"
         app:srcCompat="@drawable/ic_add" />
 
-</RelativeLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/activity_system_routing.xml b/samples/MediaRoutingDemo/src/main/res/layout/activity_system_routing.xml
index ceefa96..c3ef725 100644
--- a/samples/MediaRoutingDemo/src/main/res/layout/activity_system_routing.xml
+++ b/samples/MediaRoutingDemo/src/main/res/layout/activity_system_routing.xml
@@ -24,4 +24,4 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
 
-</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
+</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
\ No newline at end of file
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/item_system_route.xml b/samples/MediaRoutingDemo/src/main/res/layout/item_system_route.xml
index 836a846bed4..3034f1d 100644
--- a/samples/MediaRoutingDemo/src/main/res/layout/item_system_route.xml
+++ b/samples/MediaRoutingDemo/src/main/res/layout/item_system_route.xml
@@ -100,3 +100,4 @@
     </androidx.cardview.widget.CardView>
 
 </FrameLayout>
+
diff --git a/samples/MediaRoutingDemo/src/main/res/layout/route_listing_preference_item_dialog.xml b/samples/MediaRoutingDemo/src/main/res/layout/route_listing_preference_item_dialog.xml
new file mode 100644
index 0000000..3b2870b
--- /dev/null
+++ b/samples/MediaRoutingDemo/src/main/res/layout/route_listing_preference_item_dialog.xml
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Route name" />
+
+        <Spinner
+            android:id="@+id/rlp_item_dialog_route_name_spinner"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Selection behavior" />
+
+        <Spinner
+            android:id="@+id/rlp_item_dialog_selection_behavior_spinner"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </LinearLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Ongoing session" />
+
+        <CheckBox
+            android:id="@+id/rlp_item_dialog_ongoing_session_checkbox"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Ongoing session managed" />
+
+        <CheckBox
+            android:id="@+id/rlp_item_dialog_session_managed_checkbox"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Suggested route" />
+
+        <CheckBox
+            android:id="@+id/rlp_item_dialog_suggested_checkbox"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </RelativeLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_margin="12dp"
+        android:padding="4dp">
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentLeft="true"
+            android:layout_alignParentStart="true"
+            android:layout_centerVertical="true"
+            android:gravity="center"
+            android:text="Subtext" />
+
+        <Spinner
+            android:id="@+id/rlp_item_dialog_subtext_spinner"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_alignParentEnd="true"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true" />
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/MediaRoutingDemo/src/main/res/values/strings.xml b/samples/MediaRoutingDemo/src/main/res/values/strings.xml
index 87596b2..f46edb8 100644
--- a/samples/MediaRoutingDemo/src/main/res/values/strings.xml
+++ b/samples/MediaRoutingDemo/src/main/res/values/strings.xml
@@ -49,12 +49,16 @@
     <string name="dg_not_unselectable_route_name5"> Dynamic Route 5 - Not unselectable</string>
     <string name="dg_static_group_route_name6"> Dynamic Route 6 - Static Group</string>
 
+    <string name="sender_driven_route_name1">Sender Driven TV 1</string>
+    <string name="sender_driven_route_name2">Sender Driven TV 2</string>
+
     <string name="sample_media_route_provider_remote">Remote Playback (Simulated)</string>
     <string name="sample_media_route_activity_local">Local Playback</string>
     <string name="sample_media_route_activity_presentation">Local Playback on Presentation Display</string>
 
     <string name="delete_route_alert_dialog_title">Delete this route?</string>
     <string name="delete_route_alert_dialog_message">Are you sure you want to delete this route?</string>
+    <string name="is_sender_driven_switch_label">Is Sender Driven</string>
 
     <string name="settings_activity_show_system_routes">Show system routes</string>
 
diff --git a/samples/Support4Demos/OWNERS b/samples/Support4Demos/OWNERS
index 3b8f7e1..bd210e0 100644
--- a/samples/Support4Demos/OWNERS
+++ b/samples/Support4Demos/OWNERS
@@ -1,5 +1,9 @@
+adadukin@google.com
+alexfrancois@google.com
+aquilescanta@google.com
 bachinger@google.com
+bishoygendy@google.com
 christosts@google.com
 ibaker@google.com
-olly@google.com
+ivanbuper@google.com
 tonihei@google.com
diff --git a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/MediaBrowserServiceSupport.java b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/MediaBrowserServiceSupport.java
index 1015954..c3bc3c1 100644
--- a/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/MediaBrowserServiceSupport.java
+++ b/samples/Support4Demos/src/main/java/com/example/android/supportv4/media/MediaBrowserServiceSupport.java
@@ -222,6 +222,7 @@
         // Always release the MediaSession to clean up resources
         // and notify associated MediaController(s).
         mSession.release();
+        super.onDestroy();
     }
 
     @Override
diff --git a/samples/SupportPreferenceDemos/src/main/java/com/example/androidx/preference/TwoPanePreferences.kt b/samples/SupportPreferenceDemos/src/main/java/com/example/androidx/preference/TwoPanePreferences.kt
index 724783e..44b8e46 100644
--- a/samples/SupportPreferenceDemos/src/main/java/com/example/androidx/preference/TwoPanePreferences.kt
+++ b/samples/SupportPreferenceDemos/src/main/java/com/example/androidx/preference/TwoPanePreferences.kt
@@ -16,6 +16,8 @@
 
 package com.example.androidx.preference
 
+import android.content.Context
+import android.content.ContextWrapper
 import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
 import androidx.preference.PreferenceFragmentCompat
@@ -34,6 +36,14 @@
         override fun onCreatePreferenceHeader(): PreferenceFragmentCompat {
             return PreferenceHeader()
         }
+
+        /**
+         * Simulate the behavior of Hilt to ensure that PreferenceHeaderFragmentCompat
+         * does not rely on the Context being an OnBackPressedDispatcherOwner instance
+         */
+        override fun getContext(): Context {
+            return ContextWrapper(super.getContext())
+        }
     }
 
     class BasicPreferences : PreferenceFragmentCompat() {
@@ -68,13 +78,6 @@
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-
-        // Display preference header fragment as the main content
-        if (savedInstanceState == null) {
-            supportFragmentManager.beginTransaction().replace(
-                android.R.id.content,
-                PreferenceHeaderFragmentCompatImpl()
-            ).commit()
-        }
+        setContentView(R.layout.two_pane_preferences)
     }
 }
\ No newline at end of file
diff --git a/samples/SupportPreferenceDemos/src/main/res/layout/two_pane_preferences.xml b/samples/SupportPreferenceDemos/src/main/res/layout/two_pane_preferences.xml
new file mode 100644
index 0000000..38854e5
--- /dev/null
+++ b/samples/SupportPreferenceDemos/src/main/res/layout/two_pane_preferences.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/two_pane_preferences"
+    android:name="com.example.androidx.preference.TwoPanePreferences$PreferenceHeaderFragmentCompatImpl"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
\ No newline at end of file
diff --git a/security/security-identity-credential/lint-baseline.xml b/security/security-identity-credential/lint-baseline.xml
index f8343ff..83c5e2d 100644
--- a/security/security-identity-credential/lint-baseline.xml
+++ b/security/security-identity-credential/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="WrongConstant"
@@ -10,58 +10,4 @@
             file="src/main/java/androidx/security/identity/HardwareIdentityCredential.java"/>
     </issue>
 
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    protected IdentityCredential() {}"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/IdentityCredential.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Ciphersuite {"
-        errorLine2="                      ~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/IdentityCredentialStore.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    protected ResultData() {}"
-        errorLine2="              ~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/ResultData.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    public @interface Status {"
-        errorLine2="                      ~~~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/ResultData.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class Util {"
-        errorLine2="      ~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/Util.java"/>
-    </issue>
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="    protected WritableIdentityCredential() {}"
-        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/security/identity/WritableIdentityCredential.java"/>
-    </issue>
-
 </issues>
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java b/security/security-identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
index 855f060..096366c 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/HardwareIdentityCredential.java
@@ -249,6 +249,7 @@
         return builder.build();
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey) {
         mCredential.setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
@@ -271,6 +272,7 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public @NonNull
     int[] getAuthenticationDataUsageCount() {
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java b/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
index 01b4fee..4e4a17a 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredential.java
@@ -32,15 +32,12 @@
 
 /**
  * Class used to read data from a previously provisioned credential.
- *
+ * <p>
  * Use {@link IdentityCredentialStore#getCredentialByName(String, int)} to get a
  * {@link IdentityCredential} instance.
  */
 public abstract class IdentityCredential {
-    /**
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.SUBCLASSES)
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     protected IdentityCredential() {}
 
     /**
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java b/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
index c2dc700..cf2d8d2 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/IdentityCredentialStore.java
@@ -149,7 +149,7 @@
 
     /**
      * Gets the {@link IdentityCredentialStore} for direct access.
-     *
+     * <p>
      * This should only be called if {@link #isDirectAccessSupported(Context)} returns {@code true}.
      *
      * @param context the application context.
@@ -259,7 +259,6 @@
     @Deprecated
     public abstract @Nullable byte[] deleteCredentialByName(@NonNull String credentialName);
 
-    /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef(value = {CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256})
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/ResultData.java b/security/security-identity-credential/src/main/java/androidx/security/identity/ResultData.java
index 60ef9d7..b794d97 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/ResultData.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/ResultData.java
@@ -60,10 +60,7 @@
      */
     public static final int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
 
-    /**
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.SUBCLASSES)
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     protected ResultData() {}
 
     /**
@@ -322,7 +319,6 @@
 
     /**
      * The type of the entry status.
-     * @hide
      */
     @Retention(SOURCE)
     @RestrictTo(RestrictTo.Scope.LIBRARY)
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/Util.java b/security/security-identity-credential/src/main/java/androidx/security/identity/Util.java
index 0428f1b..a730041 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/Util.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/Util.java
@@ -96,9 +96,6 @@
 import co.nstant.in.cbor.model.UnicodeString;
 import co.nstant.in.cbor.model.UnsignedInteger;
 
-/**
- * @hide
- */
 class Util {
     private static final String TAG = "Util";
 
diff --git a/security/security-identity-credential/src/main/java/androidx/security/identity/WritableIdentityCredential.java b/security/security-identity-credential/src/main/java/androidx/security/identity/WritableIdentityCredential.java
index 7b2e394..53dafdc 100644
--- a/security/security-identity-credential/src/main/java/androidx/security/identity/WritableIdentityCredential.java
+++ b/security/security-identity-credential/src/main/java/androidx/security/identity/WritableIdentityCredential.java
@@ -30,14 +30,11 @@
  *
  * <p>Once persisted, the PII in a credential can be updated using
  * {@link IdentityCredential#update(PersonalizationData)}.
- *
+ * <p>
  * Use {@link IdentityCredentialStore#createCredential(String, String)} to create a new credential.
  */
 public abstract class WritableIdentityCredential {
-    /**
-     * @hide
-     */
-    @RestrictTo(RestrictTo.Scope.SUBCLASSES)
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
     protected WritableIdentityCredential() {}
 
     /**
diff --git a/settings.gradle b/settings.gradle
index 43d3b68..f117b32 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -95,9 +95,9 @@
         value("androidx.projects", getRequestedProjectSubsetName() ?: "Unset")
         value("androidx.useMaxDepVersions", providers.gradleProperty("androidx.useMaxDepVersions").isPresent().toString())
 
-        // Publish scan for androidx-main
-        publishAlways()
-        publishIfAuthenticated()
+	// Publish scan for androidx-main
+	publishAlways()
+	publishIfAuthenticated()
     }
 }
 
@@ -452,6 +452,7 @@
 includeProject(":appsearch:appsearch-ktx", [BuildType.MAIN])
 includeProject(":appsearch:appsearch-local-storage", [BuildType.MAIN])
 includeProject(":appsearch:appsearch-platform-storage", [BuildType.MAIN])
+includeProject(":appsearch:appsearch-play-services-storage", [BuildType.MAIN])
 includeProject(":appsearch:appsearch-test-util", [BuildType.MAIN])
 includeProject(":arch:core:core-common", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE])
 includeProject(":arch:core:core-runtime", [BuildType.MAIN, BuildType.FLAN, BuildType.COMPOSE])
@@ -683,6 +684,7 @@
 includeProject(":core:core-i18n", [BuildType.MAIN])
 includeProject(":core:core-ktx", [BuildType.MAIN, BuildType.GLANCE, BuildType.MEDIA, BuildType.FLAN, BuildType.COMPOSE])
 includeProject(":core:core-location-altitude", [BuildType.MAIN])
+includeProject(":core:core-location-altitude-proto", [BuildType.MAIN])
 includeProject(":core:core-performance", [BuildType.MAIN])
 includeProject(":core:core-performance-testing", [BuildType.MAIN])
 includeProject(":core:core-performance-play-services", [BuildType.MAIN])
@@ -693,6 +695,8 @@
 includeProject(":core:core-splashscreen:core-splashscreen-samples", "core/core-splashscreen/samples", [BuildType.MAIN])
 includeProject(":core:core-graphics-integration-tests:core-graphics-integration-tests", "core/core-graphics-integration-tests/testapp", [BuildType.MAIN])
 includeProject(":core:core-role", [BuildType.MAIN])
+includeProject(":core:core-telecom", [BuildType.MAIN])
+includeProject(":core:core-telecom:integration-tests:testapp", [BuildType.MAIN])
 includeProject(":core:haptics:haptics", [BuildType.MAIN])
 includeProject(":core:haptics:haptics-samples", "core/haptics/haptics/samples", [BuildType.MAIN])
 includeProject(":core:haptics:haptics-demos", "core/haptics/haptics/integration-tests/demos", [BuildType.MAIN])
@@ -770,6 +774,7 @@
 includeProject(":glance:glance-wear-tiles", [BuildType.GLANCE])
 includeProject(":glance:glance-wear-tiles-preview", [BuildType.GLANCE])
 includeProject(":graphics:filters:filters", [BuildType.MAIN])
+includeProject(":graphics:graphics-path", [BuildType.MAIN])
 includeProject(":graphics:graphics-core", [BuildType.MAIN])
 includeProject(":graphics:graphics-shapes", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":graphics:integration-tests:testapp", [BuildType.MAIN])
@@ -990,7 +995,7 @@
 includeProject(":tracing:tracing-ktx")
 includeProject(":tracing:tracing-perfetto")
 includeProject(":tracing:tracing-perfetto-binary")
-includeProject(":tracing:tracing-perfetto-common")
+includeProject(":tracing:tracing-perfetto-handshake")
 includeProject(":transition:transition", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":transition:transition-ktx", [BuildType.MAIN, BuildType.FLAN])
 includeProject(":tv:tv-foundation", [BuildType.COMPOSE])
@@ -1095,6 +1100,7 @@
 includeProject(":window:window-testing", [BuildType.MAIN, BuildType.COMPOSE, BuildType.FLAN, BuildType.WINDOW])
 includeProject(":work:integration-tests:testapp", [BuildType.MAIN])
 includeProject(":work:work-benchmark", [BuildType.MAIN])
+includeProject(":work:work-datatransfer", [BuildType.MAIN])
 includeProject(":work:work-gcm", [BuildType.MAIN])
 includeProject(":work:work-inspection", [BuildType.MAIN])
 includeProject(":work:work-multiprocess", [BuildType.MAIN])
diff --git a/slidingpanelayout/slidingpanelayout/api/api_lint.ignore b/slidingpanelayout/slidingpanelayout/api/api_lint.ignore
index e495753..a288bd0 100644
--- a/slidingpanelayout/slidingpanelayout/api/api_lint.ignore
+++ b/slidingpanelayout/slidingpanelayout/api/api_lint.ignore
@@ -1,10 +1,6 @@
 // Baseline format: 1.0
 InvalidNullabilityOverride: androidx.slidingpanelayout.widget.SlidingPaneLayout#addView(android.view.View, int, android.view.ViewGroup.LayoutParams) parameter #0:
     Invalid nullability on parameter `child` in method `addView`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.slidingpanelayout.widget.SlidingPaneLayout#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `c` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.slidingpanelayout.widget.SlidingPaneLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
-    Invalid nullability on parameter `canvas` in method `drawChild`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 InvalidNullabilityOverride: androidx.slidingpanelayout.widget.SlidingPaneLayout#removeView(android.view.View) parameter #0:
     Invalid nullability on parameter `view` in method `removeView`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
 
@@ -15,6 +11,10 @@
 
 MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#checkLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
     Missing nullability on parameter `p` in method `checkLayoutParams`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `c` in method `draw`
+MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #0:
+    Missing nullability on parameter `canvas` in method `drawChild`
 MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#drawChild(android.graphics.Canvas, android.view.View, long) parameter #1:
     Missing nullability on parameter `child` in method `drawChild`
 MissingNullability: androidx.slidingpanelayout.widget.SlidingPaneLayout#generateDefaultLayoutParams():
diff --git a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/helpers/TestActivity.kt b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/helpers/TestActivity.kt
index 207861a..0e4d8ef 100644
--- a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/helpers/TestActivity.kt
+++ b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/helpers/TestActivity.kt
@@ -27,12 +27,14 @@
         // callback when the activity created
         onActivityCreated(this)
         // disable enter animation
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
     override fun finish() {
         super.finish()
         // disable exit animation
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
diff --git a/swiperefreshlayout/swiperefreshlayout/api/api_lint.ignore b/swiperefreshlayout/swiperefreshlayout/api/api_lint.ignore
index 6038f08..25a9da5 100644
--- a/swiperefreshlayout/swiperefreshlayout/api/api_lint.ignore
+++ b/swiperefreshlayout/swiperefreshlayout/api/api_lint.ignore
@@ -13,6 +13,8 @@
     Internal field mOriginalOffsetTop must not be exposed
 
 
+MissingNullability: androidx.swiperefreshlayout.widget.CircularProgressDrawable#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.swiperefreshlayout.widget.CircularProgressDrawable#setColorFilter(android.graphics.ColorFilter) parameter #0:
     Missing nullability on parameter `colorFilter` in method `setColorFilter`
 MissingNullability: androidx.swiperefreshlayout.widget.SwipeRefreshLayout#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
diff --git a/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectKruthTest.kt b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectKruthTest.kt
new file mode 100644
index 0000000..6ee7a7b
--- /dev/null
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectKruthTest.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.kruth
+
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+/**
+ * Supplemental tests to [MapSubjectTest].
+ */
+class MapSubjectKruthTest {
+    @Test
+    fun containsExactlyEntriesIn_mapInOrder() {
+        // LinkedHashMap preserves ordering of entries, keys and values.
+        val map = LinkedHashMap<Int, Int>()
+        repeat(5) { map[it] = it }
+        val correctMap = LinkedHashMap<Int, Int>()
+        repeat(5) { correctMap[it] = it }
+        val reversedMap = LinkedHashMap<Int, Int>()
+        repeat(5) { reversedMap[4 - it] = 4 - it }
+
+        val mapInOrderCorrect = assertThat(map).containsExactlyEntriesIn(correctMap)
+        mapInOrderCorrect.inOrder()
+
+        val mapInOrderReversed = assertThat(map).containsExactlyEntriesIn(reversedMap)
+        assertFailsWith<AssertionError> {
+            mapInOrderReversed.inOrder()
+        }
+    }
+}
\ No newline at end of file
diff --git a/testutils/testutils-ktx/lint-baseline.xml b/testutils/testutils-ktx/lint-baseline.xml
deleted file mode 100644
index 5207c20..0000000
--- a/testutils/testutils-ktx/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(periodMs)"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/main/java/androidx/testutils/VerifyWithPolling.kt"/>
-    </issue>
-
-</issues>
diff --git a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/TestActivity.kt b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/TestActivity.kt
index f44d9c4..81334f8 100644
--- a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/TestActivity.kt
+++ b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/TestActivity.kt
@@ -32,6 +32,7 @@
         super.onCreate(savedInstanceState)
         setContentView(R.layout.content_view)
         println("onCreate")
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
@@ -48,6 +49,7 @@
         }
 
         super.finish()
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
diff --git a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
index 1812036..9e377d5 100644
--- a/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
+++ b/tracing/tracing-perfetto-binary/src/main/cpp/tracing_perfetto.cc
@@ -25,7 +25,7 @@
 // Concept of version useful e.g. for human-readable error messages, and stable once released.
 // Does not replace the need for a binary verification mechanism (e.g. checksum check).
 // TODO: populate using CMake
-#define VERSION "1.0.0-alpha16"
+#define VERSION "1.0.0-alpha17"
 
 namespace tracing_perfetto {
     void RegisterWithPerfetto() {
diff --git a/tracing/tracing-perfetto-common/api/current.txt b/tracing/tracing-perfetto-common/api/current.txt
deleted file mode 100644
index 98f9ffc7..0000000
--- a/tracing/tracing-perfetto-common/api/current.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-// Signature format: 4.0
-package androidx.tracing.perfetto {
-
-  public final class PerfettoSdkHandshake {
-    ctor public PerfettoSdkHandshake(String targetPackage, kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.util.Map<java.lang.String,java.lang.String>> parseJsonMap, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.String> executeShellCommand);
-    method public androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse enableTracingColdStart(kotlin.jvm.functions.Function0<kotlin.Unit> killAppProcess, androidx.tracing.perfetto.PerfettoSdkHandshake.LibrarySource? librarySource);
-    method public androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse enableTracingImmediate(optional androidx.tracing.perfetto.PerfettoSdkHandshake.LibrarySource? librarySource);
-  }
-
-  public static final class PerfettoSdkHandshake.EnableTracingResponse {
-    method public int getExitCode();
-    method public String? getMessage();
-    method public String? getRequiredVersion();
-    property public final int exitCode;
-    property public final String? message;
-    property public final String? requiredVersion;
-  }
-
-  public static final class PerfettoSdkHandshake.LibrarySource {
-    ctor public PerfettoSdkHandshake.LibrarySource(java.io.File libraryZip, java.io.File tempDirectory, kotlin.jvm.functions.Function2<? super java.io.File,? super java.io.File,kotlin.Unit> moveLibFileFromTmpDirToAppDir);
-  }
-
-  public static final class PerfettoSdkHandshake.ResponseExitCodes {
-    field public static final androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes INSTANCE;
-    field public static final int RESULT_CODE_ALREADY_ENABLED = 2; // 0x2
-    field public static final int RESULT_CODE_CANCELLED = 0; // 0x0
-    field public static final int RESULT_CODE_ERROR_BINARY_MISSING = 11; // 0xb
-    field public static final int RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR = 13; // 0xd
-    field public static final int RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH = 12; // 0xc
-    field public static final int RESULT_CODE_ERROR_OTHER = 99; // 0x63
-    field public static final int RESULT_CODE_SUCCESS = 1; // 0x1
-  }
-
-}
-
diff --git a/tracing/tracing-perfetto-common/api/restricted_current.txt b/tracing/tracing-perfetto-common/api/restricted_current.txt
deleted file mode 100644
index 98f9ffc7..0000000
--- a/tracing/tracing-perfetto-common/api/restricted_current.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-// Signature format: 4.0
-package androidx.tracing.perfetto {
-
-  public final class PerfettoSdkHandshake {
-    ctor public PerfettoSdkHandshake(String targetPackage, kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.util.Map<java.lang.String,java.lang.String>> parseJsonMap, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.String> executeShellCommand);
-    method public androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse enableTracingColdStart(kotlin.jvm.functions.Function0<kotlin.Unit> killAppProcess, androidx.tracing.perfetto.PerfettoSdkHandshake.LibrarySource? librarySource);
-    method public androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse enableTracingImmediate(optional androidx.tracing.perfetto.PerfettoSdkHandshake.LibrarySource? librarySource);
-  }
-
-  public static final class PerfettoSdkHandshake.EnableTracingResponse {
-    method public int getExitCode();
-    method public String? getMessage();
-    method public String? getRequiredVersion();
-    property public final int exitCode;
-    property public final String? message;
-    property public final String? requiredVersion;
-  }
-
-  public static final class PerfettoSdkHandshake.LibrarySource {
-    ctor public PerfettoSdkHandshake.LibrarySource(java.io.File libraryZip, java.io.File tempDirectory, kotlin.jvm.functions.Function2<? super java.io.File,? super java.io.File,kotlin.Unit> moveLibFileFromTmpDirToAppDir);
-  }
-
-  public static final class PerfettoSdkHandshake.ResponseExitCodes {
-    field public static final androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes INSTANCE;
-    field public static final int RESULT_CODE_ALREADY_ENABLED = 2; // 0x2
-    field public static final int RESULT_CODE_CANCELLED = 0; // 0x0
-    field public static final int RESULT_CODE_ERROR_BINARY_MISSING = 11; // 0xb
-    field public static final int RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR = 13; // 0xd
-    field public static final int RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH = 12; // 0xc
-    field public static final int RESULT_CODE_ERROR_OTHER = 99; // 0x63
-    field public static final int RESULT_CODE_SUCCESS = 1; // 0x1
-  }
-
-}
-
diff --git a/tracing/tracing-perfetto-common/build.gradle b/tracing/tracing-perfetto-common/build.gradle
deleted file mode 100644
index ac22d616..0000000
--- a/tracing/tracing-perfetto-common/build.gradle
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import androidx.build.BuildServerConfigurationKt
-import androidx.build.Publish
-
-plugins {
-    id("AndroidXPlugin")
-    id("java-library")
-    id("kotlin")
-}
-
-dependencies {
-    compileOnly(libs.kotlinStdlib)
-    api("androidx.annotation:annotation:1.3.0")
-}
-
-tasks.withType(Jar) {
-    destinationDirectory.set(BuildServerConfigurationKt.getDistributionDirectory(rootProject))
-}
-
-androidx {
-    name = "Tracing Perfetto Common"
-    publish = Publish.SNAPSHOT_AND_RELEASE
-    mavenVersion = LibraryVersions.TRACING_PERFETTO
-    inceptionYear = "2022"
-    description = "AndroidX Tracing: Perfetto Common"
-}
diff --git a/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkHandshake.kt b/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkHandshake.kt
deleted file mode 100644
index 9f1a06b..0000000
--- a/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkHandshake.kt
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.tracing.perfetto
-
-import androidx.annotation.IntDef
-import androidx.annotation.RestrictTo
-import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.ACTION_ENABLE_TRACING
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.ACTION_ENABLE_TRACING_COLD_START
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.KEY_PATH
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.KEY_PERSISTENT
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.RECEIVER_CLASS_NAME
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseKeys.KEY_EXIT_CODE
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseKeys.KEY_MESSAGE
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseKeys.KEY_REQUIRED_VERSION
-import java.io.File
-import java.lang.StringBuilder
-
-/**
- * Handshake implementation allowing to enable Perfetto SDK tracing in an app that enables it.
- *
- * @param targetPackage package name of the target app
- * @param parseJsonMap function parsing a flat map in a JSON format into a `Map<String, String>`
- * e.g. `"{ 'key 1': 'value 1', 'key 2': 'value 2' }"` ->
- * `mapOf("key 1" to "value 1", "key 2" to "value 2")`
- * @param executeShellCommand function allowing to execute `adb shell` commands on the target device
- *
- * For error handling, note that [parseJsonMap] and [executeShellCommand] will be called on the same
- * thread as [enableTracingImmediate] and [enableTracingColdStart].
- */
-public class PerfettoSdkHandshake(
-    private val targetPackage: String,
-    private val parseJsonMap: (jsonString: String) -> Map<String, String>,
-    private val executeShellCommand: ShellCommandExecutor
-) {
-    /**
-     * Attempts to enable tracing in an app. It will wake up (or start) the app process, so it will
-     * act as warm/hot tracing. For cold tracing see [enableTracingColdStart]
-     *
-     * Note: if the app process is not running, it will be launched making the method a bad choice
-     * for cold tracing (use [enableTracingColdStart] instead.
-     *
-     * @param librarySource optional AAR or an APK containing `libtracing_perfetto.so`
-     */
-    public fun enableTracingImmediate(
-        librarySource: LibrarySource? = null
-    ): EnableTracingResponse {
-        val libPath = librarySource?.run {
-            PerfettoSdkSideloader(targetPackage).sideloadFromZipFile(
-                libraryZip,
-                tempDirectory,
-                executeShellCommand,
-                moveLibFileFromTmpDirToAppDir
-            )
-        }
-        return sendEnableTracingBroadcast(libPath, coldStart = false)
-    }
-
-    /**
-     * Attempts to prepare cold startup tracing in an app.
-     *
-     * @param killAppProcess function responsible for terminating the app process (no-op if the
-     * process is already terminated)
-     * @param librarySource optional AAR or an APK containing `libtracing_perfetto.so`
-     */
-    public fun enableTracingColdStart(
-        killAppProcess: () -> Unit,
-        librarySource: LibrarySource?
-    ): EnableTracingResponse {
-        // sideload the `libtracing_perfetto.so` file if applicable
-        val libPath = librarySource?.run {
-            PerfettoSdkSideloader(targetPackage).sideloadFromZipFile(
-                libraryZip,
-                tempDirectory,
-                executeShellCommand,
-                moveLibFileFromTmpDirToAppDir
-            )
-        }
-
-        // ensure a clean start (e.g. in case tracing is already enabled)
-        killAppProcess()
-
-        // verify (by performing a regular handshake) that we can enable tracing at app startup
-        val response = sendEnableTracingBroadcast(libPath, coldStart = true, persistent = false)
-        if (response.exitCode == ResponseExitCodes.RESULT_CODE_SUCCESS) {
-            // terminate the app process (that we woke up by issuing a broadcast earlier)
-            killAppProcess()
-        }
-
-        return response
-    }
-
-    private fun sendEnableTracingBroadcast(
-        libPath: File? = null,
-        coldStart: Boolean,
-        persistent: Boolean? = null
-    ): EnableTracingResponse {
-        val action = if (coldStart) ACTION_ENABLE_TRACING_COLD_START else ACTION_ENABLE_TRACING
-        val commandBuilder = StringBuilder("am broadcast -a $action")
-        if (persistent != null) commandBuilder.append(" --es $KEY_PERSISTENT $persistent")
-        if (libPath != null) commandBuilder.append(" --es $KEY_PATH $libPath")
-        commandBuilder.append(" $targetPackage/$RECEIVER_CLASS_NAME")
-
-        val rawResponse = executeShellCommand(commandBuilder.toString())
-
-        val response = try {
-            parseResponse(rawResponse)
-        } catch (e: IllegalArgumentException) {
-            val message = "Exception occurred while trying to parse a response." +
-                " Error: ${e.message}. Raw response: $rawResponse."
-            EnableTracingResponse(ResponseExitCodes.RESULT_CODE_ERROR_OTHER, null, message)
-        }
-        return response
-    }
-
-    private fun parseResponse(rawResponse: String): EnableTracingResponse {
-        val line = rawResponse
-            .split(Regex("\r?\n"))
-            .firstOrNull { it.contains("Broadcast completed: result=") }
-            ?: throw IllegalArgumentException("Cannot parse: $rawResponse")
-
-        if (line == "Broadcast completed: result=0") return EnableTracingResponse(
-            ResponseExitCodes.RESULT_CODE_CANCELLED, null, null
-        )
-
-        val matchResult =
-            Regex("Broadcast completed: (result=.*?)(, data=\".*?\")?(, extras: .*)?")
-                .matchEntire(line)
-                ?: throw IllegalArgumentException("Cannot parse: $rawResponse")
-
-        val broadcastResponseCode = matchResult
-            .groups[1]
-            ?.value
-            ?.substringAfter("result=")
-            ?.toIntOrNull()
-
-        val dataString = matchResult
-            .groups
-            .firstOrNull { it?.value?.startsWith(", data=") ?: false }
-            ?.value
-            ?.substringAfter(", data=\"")
-            ?.dropLast(1)
-            ?: throw IllegalArgumentException("Cannot parse: $rawResponse. " +
-                "Unable to detect 'data=' section."
-            )
-
-        val dataMap = parseJsonMap(dataString)
-        val response = EnableTracingResponse(
-            dataMap[KEY_EXIT_CODE]?.toInt()
-                ?: throw IllegalArgumentException("Response missing $KEY_EXIT_CODE value"),
-            dataMap[KEY_REQUIRED_VERSION]
-                ?: throw IllegalArgumentException("Response missing $KEY_REQUIRED_VERSION value"),
-            dataMap[KEY_MESSAGE]
-        )
-
-        if (broadcastResponseCode != response.exitCode) {
-            throw IllegalStateException(
-                "Cannot parse: $rawResponse. Exit code " +
-                    "not matching broadcast exit code."
-            )
-        }
-
-        return response
-    }
-
-    /**
-    * @param libraryZip either an AAR or an APK containing `libtracing_perfetto.so`
-    * @param tempDirectory a directory directly accessible to the caller process (used for
-     * extraction of the binaries from the zip)
-    * @param moveLibFileFromTmpDirToAppDir a function capable of moving the binary file from
-    * the [tempDirectory] to an app accessible folder
-    */
-    // TODO(245426369): consider moving to a factory pattern for constructing these and refer to
-    //  this one as `aarLibrarySource` and `apkLibrarySource`
-    public class LibrarySource @Suppress("StreamFiles") constructor(
-        internal val libraryZip: File,
-        internal val tempDirectory: File,
-        internal val moveLibFileFromTmpDirToAppDir: FileMover
-    )
-
-    @RestrictTo(LIBRARY_GROUP)
-    public object RequestKeys {
-        public const val RECEIVER_CLASS_NAME: String = "androidx.tracing.perfetto.TracingReceiver"
-
-        /**
-         * Request to enable tracing in an app.
-         *
-         * The action is performed straight away allowing for warm / hot tracing. For cold start
-         * tracing see [ACTION_ENABLE_TRACING_COLD_START]
-         *
-         * Request can include [KEY_PATH] as an optional extra.
-         *
-         * Response to the request is a JSON string (to allow for CLI support) with the following:
-         * - [ResponseKeys.KEY_EXIT_CODE] (always)
-         * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
-         * - [ResponseKeys.KEY_MESSAGE] (optional)
-         */
-        public const val ACTION_ENABLE_TRACING: String =
-            "androidx.tracing.perfetto.action.ENABLE_TRACING"
-
-        /**
-         * Request to enable cold start tracing in an app.
-         *
-         * For warm / hot tracing, see [ACTION_ENABLE_TRACING].
-         *
-         * The action must be performed in the following order, otherwise its effects are
-         * unspecified:
-         * - the app process must be killed before performing the action
-         * - the action must then follow
-         * - the app process must be killed after performing the action
-         *
-         * Request can include [KEY_PATH] as an optional extra.
-         * Request can include [KEY_PERSISTENT] as an optional extra.
-         *
-         * Response to the request is a JSON string (to allow for CLI support) with the following:
-         * - [ResponseKeys.KEY_EXIT_CODE] (always)
-         * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
-         * - [ResponseKeys.KEY_MESSAGE] (optional)
-         */
-        public const val ACTION_ENABLE_TRACING_COLD_START: String =
-            "androidx.tracing.perfetto.action.ENABLE_TRACING_COLD_START"
-
-        /**
-         * Request to disable cold start tracing (previously enabled with
-         * [ACTION_ENABLE_TRACING_COLD_START]).
-         *
-         * The action is particularly useful when cold start tracing was enabled in
-         * [KEY_PERSISTENT] mode.
-         *
-         * The action must be performed in the following order, otherwise its effects are
-         * unspecified:
-         * - the app process must be killed before performing the action
-         * - the action must then follow
-         * - the app process must be killed after performing the action
-         *
-         * Request can include [KEY_PATH] as an optional extra.
-         * Request can include [KEY_PERSISTENT] as an optional extra.
-         *
-         * Response to the request is a JSON string (to allow for CLI support) with the following:
-         * - [ResponseKeys.KEY_EXIT_CODE] (always)
-         */
-        public const val ACTION_DISABLE_TRACING_COLD_START: String =
-            "androidx.tracing.perfetto.action.DISABLE_TRACING_COLD_START"
-
-        /** Path to tracing native binary file */
-        public const val KEY_PATH: String = "path"
-
-        /**
-         * Boolean flag to signify whether the operation should be persistent between runs
-         * (or only performed once).
-         *
-         * Applies to [ACTION_ENABLE_TRACING_COLD_START]
-         */
-        public const val KEY_PERSISTENT: String = "persistent"
-    }
-
-    @RestrictTo(LIBRARY_GROUP)
-    public object ResponseKeys {
-        /** Exit code as listed in [ResponseExitCodes]. */
-        public const val KEY_EXIT_CODE: String = "exitCode"
-
-        /**
-         * Required version of the binaries. Java and binary library versions have to match to
-         * ensure compatibility. In the Maven format, e.g. 1.2.3-beta01.
-         */
-        public const val KEY_REQUIRED_VERSION: String = "requiredVersion"
-
-        /**
-         * Message string that gives more information about the response, e.g. recovery steps
-         * if applicable.
-         */
-        public const val KEY_MESSAGE: String = "message"
-    }
-
-    public object ResponseExitCodes {
-        /**
-         * Indicates that the broadcast resulted in `result=0`, which is an equivalent
-         * of [android.app.Activity.RESULT_CANCELED].
-         *
-         * This most likely means that the app does not expose a [PerfettoSdkHandshake] compatible
-         * receiver.
-         */
-        @Suppress("KDocUnresolvedReference")
-        public const val RESULT_CODE_CANCELLED: Int = 0
-
-        public const val RESULT_CODE_SUCCESS: Int = 1
-        public const val RESULT_CODE_ALREADY_ENABLED: Int = 2
-
-        /**
-         * Required version described in [EnableTracingResponse.requiredVersion].
-         * A follow-up [enableTracingImmediate] request expected with binaries to sideload specified.
-         */
-        public const val RESULT_CODE_ERROR_BINARY_MISSING: Int = 11
-
-        /** Required version described in [EnableTracingResponse.requiredVersion]. */
-        public const val RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH: Int = 12
-
-        /**
-         * Could be a result of a stale version of the binary cached locally.
-         * Retrying with a freshly downloaded library likely to fix the issue.
-         * More specific information in [EnableTracingResponse.message]
-         */
-        public const val RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR: Int = 13
-
-        /** More specific information in [EnableTracingResponse.message] */
-        public const val RESULT_CODE_ERROR_OTHER: Int = 99
-    }
-
-    @Retention(AnnotationRetention.SOURCE)
-    @IntDef(
-        ResponseExitCodes.RESULT_CODE_CANCELLED,
-        ResponseExitCodes.RESULT_CODE_SUCCESS,
-        ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED,
-        ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING,
-        ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH,
-        ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR,
-        ResponseExitCodes.RESULT_CODE_ERROR_OTHER
-    )
-    private annotation class EnableTracingResultCode
-
-    public class EnableTracingResponse @RestrictTo(LIBRARY_GROUP) constructor(
-        @EnableTracingResultCode public val exitCode: Int,
-
-        /**
-         * This can be `null` iff we cannot communicate with the broadcast receiver of the target
-         * process (e.g. app does not offer Perfetto tracing) or if we cannot parse the response
-         * from the receiver. In either case, tracing is unlikely to work under these circumstances,
-         * and more context on how to proceed can be found in [exitCode] or [message] properties.
-         */
-        public val requiredVersion: String?,
-
-        public val message: String?
-    )
-}
diff --git a/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkSideloader.kt b/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkSideloader.kt
deleted file mode 100644
index 9dfb51a..0000000
--- a/tracing/tracing-perfetto-common/src/main/java/androidx/tracing/perfetto/PerfettoSdkSideloader.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.tracing.perfetto
-
-import java.io.File
-import java.util.zip.ZipFile
-
-/**
- * Sideloads the `libtracing_perfetto.so` file to a location available to the traced app
- *
- * The class solves the following sub-problems:
- * - knowing the right location to place the binaries
- * - knowing how to extract the binaries from an AAR or APK, including choosing the right build
- *   variant for the device (e.g. arm64-v8a) from the archive
- * - knowing how to handle device IO permissions, e.g. to allow a Benchmark app place
- *   the Perfetto binaries in a location accessible by the benchmarked app (we use `shell` for this)
- */
-internal class PerfettoSdkSideloader(private val packageName: String) {
-
-    /**
-     * Sideloads `libtracing_perfetto.so` from a ZIP source to a location available to the traced
-     * app
-     *
-     * @param sourceZipFile either an AAR or an APK containing `libtracing_perfetto.so`
-     * @param shellCommandExecutor function capable of executing adb shell commands (used to
-     * determine the device ABI)
-     * @param tempDirectory a directory directly accessible to the process (used for extraction
-     * of the binaries from the zip)
-     * @param moveLibFileFromTmpDirToAppDir a function capable of moving the binary file from
-     * the [tempDirectory] and an app accessible folder
-     *
-     * @return location where the library file was sideloaded to
-     */
-    fun sideloadFromZipFile(
-        sourceZipFile: File,
-        tempDirectory: File,
-        shellCommandExecutor: ShellCommandExecutor,
-        moveLibFileFromTmpDirToAppDir: FileMover
-    ): File {
-        val abi = getDeviceAbi(shellCommandExecutor)
-        val tmpFile = extractPerfettoBinaryFromZip(sourceZipFile, tempDirectory, abi)
-        return sideloadSoFile(tmpFile, moveLibFileFromTmpDirToAppDir)
-    }
-
-    /**
-     * Sideloads `libtracing_perfetto.so` to a location available to the traced app
-     *
-     * @param libFile `libtracing_perfetto.so` file
-     * @param moveLibFileToAppDir a function moving the [libFile] to an app accessible folder
-     *
-     * @return location where the library file was sideloaded to
-     */
-    private fun sideloadSoFile(libFile: File, moveLibFileToAppDir: FileMover): File {
-        val dstFile = libFileForPackageName(packageName)
-        moveLibFileToAppDir(libFile, dstFile)
-        return dstFile
-    }
-
-    private fun extractPerfettoBinaryFromZip(
-        sourceZip: File,
-        outputDir: File,
-        abi: String
-    ): File {
-        val outputFile = outputDir.resolve(libFileName)
-        val rxLibPathInsideZip = Regex(".*(lib|jni)/[^/]*$abi[^/]*/$libFileName")
-        val zipFile = ZipFile(sourceZip)
-        val entry = zipFile
-            .entries()
-            .asSequence()
-            .firstOrNull { it.name.matches(rxLibPathInsideZip) }
-            ?: throw IllegalStateException(
-                "Unable to locate $libFileName required to enable Perfetto SDK. " +
-                    "Tried inside ${sourceZip.absolutePath}."
-            )
-        zipFile.getInputStream(entry).use { inputStream ->
-            outputFile.outputStream().use { outputStream ->
-                inputStream.copyTo(outputStream)
-            }
-        }
-        return outputFile
-    }
-
-    private fun getDeviceAbi(executeShellCommand: ShellCommandExecutor): String =
-        executeShellCommand("getprop ro.product.cpu.abilist").split(",")
-            .plus(executeShellCommand("getprop ro.product.cpu.abi"))
-            .first()
-            .trim()
-
-    private companion object {
-        private const val libFileName = "libtracing_perfetto.so"
-
-        fun libFileForPackageName(packageName: String) =
-            File("/sdcard/Android/media/$packageName/$libFileName")
-    }
-}
-
-internal typealias FileMover = (srcFile: File, dstFile: File) -> Unit
-
-internal typealias ShellCommandExecutor = (command: String) -> String
\ No newline at end of file
diff --git a/tracing/tracing-perfetto-handshake/api/current.txt b/tracing/tracing-perfetto-handshake/api/current.txt
new file mode 100644
index 0000000..9aa8915
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/api/current.txt
@@ -0,0 +1,39 @@
+// Signature format: 4.0
+package androidx.tracing.perfetto.handshake {
+
+  public final class PerfettoSdkHandshake {
+    ctor public PerfettoSdkHandshake(String targetPackage, kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.util.Map<java.lang.String,java.lang.String>> parseJsonMap, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.String> executeShellCommand);
+    method public androidx.tracing.perfetto.handshake.protocol.EnableTracingResponse enableTracingColdStart(kotlin.jvm.functions.Function0<kotlin.Unit> killAppProcess, androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.LibrarySource? librarySource);
+    method public androidx.tracing.perfetto.handshake.protocol.EnableTracingResponse enableTracingImmediate(optional androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.LibrarySource? librarySource);
+  }
+
+  public static final class PerfettoSdkHandshake.LibrarySource {
+    ctor public PerfettoSdkHandshake.LibrarySource(java.io.File libraryZip, java.io.File tempDirectory, kotlin.jvm.functions.Function2<? super java.io.File,? super java.io.File,kotlin.Unit> moveLibFileFromTmpDirToAppDir);
+  }
+
+}
+
+package androidx.tracing.perfetto.handshake.protocol {
+
+  public final class EnableTracingResponse {
+    method public int getExitCode();
+    method public String? getMessage();
+    method public String? getRequiredVersion();
+    property public final int exitCode;
+    property public final String? message;
+    property public final String? requiredVersion;
+  }
+
+  public final class ResponseExitCodes {
+    field public static final androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes INSTANCE;
+    field public static final int RESULT_CODE_ALREADY_ENABLED = 2; // 0x2
+    field public static final int RESULT_CODE_CANCELLED = 0; // 0x0
+    field public static final int RESULT_CODE_ERROR_BINARY_MISSING = 11; // 0xb
+    field public static final int RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR = 13; // 0xd
+    field public static final int RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH = 12; // 0xc
+    field public static final int RESULT_CODE_ERROR_OTHER = 99; // 0x63
+    field public static final int RESULT_CODE_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/tracing/tracing-perfetto-handshake/api/restricted_current.txt b/tracing/tracing-perfetto-handshake/api/restricted_current.txt
new file mode 100644
index 0000000..9aa8915
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/api/restricted_current.txt
@@ -0,0 +1,39 @@
+// Signature format: 4.0
+package androidx.tracing.perfetto.handshake {
+
+  public final class PerfettoSdkHandshake {
+    ctor public PerfettoSdkHandshake(String targetPackage, kotlin.jvm.functions.Function1<? super java.lang.String,? extends java.util.Map<java.lang.String,java.lang.String>> parseJsonMap, kotlin.jvm.functions.Function1<? super java.lang.String,java.lang.String> executeShellCommand);
+    method public androidx.tracing.perfetto.handshake.protocol.EnableTracingResponse enableTracingColdStart(kotlin.jvm.functions.Function0<kotlin.Unit> killAppProcess, androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.LibrarySource? librarySource);
+    method public androidx.tracing.perfetto.handshake.protocol.EnableTracingResponse enableTracingImmediate(optional androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.LibrarySource? librarySource);
+  }
+
+  public static final class PerfettoSdkHandshake.LibrarySource {
+    ctor public PerfettoSdkHandshake.LibrarySource(java.io.File libraryZip, java.io.File tempDirectory, kotlin.jvm.functions.Function2<? super java.io.File,? super java.io.File,kotlin.Unit> moveLibFileFromTmpDirToAppDir);
+  }
+
+}
+
+package androidx.tracing.perfetto.handshake.protocol {
+
+  public final class EnableTracingResponse {
+    method public int getExitCode();
+    method public String? getMessage();
+    method public String? getRequiredVersion();
+    property public final int exitCode;
+    property public final String? message;
+    property public final String? requiredVersion;
+  }
+
+  public final class ResponseExitCodes {
+    field public static final androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes INSTANCE;
+    field public static final int RESULT_CODE_ALREADY_ENABLED = 2; // 0x2
+    field public static final int RESULT_CODE_CANCELLED = 0; // 0x0
+    field public static final int RESULT_CODE_ERROR_BINARY_MISSING = 11; // 0xb
+    field public static final int RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR = 13; // 0xd
+    field public static final int RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH = 12; // 0xc
+    field public static final int RESULT_CODE_ERROR_OTHER = 99; // 0x63
+    field public static final int RESULT_CODE_SUCCESS = 1; // 0x1
+  }
+
+}
+
diff --git a/tracing/tracing-perfetto-handshake/build.gradle b/tracing/tracing-perfetto-handshake/build.gradle
new file mode 100644
index 0000000..1081279
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/build.gradle
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.BuildServerConfigurationKt
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("java-library")
+    id("kotlin")
+}
+
+dependencies {
+    compileOnly(libs.kotlinStdlib)
+    api("androidx.annotation:annotation:1.3.0")
+}
+
+tasks.withType(Jar) {
+    destinationDirectory.set(BuildServerConfigurationKt.getDistributionDirectory(rootProject))
+}
+
+androidx {
+    name = "Tracing Perfetto Handshake"
+    publish = Publish.SNAPSHOT_AND_RELEASE
+    mavenVersion = LibraryVersions.TRACING_PERFETTO
+    inceptionYear = "2022"
+    description = "AndroidX Tracing: Perfetto Handshake"
+}
diff --git a/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkHandshake.kt b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkHandshake.kt
new file mode 100644
index 0000000..026828e
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkHandshake.kt
@@ -0,0 +1,192 @@
+/*
+ * 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.tracing.perfetto.handshake
+
+import androidx.tracing.perfetto.handshake.protocol.EnableTracingResponse
+import androidx.tracing.perfetto.handshake.protocol.RequestKeys.ACTION_ENABLE_TRACING
+import androidx.tracing.perfetto.handshake.protocol.RequestKeys.ACTION_ENABLE_TRACING_COLD_START
+import androidx.tracing.perfetto.handshake.protocol.RequestKeys.KEY_PATH
+import androidx.tracing.perfetto.handshake.protocol.RequestKeys.KEY_PERSISTENT
+import androidx.tracing.perfetto.handshake.protocol.RequestKeys.RECEIVER_CLASS_NAME
+import androidx.tracing.perfetto.handshake.protocol.ResponseExitCodes
+import androidx.tracing.perfetto.handshake.protocol.ResponseKeys.KEY_EXIT_CODE
+import androidx.tracing.perfetto.handshake.protocol.ResponseKeys.KEY_MESSAGE
+import androidx.tracing.perfetto.handshake.protocol.ResponseKeys.KEY_REQUIRED_VERSION
+import java.io.File
+
+/**
+ * Handshake implementation allowing to enable Perfetto SDK tracing in an app that enables it.
+ *
+ * @param targetPackage package name of the target app
+ * @param parseJsonMap function parsing a flat map in a JSON format into a `Map<String, String>`
+ * e.g. `"{ 'key 1': 'value 1', 'key 2': 'value 2' }"` ->
+ * `mapOf("key 1" to "value 1", "key 2" to "value 2")`
+ * @param executeShellCommand function allowing to execute `adb shell` commands on the target device
+ *
+ * For error handling, note that [parseJsonMap] and [executeShellCommand] will be called on the same
+ * thread as [enableTracingImmediate] and [enableTracingColdStart].
+ */
+public class PerfettoSdkHandshake(
+    private val targetPackage: String,
+    private val parseJsonMap: (jsonString: String) -> Map<String, String>,
+    private val executeShellCommand: ShellCommandExecutor
+) {
+    /**
+     * Attempts to enable tracing in an app. It will wake up (or start) the app process, so it will
+     * act as warm/hot tracing. For cold tracing see [enableTracingColdStart]
+     *
+     * Note: if the app process is not running, it will be launched making the method a bad choice
+     * for cold tracing (use [enableTracingColdStart] instead.
+     *
+     * @param librarySource optional AAR or an APK containing `libtracing_perfetto.so`
+     */
+    public fun enableTracingImmediate(
+        librarySource: LibrarySource? = null
+    ): EnableTracingResponse {
+        val libPath = librarySource?.run {
+            PerfettoSdkSideloader(targetPackage).sideloadFromZipFile(
+                libraryZip,
+                tempDirectory,
+                executeShellCommand,
+                moveLibFileFromTmpDirToAppDir
+            )
+        }
+        return sendEnableTracingBroadcast(libPath, coldStart = false)
+    }
+
+    /**
+     * Attempts to prepare cold startup tracing in an app.
+     *
+     * @param killAppProcess function responsible for terminating the app process (no-op if the
+     * process is already terminated)
+     * @param librarySource optional AAR or an APK containing `libtracing_perfetto.so`
+     */
+    public fun enableTracingColdStart(
+        killAppProcess: () -> Unit,
+        librarySource: LibrarySource?
+    ): EnableTracingResponse {
+        // sideload the `libtracing_perfetto.so` file if applicable
+        val libPath = librarySource?.run {
+            PerfettoSdkSideloader(targetPackage).sideloadFromZipFile(
+                libraryZip,
+                tempDirectory,
+                executeShellCommand,
+                moveLibFileFromTmpDirToAppDir
+            )
+        }
+
+        // ensure a clean start (e.g. in case tracing is already enabled)
+        killAppProcess()
+
+        // verify (by performing a regular handshake) that we can enable tracing at app startup
+        val response = sendEnableTracingBroadcast(libPath, coldStart = true, persistent = false)
+        if (response.exitCode == ResponseExitCodes.RESULT_CODE_SUCCESS) {
+            // terminate the app process (that we woke up by issuing a broadcast earlier)
+            killAppProcess()
+        }
+
+        return response
+    }
+
+    private fun sendEnableTracingBroadcast(
+        libPath: File? = null,
+        coldStart: Boolean,
+        persistent: Boolean? = null
+    ): EnableTracingResponse {
+        val action = if (coldStart) ACTION_ENABLE_TRACING_COLD_START else ACTION_ENABLE_TRACING
+        val commandBuilder = StringBuilder("am broadcast -a $action")
+        if (persistent != null) commandBuilder.append(" --es $KEY_PERSISTENT $persistent")
+        if (libPath != null) commandBuilder.append(" --es $KEY_PATH $libPath")
+        commandBuilder.append(" $targetPackage/$RECEIVER_CLASS_NAME")
+
+        val rawResponse = executeShellCommand(commandBuilder.toString())
+
+        val response = try {
+            parseResponse(rawResponse)
+        } catch (e: IllegalArgumentException) {
+            val message = "Exception occurred while trying to parse a response." +
+                " Error: ${e.message}. Raw response: $rawResponse."
+            EnableTracingResponse(ResponseExitCodes.RESULT_CODE_ERROR_OTHER, null, message)
+        }
+        return response
+    }
+
+    private fun parseResponse(rawResponse: String): EnableTracingResponse {
+        val line = rawResponse
+            .split(Regex("\r?\n"))
+            .firstOrNull { it.contains("Broadcast completed: result=") }
+            ?: throw IllegalArgumentException("Cannot parse: $rawResponse")
+
+        if (line == "Broadcast completed: result=0") return EnableTracingResponse(
+            ResponseExitCodes.RESULT_CODE_CANCELLED, null, null
+        )
+
+        val matchResult =
+            Regex("Broadcast completed: (result=.*?)(, data=\".*?\")?(, extras: .*)?")
+                .matchEntire(line)
+                ?: throw IllegalArgumentException("Cannot parse: $rawResponse")
+
+        val broadcastResponseCode = matchResult
+            .groups[1]
+            ?.value
+            ?.substringAfter("result=")
+            ?.toIntOrNull()
+
+        val dataString = matchResult
+            .groups
+            .firstOrNull { it?.value?.startsWith(", data=") ?: false }
+            ?.value
+            ?.substringAfter(", data=\"")
+            ?.dropLast(1)
+            ?: throw IllegalArgumentException("Cannot parse: $rawResponse. " +
+                "Unable to detect 'data=' section."
+            )
+
+        val dataMap = parseJsonMap(dataString)
+        val response = EnableTracingResponse(
+            dataMap[KEY_EXIT_CODE]?.toInt()
+                ?: throw IllegalArgumentException("Response missing $KEY_EXIT_CODE value"),
+            dataMap[KEY_REQUIRED_VERSION]
+                ?: throw IllegalArgumentException("Response missing $KEY_REQUIRED_VERSION value"),
+            dataMap[KEY_MESSAGE]
+        )
+
+        if (broadcastResponseCode != response.exitCode) {
+            throw IllegalStateException(
+                "Cannot parse: $rawResponse. Exit code " +
+                    "not matching broadcast exit code."
+            )
+        }
+
+        return response
+    }
+
+    /**
+    * @param libraryZip either an AAR or an APK containing `libtracing_perfetto.so`
+    * @param tempDirectory a directory directly accessible to the caller process (used for
+     * extraction of the binaries from the zip)
+    * @param moveLibFileFromTmpDirToAppDir a function capable of moving the binary file from
+    * the [tempDirectory] to an app accessible folder
+    */
+    // TODO(245426369): consider moving to a factory pattern for constructing these and refer to
+    //  this one as `aarLibrarySource` and `apkLibrarySource`
+    public class LibrarySource @Suppress("StreamFiles") constructor(
+        internal val libraryZip: File,
+        internal val tempDirectory: File,
+        internal val moveLibFileFromTmpDirToAppDir: FileMover
+    )
+}
diff --git a/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkSideloader.kt b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkSideloader.kt
new file mode 100644
index 0000000..df50de5
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/PerfettoSdkSideloader.kt
@@ -0,0 +1,113 @@
+/*
+ * 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.tracing.perfetto.handshake
+
+import java.io.File
+import java.util.zip.ZipFile
+
+/**
+ * Sideloads the `libtracing_perfetto.so` file to a location available to the traced app
+ *
+ * The class solves the following sub-problems:
+ * - knowing the right location to place the binaries
+ * - knowing how to extract the binaries from an AAR or APK, including choosing the right build
+ *   variant for the device (e.g. arm64-v8a) from the archive
+ * - knowing how to handle device IO permissions, e.g. to allow a Benchmark app place
+ *   the Perfetto binaries in a location accessible by the benchmarked app (we use `shell` for this)
+ */
+internal class PerfettoSdkSideloader(private val packageName: String) {
+
+    /**
+     * Sideloads `libtracing_perfetto.so` from a ZIP source to a location available to the traced
+     * app
+     *
+     * @param sourceZipFile either an AAR or an APK containing `libtracing_perfetto.so`
+     * @param shellCommandExecutor function capable of executing adb shell commands (used to
+     * determine the device ABI)
+     * @param tempDirectory a directory directly accessible to the process (used for extraction
+     * of the binaries from the zip)
+     * @param moveLibFileFromTmpDirToAppDir a function capable of moving the binary file from
+     * the [tempDirectory] and an app accessible folder
+     *
+     * @return location where the library file was sideloaded to
+     */
+    fun sideloadFromZipFile(
+        sourceZipFile: File,
+        tempDirectory: File,
+        shellCommandExecutor: ShellCommandExecutor,
+        moveLibFileFromTmpDirToAppDir: FileMover
+    ): File {
+        val abi = getDeviceAbi(shellCommandExecutor)
+        val tmpFile = extractPerfettoBinaryFromZip(sourceZipFile, tempDirectory, abi)
+        return sideloadSoFile(tmpFile, moveLibFileFromTmpDirToAppDir)
+    }
+
+    /**
+     * Sideloads `libtracing_perfetto.so` to a location available to the traced app
+     *
+     * @param libFile `libtracing_perfetto.so` file
+     * @param moveLibFileToAppDir a function moving the [libFile] to an app accessible folder
+     *
+     * @return location where the library file was sideloaded to
+     */
+    private fun sideloadSoFile(libFile: File, moveLibFileToAppDir: FileMover): File {
+        val dstFile = libFileForPackageName(packageName)
+        moveLibFileToAppDir(libFile, dstFile)
+        return dstFile
+    }
+
+    private fun extractPerfettoBinaryFromZip(
+        sourceZip: File,
+        outputDir: File,
+        abi: String
+    ): File {
+        val outputFile = outputDir.resolve(libFileName)
+        val rxLibPathInsideZip = Regex(".*(lib|jni)/[^/]*$abi[^/]*/$libFileName")
+        val zipFile = ZipFile(sourceZip)
+        val entry = zipFile
+            .entries()
+            .asSequence()
+            .firstOrNull { it.name.matches(rxLibPathInsideZip) }
+            ?: throw IllegalStateException(
+                "Unable to locate $libFileName required to enable Perfetto SDK. " +
+                    "Tried inside ${sourceZip.absolutePath}."
+            )
+        zipFile.getInputStream(entry).use { inputStream ->
+            outputFile.outputStream().use { outputStream ->
+                inputStream.copyTo(outputStream)
+            }
+        }
+        return outputFile
+    }
+
+    private fun getDeviceAbi(executeShellCommand: ShellCommandExecutor): String =
+        executeShellCommand("getprop ro.product.cpu.abilist").split(",")
+            .plus(executeShellCommand("getprop ro.product.cpu.abi"))
+            .first()
+            .trim()
+
+    private companion object {
+        private const val libFileName = "libtracing_perfetto.so"
+
+        fun libFileForPackageName(packageName: String) =
+            File("/sdcard/Android/media/$packageName/$libFileName")
+    }
+}
+
+internal typealias FileMover = (srcFile: File, dstFile: File) -> Unit
+
+internal typealias ShellCommandExecutor = (command: String) -> String
\ No newline at end of file
diff --git a/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/protocol/Protocol.kt b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/protocol/Protocol.kt
new file mode 100644
index 0000000..fbc0553
--- /dev/null
+++ b/tracing/tracing-perfetto-handshake/src/main/java/androidx/tracing/perfetto/handshake/protocol/Protocol.kt
@@ -0,0 +1,183 @@
+/*
+ * 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.tracing.perfetto.handshake.protocol
+
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
+
+// Keep these two packages in sync:
+// - `androidx.tracing.perfetto.handshake.protocol` in the tracing/tracing-perfetto-common folder
+// - `androidx.tracing.perfetto.internal.handshake.protocol` in the tracing/tracing-perfetto folder
+//
+// This is a part of a WIP refactor to decouple tracing-perfetto and tracing-perfetto-common and to
+// rename tracing-perfetto-common to tracing-perfetto-handshake tracked under TODO(243405142)
+
+@RestrictTo(LIBRARY_GROUP)
+public object RequestKeys {
+    public const val RECEIVER_CLASS_NAME: String = "androidx.tracing.perfetto.TracingReceiver"
+
+    /**
+     * Request to enable tracing in an app.
+     *
+     * The action is performed straight away allowing for warm / hot tracing. For cold start
+     * tracing see [ACTION_ENABLE_TRACING_COLD_START]
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
+     * - [ResponseKeys.KEY_MESSAGE] (optional)
+     */
+    public const val ACTION_ENABLE_TRACING: String =
+        "androidx.tracing.perfetto.action.ENABLE_TRACING"
+
+    /**
+     * Request to enable cold start tracing in an app.
+     *
+     * For warm / hot tracing, see [ACTION_ENABLE_TRACING].
+     *
+     * The action must be performed in the following order, otherwise its effects are
+     * unspecified:
+     * - the app process must be killed before performing the action
+     * - the action must then follow
+     * - the app process must be killed after performing the action
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     * Request can include [KEY_PERSISTENT] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
+     * - [ResponseKeys.KEY_MESSAGE] (optional)
+     */
+    public const val ACTION_ENABLE_TRACING_COLD_START: String =
+        "androidx.tracing.perfetto.action.ENABLE_TRACING_COLD_START"
+
+    /**
+     * Request to disable cold start tracing (previously enabled with
+     * [ACTION_ENABLE_TRACING_COLD_START]).
+     *
+     * The action is particularly useful when cold start tracing was enabled in
+     * [KEY_PERSISTENT] mode.
+     *
+     * The action must be performed in the following order, otherwise its effects are
+     * unspecified:
+     * - the app process must be killed before performing the action
+     * - the action must then follow
+     * - the app process must be killed after performing the action
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     * Request can include [KEY_PERSISTENT] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     */
+    public const val ACTION_DISABLE_TRACING_COLD_START: String =
+        "androidx.tracing.perfetto.action.DISABLE_TRACING_COLD_START"
+
+    /** Path to tracing native binary file */
+    public const val KEY_PATH: String = "path"
+
+    /**
+     * Boolean flag to signify whether the operation should be persistent between runs
+     * (or only performed once).
+     *
+     * Applies to [ACTION_ENABLE_TRACING_COLD_START]
+     */
+    public const val KEY_PERSISTENT: String = "persistent"
+}
+
+@RestrictTo(LIBRARY_GROUP)
+public object ResponseKeys {
+    /** Exit code as listed in [ResponseExitCodes]. */
+    public const val KEY_EXIT_CODE: String = "exitCode"
+
+    /**
+     * Required version of the binaries. Java and binary library versions have to match to
+     * ensure compatibility. In the Maven format, e.g. 1.2.3-beta01.
+     */
+    public const val KEY_REQUIRED_VERSION: String = "requiredVersion"
+
+    /**
+     * Message string that gives more information about the response, e.g. recovery steps
+     * if applicable.
+     */
+    public const val KEY_MESSAGE: String = "message"
+}
+
+public object ResponseExitCodes {
+    /**
+     * Indicates that the broadcast resulted in `result=0`, which is an equivalent
+     * of [android.app.Activity.RESULT_CANCELED].
+     *
+     * This most likely means that the app does not expose a [PerfettoSdkHandshake] compatible
+     * receiver.
+     */
+    @Suppress("KDocUnresolvedReference")
+    public const val RESULT_CODE_CANCELLED: Int = 0
+
+    public const val RESULT_CODE_SUCCESS: Int = 1
+    public const val RESULT_CODE_ALREADY_ENABLED: Int = 2
+
+    /**
+     * Required version described in [EnableTracingResponse.requiredVersion].
+     * A follow-up [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.enableTracingImmediate]
+     * request expected with binaries to sideload specified.
+     */
+    public const val RESULT_CODE_ERROR_BINARY_MISSING: Int = 11
+
+    /** Required version described in [EnableTracingResponse.requiredVersion]. */
+    public const val RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH: Int = 12
+
+    /**
+     * Could be a result of a stale version of the binary cached locally.
+     * Retrying with a freshly downloaded library likely to fix the issue.
+     * More specific information in [EnableTracingResponse.message]
+     */
+    public const val RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR: Int = 13
+
+    /** More specific information in [EnableTracingResponse.message] */
+    public const val RESULT_CODE_ERROR_OTHER: Int = 99
+}
+
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+    ResponseExitCodes.RESULT_CODE_CANCELLED,
+    ResponseExitCodes.RESULT_CODE_SUCCESS,
+    ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR,
+    ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+)
+private annotation class EnableTracingResultCode
+
+public class EnableTracingResponse @RestrictTo(LIBRARY_GROUP) constructor(
+    @EnableTracingResultCode public val exitCode: Int,
+
+    /**
+     * This can be `null` iff we cannot communicate with the broadcast receiver of the target
+     * process (e.g. app does not offer Perfetto tracing) or if we cannot parse the response
+     * from the receiver. In either case, tracing is unlikely to work under these circumstances,
+     * and more context on how to proceed can be found in [exitCode] or [message] properties.
+     */
+    public val requiredVersion: String?,
+
+    public val message: String?
+)
diff --git a/tracing/tracing-perfetto/build.gradle b/tracing/tracing-perfetto/build.gradle
index 257bb64..71b9af5 100644
--- a/tracing/tracing-perfetto/build.gradle
+++ b/tracing/tracing-perfetto/build.gradle
@@ -46,7 +46,6 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.3.0")
-    implementation(project(":tracing:tracing-perfetto-common"))
     implementation("androidx.startup:startup-runtime:1.1.1")
     implementation(libs.kotlinStdlib)
     androidTestImplementation(libs.testExtJunit)
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
index 000e3ff..5a70f00 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/jni/test/PerfettoNativeTest.kt
@@ -30,7 +30,7 @@
         init {
             PerfettoNative.loadLib()
         }
-        const val libraryVersion = "1.0.0-alpha16" // TODO: get using reflection
+        const val libraryVersion = "1.0.0-alpha17" // TODO: get using reflection
     }
 
     @Test
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
index 233ee75..257480f 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
@@ -20,9 +20,9 @@
 import androidx.annotation.RequiresApi
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.RECEIVER_CLASS_NAME
 import androidx.tracing.perfetto.Tracing
 import androidx.tracing.perfetto.TracingReceiver
+import androidx.tracing.perfetto.internal.handshake.protocol.RequestKeys.RECEIVER_CLASS_NAME
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/Tracing.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/Tracing.kt
index a97d57f..0e3731f 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/Tracing.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/Tracing.kt
@@ -18,13 +18,13 @@
 import android.content.Context
 import android.os.Build
 import androidx.annotation.RequiresApi
-import androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
+import androidx.tracing.perfetto.internal.handshake.protocol.EnableTracingResponse
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_SUCCESS
 import androidx.tracing.perfetto.jni.PerfettoNative
 import androidx.tracing.perfetto.security.IncorrectChecksumException
 import androidx.tracing.perfetto.security.SafeLibLoader
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
index 43fd4e3..e2d94a9 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
@@ -23,16 +23,16 @@
 import android.util.JsonWriter
 import androidx.annotation.RestrictTo
 import androidx.annotation.RestrictTo.Scope.LIBRARY
-import androidx.tracing.perfetto.PerfettoSdkHandshake.EnableTracingResponse
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.ACTION_ENABLE_TRACING
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.ACTION_ENABLE_TRACING_COLD_START
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.KEY_PATH
-import androidx.tracing.perfetto.PerfettoSdkHandshake.RequestKeys.KEY_PERSISTENT
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
-import androidx.tracing.perfetto.PerfettoSdkHandshake.ResponseKeys
 import androidx.tracing.perfetto.StartupTracingConfigStore.store
 import androidx.tracing.perfetto.Tracing.EnableTracingResponse
+import androidx.tracing.perfetto.internal.handshake.protocol.EnableTracingResponse
+import androidx.tracing.perfetto.internal.handshake.protocol.RequestKeys.ACTION_ENABLE_TRACING
+import androidx.tracing.perfetto.internal.handshake.protocol.RequestKeys.ACTION_ENABLE_TRACING_COLD_START
+import androidx.tracing.perfetto.internal.handshake.protocol.RequestKeys.KEY_PATH
+import androidx.tracing.perfetto.internal.handshake.protocol.RequestKeys.KEY_PERSISTENT
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseExitCodes.RESULT_CODE_SUCCESS
+import androidx.tracing.perfetto.internal.handshake.protocol.ResponseKeys
 import java.io.File
 import java.io.StringWriter
 import java.util.concurrent.LinkedBlockingQueue
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/internal/handshake/protocol/Protocol.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/internal/handshake/protocol/Protocol.kt
new file mode 100644
index 0000000..b9ce584
--- /dev/null
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/internal/handshake/protocol/Protocol.kt
@@ -0,0 +1,183 @@
+/*
+ * 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.tracing.perfetto.internal.handshake.protocol
+
+import androidx.annotation.IntDef
+import androidx.annotation.RestrictTo
+import androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP
+
+// Keep these two packages in sync:
+// - `androidx.tracing.perfetto.handshake.protocol` in the tracing/tracing-perfetto-common folder
+// - `androidx.tracing.perfetto.internal.handshake.protocol` in the tracing/tracing-perfetto folder
+//
+// This is a part of a WIP refactor to decouple tracing-perfetto and tracing-perfetto-common and to
+// rename tracing-perfetto-common to tracing-perfetto-handshake tracked under TODO(243405142)
+
+@RestrictTo(LIBRARY_GROUP)
+internal object RequestKeys {
+    public const val RECEIVER_CLASS_NAME: String = "androidx.tracing.perfetto.TracingReceiver"
+
+    /**
+     * Request to enable tracing in an app.
+     *
+     * The action is performed straight away allowing for warm / hot tracing. For cold start
+     * tracing see [ACTION_ENABLE_TRACING_COLD_START]
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
+     * - [ResponseKeys.KEY_MESSAGE] (optional)
+     */
+    public const val ACTION_ENABLE_TRACING: String =
+        "androidx.tracing.perfetto.action.ENABLE_TRACING"
+
+    /**
+     * Request to enable cold start tracing in an app.
+     *
+     * For warm / hot tracing, see [ACTION_ENABLE_TRACING].
+     *
+     * The action must be performed in the following order, otherwise its effects are
+     * unspecified:
+     * - the app process must be killed before performing the action
+     * - the action must then follow
+     * - the app process must be killed after performing the action
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     * Request can include [KEY_PERSISTENT] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     * - [ResponseKeys.KEY_REQUIRED_VERSION] (always)
+     * - [ResponseKeys.KEY_MESSAGE] (optional)
+     */
+    public const val ACTION_ENABLE_TRACING_COLD_START: String =
+        "androidx.tracing.perfetto.action.ENABLE_TRACING_COLD_START"
+
+    /**
+     * Request to disable cold start tracing (previously enabled with
+     * [ACTION_ENABLE_TRACING_COLD_START]).
+     *
+     * The action is particularly useful when cold start tracing was enabled in
+     * [KEY_PERSISTENT] mode.
+     *
+     * The action must be performed in the following order, otherwise its effects are
+     * unspecified:
+     * - the app process must be killed before performing the action
+     * - the action must then follow
+     * - the app process must be killed after performing the action
+     *
+     * Request can include [KEY_PATH] as an optional extra.
+     * Request can include [KEY_PERSISTENT] as an optional extra.
+     *
+     * Response to the request is a JSON string (to allow for CLI support) with the following:
+     * - [ResponseKeys.KEY_EXIT_CODE] (always)
+     */
+    public const val ACTION_DISABLE_TRACING_COLD_START: String =
+        "androidx.tracing.perfetto.action.DISABLE_TRACING_COLD_START"
+
+    /** Path to tracing native binary file */
+    public const val KEY_PATH: String = "path"
+
+    /**
+     * Boolean flag to signify whether the operation should be persistent between runs
+     * (or only performed once).
+     *
+     * Applies to [ACTION_ENABLE_TRACING_COLD_START]
+     */
+    public const val KEY_PERSISTENT: String = "persistent"
+}
+
+@RestrictTo(LIBRARY_GROUP)
+internal object ResponseKeys {
+    /** Exit code as listed in [ResponseExitCodes]. */
+    public const val KEY_EXIT_CODE: String = "exitCode"
+
+    /**
+     * Required version of the binaries. Java and binary library versions have to match to
+     * ensure compatibility. In the Maven format, e.g. 1.2.3-beta01.
+     */
+    public const val KEY_REQUIRED_VERSION: String = "requiredVersion"
+
+    /**
+     * Message string that gives more information about the response, e.g. recovery steps
+     * if applicable.
+     */
+    public const val KEY_MESSAGE: String = "message"
+}
+
+internal object ResponseExitCodes {
+    /**
+     * Indicates that the broadcast resulted in `result=0`, which is an equivalent
+     * of [android.app.Activity.RESULT_CANCELED].
+     *
+     * This most likely means that the app does not expose a [PerfettoSdkHandshake] compatible
+     * receiver.
+     */
+    @Suppress("KDocUnresolvedReference")
+    public const val RESULT_CODE_CANCELLED: Int = 0
+
+    public const val RESULT_CODE_SUCCESS: Int = 1
+    public const val RESULT_CODE_ALREADY_ENABLED: Int = 2
+
+    /**
+     * Required version described in [EnableTracingResponse.requiredVersion].
+     * A follow-up [androidx.tracing.perfetto.handshake.PerfettoSdkHandshake.enableTracingImmediate]
+     * request expected with binaries to sideload specified.
+     */
+    public const val RESULT_CODE_ERROR_BINARY_MISSING: Int = 11
+
+    /** Required version described in [EnableTracingResponse.requiredVersion]. */
+    public const val RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH: Int = 12
+
+    /**
+     * Could be a result of a stale version of the binary cached locally.
+     * Retrying with a freshly downloaded library likely to fix the issue.
+     * More specific information in [EnableTracingResponse.message]
+     */
+    public const val RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR: Int = 13
+
+    /** More specific information in [EnableTracingResponse.message] */
+    public const val RESULT_CODE_ERROR_OTHER: Int = 99
+}
+
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+    ResponseExitCodes.RESULT_CODE_CANCELLED,
+    ResponseExitCodes.RESULT_CODE_SUCCESS,
+    ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERSION_MISMATCH,
+    ResponseExitCodes.RESULT_CODE_ERROR_BINARY_VERIFICATION_ERROR,
+    ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+)
+private annotation class EnableTracingResultCode
+
+internal class EnableTracingResponse @RestrictTo(LIBRARY_GROUP) constructor(
+    @EnableTracingResultCode public val exitCode: Int,
+
+    /**
+     * This can be `null` iff we cannot communicate with the broadcast receiver of the target
+     * process (e.g. app does not offer Perfetto tracing) or if we cannot parse the response
+     * from the receiver. In either case, tracing is unlikely to work under these circumstances,
+     * and more context on how to proceed can be found in [exitCode] or [message] properties.
+     */
+    public val requiredVersion: String?,
+
+    public val message: String?
+)
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
index 8a461b5..31f40a1 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/jni/PerfettoNative.kt
@@ -25,12 +25,12 @@
 
     // TODO(224510255): load from a file produced at build time
     object Metadata {
-        const val version = "1.0.0-alpha16"
+        const val version = "1.0.0-alpha17"
         val checksums = mapOf(
-            "arm64-v8a" to "202c4b9026b31ec905c1eeb8d899843014436a73bc3f76110372084b11107fde",
-            "armeabi-v7a" to "597dfd46a3111bf1863bcd138e7171783d669078d2ad5cf137695f4310d2f726",
-            "x86" to "606047a8e037a882c3637137f447f93256e1cd3eb680030fa0afbd069b7233ce",
-            "x86_64" to "c2ad4ad2a34b4d98aa5380c3b7639767a131ef0a920648b90689f52d30adc874",
+            "arm64-v8a" to "50caf24da1716eb52974a4554da0d22e5c14ebf0deb40746a84011746ad28c5c",
+            "armeabi-v7a" to "e2c8fd9910635c37e0e59d758cb0418fd14e306d8a4f3962c7ea4f045e820ac2",
+            "x86" to "b8bca8f0792bc4e53db3e13c084f8573bd62c821d994fe92273586107dd5e16c",
+            "x86_64" to "0709dde1c246b249bc80bcbd3ff6ee28c70acf6ff6917b2753f40936056854e0",
         )
     }
 
diff --git a/transition/transition/api/current.txt b/transition/transition/api/current.txt
index fdaded9..672d6db 100644
--- a/transition/transition/api/current.txt
+++ b/transition/transition/api/current.txt
@@ -146,6 +146,7 @@
     method public String getName();
     method public androidx.transition.PathMotion getPathMotion();
     method public androidx.transition.TransitionPropagation? getPropagation();
+    method public final androidx.transition.Transition getRootTransition();
     method public long getStartDelay();
     method public java.util.List<java.lang.Integer!> getTargetIds();
     method public java.util.List<java.lang.String!>? getTargetNames();
@@ -153,6 +154,7 @@
     method public java.util.List<android.view.View!> getTargets();
     method public String![]? getTransitionProperties();
     method public androidx.transition.TransitionValues? getTransitionValues(android.view.View, boolean);
+    method public boolean isSeekingSupported();
     method public boolean isTransitionRequired(androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
     method public androidx.transition.Transition removeListener(androidx.transition.Transition.TransitionListener);
     method public androidx.transition.Transition removeTarget(android.view.View);
@@ -180,9 +182,11 @@
   public static interface Transition.TransitionListener {
     method public void onTransitionCancel(androidx.transition.Transition);
     method public void onTransitionEnd(androidx.transition.Transition);
+    method public default void onTransitionEnd(androidx.transition.Transition, boolean);
     method public void onTransitionPause(androidx.transition.Transition);
     method public void onTransitionResume(androidx.transition.Transition);
     method public void onTransitionStart(androidx.transition.Transition);
+    method public default void onTransitionStart(androidx.transition.Transition, boolean);
   }
 
   public class TransitionInflater {
@@ -204,6 +208,7 @@
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, androidx.transition.Transition?);
+    method public static androidx.transition.TransitionSeekController? controlDelayedTransition(android.view.ViewGroup, androidx.transition.Transition);
     method public static void endTransitions(android.view.ViewGroup?);
     method public static void go(androidx.transition.Scene);
     method public static void go(androidx.transition.Scene, androidx.transition.Transition?);
@@ -219,6 +224,17 @@
     method public abstract long getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
   }
 
+  public interface TransitionSeekController {
+    method public void addOnReadyListener(androidx.core.util.Consumer<androidx.transition.TransitionSeekController!>);
+    method public void animateToEnd();
+    method public void animateToStart();
+    method public long getCurrentPlayTimeMillis();
+    method public long getDurationMillis();
+    method public boolean isReady();
+    method public void removeOnReadyListener(androidx.core.util.Consumer<androidx.transition.TransitionSeekController!>);
+    method public void setCurrentPlayTimeMillis(long);
+  }
+
   public class TransitionSet extends androidx.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
diff --git a/transition/transition/api/restricted_current.txt b/transition/transition/api/restricted_current.txt
index a344c51..187290f 100644
--- a/transition/transition/api/restricted_current.txt
+++ b/transition/transition/api/restricted_current.txt
@@ -172,6 +172,7 @@
     method public String getName();
     method public androidx.transition.PathMotion getPathMotion();
     method public androidx.transition.TransitionPropagation? getPropagation();
+    method public final androidx.transition.Transition getRootTransition();
     method public long getStartDelay();
     method public java.util.List<java.lang.Integer!> getTargetIds();
     method public java.util.List<java.lang.String!>? getTargetNames();
@@ -179,6 +180,7 @@
     method public java.util.List<android.view.View!> getTargets();
     method public String![]? getTransitionProperties();
     method public androidx.transition.TransitionValues? getTransitionValues(android.view.View, boolean);
+    method public boolean isSeekingSupported();
     method public boolean isTransitionRequired(androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void pause(android.view.View?);
     method public androidx.transition.Transition removeListener(androidx.transition.Transition.TransitionListener);
@@ -213,9 +215,11 @@
   public static interface Transition.TransitionListener {
     method public void onTransitionCancel(androidx.transition.Transition);
     method public void onTransitionEnd(androidx.transition.Transition);
+    method public default void onTransitionEnd(androidx.transition.Transition, boolean);
     method public void onTransitionPause(androidx.transition.Transition);
     method public void onTransitionResume(androidx.transition.Transition);
     method public void onTransitionStart(androidx.transition.Transition);
+    method public default void onTransitionStart(androidx.transition.Transition, boolean);
   }
 
   public class TransitionInflater {
@@ -237,6 +241,7 @@
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
     method public static void beginDelayedTransition(android.view.ViewGroup, androidx.transition.Transition?);
+    method public static androidx.transition.TransitionSeekController? controlDelayedTransition(android.view.ViewGroup, androidx.transition.Transition);
     method public static void endTransitions(android.view.ViewGroup?);
     method public static void go(androidx.transition.Scene);
     method public static void go(androidx.transition.Scene, androidx.transition.Transition?);
@@ -252,6 +257,17 @@
     method public abstract long getStartDelay(android.view.ViewGroup, androidx.transition.Transition, androidx.transition.TransitionValues?, androidx.transition.TransitionValues?);
   }
 
+  public interface TransitionSeekController {
+    method public void addOnReadyListener(androidx.core.util.Consumer<androidx.transition.TransitionSeekController!>);
+    method public void animateToEnd();
+    method public void animateToStart();
+    method public long getCurrentPlayTimeMillis();
+    method public long getDurationMillis();
+    method public boolean isReady();
+    method public void removeOnReadyListener(androidx.core.util.Consumer<androidx.transition.TransitionSeekController!>);
+    method public void setCurrentPlayTimeMillis(long);
+  }
+
   public class TransitionSet extends androidx.transition.Transition {
     ctor public TransitionSet();
     ctor public TransitionSet(android.content.Context, android.util.AttributeSet);
diff --git a/transition/transition/build.gradle b/transition/transition/build.gradle
index 1518fbe..b899cd4 100644
--- a/transition/transition/build.gradle
+++ b/transition/transition/build.gradle
@@ -8,7 +8,7 @@
 
 dependencies {
     api("androidx.annotation:annotation:1.2.0")
-    api("androidx.core:core:1.1.0")
+    api(project(":core:core"))
     implementation("androidx.collection:collection:1.1.0")
     compileOnly("androidx.fragment:fragment:1.2.5")
     compileOnly("androidx.appcompat:appcompat:1.0.1")
@@ -22,6 +22,7 @@
     androidTestImplementation(libs.espressoCore, excludes.espresso)
     androidTestImplementation(libs.mockitoCore, excludes.bytebuddy) // DexMaker has it"s own MockMaker
     androidTestImplementation(libs.dexmakerMockito, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+    androidTestImplementation(libs.opentest4j)
     androidTestImplementation(project(":fragment:fragment"))
     androidTestImplementation("androidx.appcompat:appcompat:1.1.0")
     androidTestImplementation(project(":internal-testutils-runtime"), {
diff --git a/transition/transition/src/androidTest/java/androidx/transition/AlwaysTransition.kt b/transition/transition/src/androidTest/java/androidx/transition/AlwaysTransition.kt
new file mode 100644
index 0000000..0ac5f03
--- /dev/null
+++ b/transition/transition/src/androidTest/java/androidx/transition/AlwaysTransition.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.transition
+
+import android.animation.Animator
+import android.animation.ValueAnimator
+import android.view.ViewGroup
+
+/**
+ * A test transition that always provides an animation, regardless of start/end state
+ */
+class AlwaysTransition(private val keyPrefix: String) : Transition() {
+    override fun captureStartValues(transitionValues: TransitionValues) {
+        transitionValues.values[keyPrefix + Key] = AlwaysChangingValue++
+    }
+
+    override fun captureEndValues(transitionValues: TransitionValues) {
+        transitionValues.values[keyPrefix + Key] = AlwaysChangingValue++
+    }
+
+    override fun isSeekingSupported(): Boolean = true
+
+    override fun createAnimator(
+        sceneRoot: ViewGroup,
+        startValues: TransitionValues?,
+        endValues: TransitionValues?
+    ): Animator = ValueAnimator.ofFloat(0f, 100f)
+
+    companion object {
+        private const val Key = "alwaysChanging"
+        private var AlwaysChangingValue = 0
+    }
+}
\ No newline at end of file
diff --git a/transition/transition/src/androidTest/java/androidx/transition/BaseTransitionTest.java b/transition/transition/src/androidTest/java/androidx/transition/BaseTransitionTest.java
index a5b727f..e2ed58e 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/BaseTransitionTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/BaseTransitionTest.java
@@ -17,7 +17,7 @@
 package androidx.transition;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -55,7 +55,7 @@
         mRoot = (LinearLayout) rule.getActivity().findViewById(R.id.root);
         mTransitionTargets.clear();
         mTransition = createTransition();
-        mListener = mock(Transition.TransitionListener.class);
+        mListener = spy(new TransitionListenerAdapter());
         mTransition.addListener(mListener);
     }
 
@@ -113,7 +113,7 @@
 
     void resetListener() {
         mTransition.removeListener(mListener);
-        mListener = mock(Transition.TransitionListener.class);
+        mListener = spy(new TransitionListenerAdapter());
         mTransition.addListener(mListener);
     }
 
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
index c1a8962..3206c710 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeBoundsTest.java
@@ -19,23 +19,33 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.os.Build;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.LinearInterpolator;
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
+import androidx.core.os.BuildCompat;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.transition.test.R;
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 @LargeTest
 public class ChangeBoundsTest extends BaseTransitionTest {
 
@@ -113,7 +123,592 @@
         suppressLayout.ensureExpectedValueApplied();
     }
 
-    private class TestSuppressLayout extends FrameLayout {
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingChangeBoundsNoClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+
+        final View view = viewArr[0];
+        ViewGroup parent = (ViewGroup) view.getParent();
+
+        rule.runOnUiThread(() -> {
+            assertEquals(100, view.getWidth());
+            assertEquals(100, view.getHeight());
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 200;
+            layoutParams.height = 300;
+            view.setLayoutParams(layoutParams);
+        });
+        final TransitionSeekController seekController = seekControllerArr[0];
+        CountDownLatch endLatch = new CountDownLatch(1);
+
+        rule.runOnUiThread(() -> {
+            assertEquals(100, view.getWidth());
+            assertEquals(100, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek past the always there transition before the change bounds
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(100, view.getWidth());
+            assertEquals(100, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek to half through the change bounds
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(150, view.getWidth());
+            assertEquals(200, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek past the ChangeBounds
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(200, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek back to half through the change bounds
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(150, view.getWidth());
+            assertEquals(200, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek before the change bounds:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(100, view.getWidth());
+            assertEquals(100, view.getHeight());
+            assertTrue(parent.isLayoutSuppressed());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            ChangeBounds returnTransition = new ChangeBounds();
+            returnTransition.addListener(new TransitionListenerAdapter() {
+                @Override
+                public void onTransitionEnd(Transition transition) {
+                    endLatch.countDown();
+                }
+            });
+            TransitionManager.beginDelayedTransition(mRoot, returnTransition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 100;
+            layoutParams.height = 100;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 150x200 through and head toward 100x100
+            assertTrue(150 >= view.getWidth());
+            assertTrue(200 >= view.getHeight());
+        });
+
+        assertTrue(endLatch.await(3, TimeUnit.SECONDS));
+        rule.runOnUiThread(() -> {
+            assertFalse(parent.isLayoutSuppressed());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingChangeBoundsWithClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+        ViewGroup parent = (ViewGroup) view.getParent();
+
+        rule.runOnUiThread(() -> {
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 200;
+            view.setLayoutParams(layoutParams);
+        });
+        final TransitionSeekController seekController = seekControllerArr[0];
+        CountDownLatch endLatch = new CountDownLatch(1);
+
+        rule.runOnUiThread(() -> {
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertEquals(new Rect(0, 0, 400, 300), view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek past the always there transition before the change bounds
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertEquals(new Rect(0, 0, 400, 300), view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek to half through the change bounds
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertEquals(new Rect(0, 0, 350, 250), view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek past the ChangeBounds
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(300, view.getWidth());
+            assertEquals(200, view.getHeight());
+            assertNull(view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek back to half through the change bounds
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertEquals(new Rect(0, 0, 350, 250), view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            // Seek before the change bounds:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+            assertNull(view.getClipBounds());
+            assertTrue(parent.isLayoutSuppressed());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            ChangeBounds returnTransition = new ChangeBounds();
+            returnTransition.setResizeClip(true);
+            returnTransition.addListener(new TransitionListenerAdapter() {
+                @Override
+                public void onTransitionEnd(@NonNull Transition transition) {
+                    endLatch.countDown();
+                }
+            });
+            TransitionManager.beginDelayedTransition(mRoot, returnTransition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 200;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 400x500, clipped to 350x250
+            assertEquals(400, view.getWidth());
+            assertEquals(500, view.getHeight());
+            assertTrue(view.getClipBounds().width() <= 350);
+            assertTrue(view.getClipBounds().height() >= 250);
+        });
+
+        assertTrue(endLatch.await(3, TimeUnit.SECONDS));
+        rule.runOnUiThread(() -> {
+            assertEquals(200, view.getWidth());
+            assertEquals(500, view.getHeight());
+            assertFalse(parent.isLayoutSuppressed());
+            assertNull(view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void interruptedBeforeStartNoClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            ChangeBounds change = new ChangeBounds();
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, change);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 100;
+            layoutParams.height = 150;
+            view.setLayoutParams(layoutParams);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            // It should start from 400x300
+            assertEquals(400, view.getWidth());
+            assertEquals(300, view.getHeight());
+
+            // go halfway through
+            seekController.setCurrentPlayTimeMillis(150);
+            assertEquals(250, view.getWidth());
+            assertEquals(225, view.getHeight());
+
+            // skip to the end
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(100, view.getWidth());
+            assertEquals(150, view.getHeight());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void interruptedBeforeStartWithClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            ChangeBounds change = new ChangeBounds();
+            change.setResizeClip(true);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, change);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 600;
+            layoutParams.height = 150;
+            view.setLayoutParams(layoutParams);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            // It should start from 600x500, clipped to 400x300
+            assertEquals(600, view.getWidth());
+            assertEquals(500, view.getHeight());
+            assertEquals(400, view.getClipBounds().width());
+            assertEquals(300, view.getClipBounds().height());
+
+            // go halfway through
+            seekController.setCurrentPlayTimeMillis(150);
+            assertEquals(500, view.getClipBounds().width());
+            assertEquals(225, view.getClipBounds().height());
+
+            // skip to the end
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(600, view.getWidth());
+            assertEquals(150, view.getHeight());
+            assertNull(view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void interruptedAfterEndNoClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+        TransitionSeekController seekController1 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekController1.setCurrentPlayTimeMillis(800);
+            ChangeBounds change = new ChangeBounds();
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, change);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 100;
+            layoutParams.height = 150;
+            view.setLayoutParams(layoutParams);
+        });
+
+        final TransitionSeekController seekController2 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            // It should start from 300x500
+            assertEquals(300, view.getWidth());
+            assertEquals(500, view.getHeight());
+
+            // go halfway through
+            seekController2.setCurrentPlayTimeMillis(150);
+            assertEquals(200, view.getWidth());
+            assertEquals(325, view.getHeight());
+
+            // skip to the end
+            seekController2.setCurrentPlayTimeMillis(300);
+            assertEquals(100, view.getWidth());
+            assertEquals(150, view.getHeight());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void interruptedAfterEndWithClip() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+        TransitionSeekController seekController1 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekController1.setCurrentPlayTimeMillis(800);
+            ChangeBounds change = new ChangeBounds();
+            change.setResizeClip(true);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, change);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 100;
+            layoutParams.height = 150;
+            view.setLayoutParams(layoutParams);
+        });
+
+        final TransitionSeekController seekController2 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            // It should start from 300x500, clipped to 300x500
+            assertEquals(300, view.getWidth());
+            assertEquals(500, view.getHeight());
+            assertEquals(300, view.getClipBounds().width());
+            assertEquals(500, view.getClipBounds().height());
+
+            // go halfway through
+            seekController2.setCurrentPlayTimeMillis(150);
+            assertEquals(200, view.getClipBounds().width());
+            assertEquals(325, view.getClipBounds().height());
+
+            // skip to the end
+            seekController2.setCurrentPlayTimeMillis(300);
+            assertEquals(100, view.getWidth());
+            assertEquals(150, view.getHeight());
+            assertNull(view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void startTransitionAfterSeeking() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        ChangeBounds changeBounds = new ChangeBounds();
+        changeBounds.setResizeClip(true);
+        transition.addTransition(changeBounds);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+        TransitionSeekController seekController1 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekController1.setCurrentPlayTimeMillis(900);
+            seekController1.setCurrentPlayTimeMillis(0);
+
+            ChangeBounds change = new ChangeBounds();
+            change.setResizeClip(true);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, change);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 100;
+            layoutParams.height = 150;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(400, view.getClipBounds().width());
+            assertEquals(300, view.getClipBounds().height());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekNoChange() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(400, 300));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+        TransitionSeekController seekController1 = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekController1.setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] =
+                    TransitionManager.controlDelayedTransition(mRoot, new ChangeBounds());
+            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
+            layoutParams.width = 300;
+            layoutParams.height = 500;
+            view.setLayoutParams(layoutParams);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0, seekControllerArr[0].getDurationMillis());
+            assertEquals(350, view.getWidth());
+            assertEquals(400, view.getHeight());
+
+            // First seek controls the transition
+            seekController1.setCurrentPlayTimeMillis(900);
+            assertEquals(300, view.getWidth());
+            assertEquals(500, view.getHeight());
+        });
+    }
+
+    private static class TestSuppressLayout extends FrameLayout {
 
         private boolean mExpectedSuppressLayout;
         private Boolean mActualSuppressLayout;
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
index fc3808d5..f255f62 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeClipBoundsTest.java
@@ -19,6 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.spy;
@@ -27,8 +28,11 @@
 
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.os.Build;
 import android.view.View;
+import android.view.ViewGroup;
 
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 import androidx.test.filters.LargeTest;
 import androidx.test.filters.SdkSuppress;
@@ -36,6 +40,9 @@
 import org.junit.Test;
 import org.mockito.ArgumentMatcher;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 @LargeTest
 public class ChangeClipBoundsTest extends BaseTransitionTest {
 
@@ -103,6 +110,407 @@
 
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingClipToNull() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            viewArr[0].setClipBounds(new Rect(0, 0, 50, 50));
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+        final View view = viewArr[0];
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(null);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+        ChangeClipBounds returnTransition = new ChangeClipBounds();
+        CountDownLatch latch = new CountDownLatch(1);
+        returnTransition.addListener(new TransitionListenerAdapter() {
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                latch.countDown();
+            }
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek past the always there transition before the clip transition
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 75, 75), view.getClipBounds());
+
+            // Seek past the transition
+            seekController.setCurrentPlayTimeMillis(800);
+            assertNull(view.getClipBounds());
+
+            // Seek back to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 75, 75), view.getClipBounds());
+
+            // Seek before the transition:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, returnTransition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 75x75 and then transition in
+            assertTrue(view.getClipBounds().width() <= 75);
+            assertTrue(view.getClipBounds().height() <= 75);
+        });
+
+        assertTrue(latch.await(3, TimeUnit.SECONDS));
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingClipFromNull() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+        final View view = viewArr[0];
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+        ChangeClipBounds returnTransition = new ChangeClipBounds();
+        CountDownLatch latch = new CountDownLatch(1);
+        returnTransition.addListener(new TransitionListenerAdapter() {
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                latch.countDown();
+            }
+        });
+
+        rule.runOnUiThread(() -> {
+            assertNull(view.getClipBounds());
+
+            // Seek past the always there transition before the clip transition
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(new Rect(0, 0, 100, 100), view.getClipBounds());
+
+            // Seek to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 75, 75), view.getClipBounds());
+
+            // Seek past the transition
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek back to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 75, 75), view.getClipBounds());
+
+            // Seek before the transition:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertNull(view.getClipBounds());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, returnTransition);
+            view.setClipBounds(null);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 75x75 and then transition in
+            assertTrue(view.getClipBounds().width() >= 75);
+            assertTrue(view.getClipBounds().height() >= 75);
+        });
+
+        assertTrue(latch.await(3, TimeUnit.SECONDS));
+        rule.runOnUiThread(() -> {
+            assertNull(view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingClips() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+            viewArr[0].setClipBounds(new Rect(0, 0, 50, 50));
+        });
+        final View view = viewArr[0];
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 80, 80));
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+        ChangeClipBounds returnTransition = new ChangeClipBounds();
+        CountDownLatch latch = new CountDownLatch(1);
+        returnTransition.addListener(new TransitionListenerAdapter() {
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                latch.countDown();
+            }
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek past the always there transition before the clip transition
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 65, 65), view.getClipBounds());
+
+            // Seek past the transition
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(new Rect(0, 0, 80, 80), view.getClipBounds());
+
+            // Seek back to half through the transition
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(new Rect(0, 0, 65, 65), view.getClipBounds());
+
+            // Seek before the transition:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, returnTransition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 75x75 and then transition in
+            assertTrue(view.getClipBounds().width() <= 65);
+            assertTrue(view.getClipBounds().height() <= 65);
+        });
+
+        assertTrue(latch.await(3, TimeUnit.SECONDS));
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void changeClipBeforeStart() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+            viewArr[0].setClipBounds(new Rect(0, 0, 20, 50));
+        });
+        final View view = viewArr[0];
+        rule.runOnUiThread(() -> {
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 80, 80));
+        });
+
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] =
+                    TransitionManager.controlDelayedTransition(mRoot, new ChangeClipBounds());
+            view.setClipBounds(new Rect(0, 0, 100, 100));
+        });
+
+        rule.runOnUiThread(() -> {
+            TransitionSeekController seekController = seekControllerArr[0];
+            // It should start from 20x50 and go to 100x100
+            assertEquals(20, view.getClipBounds().width());
+            assertEquals(50, view.getClipBounds().height());
+
+            // half way through
+            seekController.setCurrentPlayTimeMillis(150);
+            assertEquals(60, view.getClipBounds().width());
+            assertEquals(75, view.getClipBounds().height());
+
+            // finish
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(100, view.getClipBounds().width());
+            assertEquals(100, view.getClipBounds().height());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testSeekInterruption() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // supported on U+
+        }
+        final View view = new View(rule.getActivity());
+
+        rule.runOnUiThread(() -> {
+            mRoot.addView(view, new ViewGroup.LayoutParams(100, 100));
+        });
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        rule.runOnUiThread(() -> {
+            assertNull(view.getClipBounds());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+
+            // Seek back to the beginning
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            assertNull(view.getClipBounds());
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(50, 50, 100, 100));
+        });
+
+        rule.runOnUiThread(() -> {
+            assertNull(view.getClipBounds());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(new Rect(50, 50, 100, 100), view.getClipBounds());
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(null);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(50, 50, 100, 100), view.getClipBounds());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertNull(view.getClipBounds());
+
+            // Seek to the middle
+            seekControllerArr[0].setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(new Rect(25, 25, 100, 100), view.getClipBounds());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testSeekNoChange() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // supported on U+
+        }
+        final View view = new View(rule.getActivity());
+
+        rule.runOnUiThread(() -> {
+            mRoot.addView(view, new ViewGroup.LayoutParams(100, 100));
+        });
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeClipBounds());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        TransitionSeekController firstController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] =
+                    TransitionManager.controlDelayedTransition(mRoot, new ChangeClipBounds());
+            view.setClipBounds(new Rect(0, 0, 50, 50));
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0, seekControllerArr[0].getDurationMillis());
+
+            // Should only be controlled by the first transition
+            firstController.setCurrentPlayTimeMillis(900);
+            assertEquals(new Rect(0, 0, 50, 50), view.getClipBounds());
+        });
+    }
+
     private ArgumentMatcher<Rect> isRectContaining(final Rect rect) {
         return new ArgumentMatcher<Rect>() {
             @Override
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeImageTransformTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeImageTransformTest.java
index 8ddefd7..ebff1c4 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeImageTransformTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeImageTransformTest.java
@@ -40,7 +40,9 @@
 
 import androidx.annotation.NonNull;
 import androidx.core.app.ActivityCompat;
+import androidx.core.os.BuildCompat;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.transition.test.R;
 
@@ -153,6 +155,88 @@
         assertEquals(ImageView.ScaleType.CENTER_CROP, imageView.getScaleType());
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testSeekInterruption() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final ImageView imageView = enterImageViewScene(ImageView.ScaleType.FIT_START,
+                null, false);
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeImageTransform());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
+        });
+
+        rule.runOnUiThread(() -> {
+            verifyMatrixMatches(fitStartMatrix(), getDrawMatrixCompat(imageView));
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            verifyMatrixMatches(fitXYMatrix(), getDrawMatrixCompat(imageView));
+            // Seek back to the beginning
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            verifyMatrixMatches(fitStartMatrix(), getDrawMatrixCompat(imageView));
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            imageView.setScaleType(ImageView.ScaleType.FIT_END);
+        });
+
+        rule.runOnUiThread(() -> {
+            verifyMatrixMatches(fitStartMatrix(), getDrawMatrixCompat(imageView));
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            verifyMatrixMatches(fitEndMatrix(), getDrawMatrixCompat(imageView));
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            imageView.setScaleType(ImageView.ScaleType.FIT_START);
+        });
+
+        rule.runOnUiThread(() -> {
+            verifyMatrixMatches(fitEndMatrix(), getDrawMatrixCompat(imageView));
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            verifyMatrixMatches(fitStartMatrix(), getDrawMatrixCompat(imageView));
+
+            // Seek to the middle
+            seekControllerArr[0].setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
+        });
+
+        rule.runOnUiThread(() -> {
+            verifyMatrixMatches(betweenStartAndEnd(), getDrawMatrixCompat(imageView));
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            verifyMatrixMatches(fitXYMatrix(), getDrawMatrixCompat(imageView));
+        });
+    }
+
+    private Matrix betweenStartAndEnd() {
+        Matrix start = fitStartMatrix();
+        float[] startVals = new float[9];
+        start.getValues(startVals);
+        Matrix end = fitEndMatrix();
+        float[] endVals = new float[9];
+        end.getValues(endVals);
+
+        float[] middleVals = new float[9];
+        for (int i = 0; i < 9; i++) {
+            middleVals[i] = (startVals[i] + endVals[i]) / 2f;
+        }
+        Matrix middle = new Matrix();
+        middle.setValues(middleVals);
+        return middle;
+    }
+
     private Matrix centerMatrix() {
         int imageWidth = mImage.getIntrinsicWidth();
         int imageViewWidth = mImageView.getWidth();
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ChangeScrollTest.java b/transition/transition/src/androidTest/java/androidx/transition/ChangeScrollTest.java
index 3f94b5a..68414e5 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ChangeScrollTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ChangeScrollTest.java
@@ -19,15 +19,21 @@
 import static androidx.transition.AtLeastOnceWithin.atLeastOnceWithin;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalMatchers.and;
 import static org.mockito.AdditionalMatchers.gt;
 import static org.mockito.AdditionalMatchers.leq;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.os.Build;
+import android.view.View;
+import android.view.ViewGroup;
 import android.widget.TextView;
 
+import androidx.core.os.BuildCompat;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.transition.test.R;
 
@@ -76,4 +82,193 @@
         });
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingScroll() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeScroll());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(100);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0, view.getScrollY());
+
+            // Seek past the always there transition before the scroll
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(0, view.getScrollY());
+
+            // Seek to half through the scroll
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(50, view.getScrollY());
+
+            // Seek past the scroll
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(100, view.getScrollY());
+
+            // Seek back to half through the scroll
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(50, view.getScrollY());
+
+            // Seek before the scroll:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(0, view.getScrollY());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, new ChangeScroll());
+            view.setScrollY(0);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 50 and move to 0
+            assertTrue(view.getScrollY() <= 50);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingScrollBeforeStart() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeScroll());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+            viewArr[0].setScrollY(100);
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(200);
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] =
+                    TransitionManager.controlDelayedTransition(mRoot, new ChangeScroll());
+            view.setScrollY(0);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            // Should start from 100 and go to 0
+            assertEquals(100, view.getScrollY());
+
+            // Seek to half through the scroll
+            seekController.setCurrentPlayTimeMillis(150);
+            assertEquals(50, view.getScrollY());
+
+            // Seek to the end
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(0, view.getScrollY());
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void testSeekInterruption() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final View view = new View(rule.getActivity());
+
+        rule.runOnUiThread(() -> {
+            mRoot.addView(view, new ViewGroup.LayoutParams(100, 100));
+        });
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new ChangeScroll());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(100);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0, view.getScrollY());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(100, view.getScrollY());
+
+            // Seek back to the beginning
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            assertEquals(0, view.getScrollY());
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(200);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0, view.getScrollY());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(200, view.getScrollY());
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(50);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(200, view.getScrollY());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(50, view.getScrollY());
+
+            // Seek to the middle
+            seekControllerArr[0].setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setScrollY(500);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals((200 + 50) / 2, view.getScrollY());
+
+            // Seek to the end
+            seekControllerArr[0].setCurrentPlayTimeMillis(900);
+            assertEquals(500, view.getScrollY());
+        });
+    }
 }
diff --git a/transition/transition/src/androidTest/java/androidx/transition/ExplodeTest.java b/transition/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
index 34954a9..7a9fc71 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/ExplodeTest.java
@@ -20,15 +20,22 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
 import android.graphics.Color;
+import android.os.Build;
 import android.view.Gravity;
 import android.view.View;
+import android.view.animation.LinearInterpolator;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
+import androidx.core.os.BuildCompat;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.hamcrest.Description;
@@ -176,6 +183,279 @@
         assertThat(Arrays.asList(1f, 9f, 3f), is(not(decreasing())));
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingExplode() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new Explode());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            this.mRedSquare.setVisibility(View.GONE);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        float[] translationValues = new float[2];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, ViewUtils.getTransitionAlpha(mRedSquare), 0f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+
+            // Seek past the always there transition before the explode
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+
+            // Seek half way:
+            seekController.setCurrentPlayTimeMillis(450);
+            assertNotEquals(0f, mRedSquare.getTranslationX(), 0.01f);
+            assertNotEquals(0f, mRedSquare.getTranslationY(), 0.01f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            translationValues[0] = mRedSquare.getTranslationX();
+            translationValues[1] = mRedSquare.getTranslationY();
+
+            // Seek past the end
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+            assertEquals(View.GONE, mRedSquare.getVisibility());
+
+            // Seek before the explode:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+
+            seekController.setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and decrease
+            assertEquals(translationValues[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(translationValues[1], mRedSquare.getTranslationY(), 1f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingImplode() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        Explode implode = new Explode();
+        implode.setInterpolator(new LinearInterpolator());
+        transition.addTransition(implode);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        rule.runOnUiThread(() -> {
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            mRedSquare.setVisibility(View.VISIBLE);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        float[] translationValues = new float[2];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, ViewUtils.getTransitionAlpha(mRedSquare), 0f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertNotEquals(0f, mRedSquare.getTranslationX(), 0.01f);
+            assertNotEquals(0f, mRedSquare.getTranslationY(), 0.01f);
+
+            float startX = mRedSquare.getTranslationX();
+            float startY = mRedSquare.getTranslationY();
+
+            // Seek past the always there transition before the explode
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(startX, mRedSquare.getTranslationX(), 0f);
+            assertEquals(startY, mRedSquare.getTranslationY(), 0f);
+
+            // Seek half way:
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(startX / 2f, mRedSquare.getTranslationX(), 0.01f);
+            assertEquals(startY / 2f, mRedSquare.getTranslationY(), 0.01f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            translationValues[0] = mRedSquare.getTranslationX();
+            translationValues[1] = mRedSquare.getTranslationY();
+
+            // Seek past the end
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+
+            // Seek before the explode:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+            assertEquals(startX, mRedSquare.getTranslationX(), 0f);
+            assertEquals(startY, mRedSquare.getTranslationY(), 0f);
+
+            seekController.setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and increase
+            assertEquals(translationValues[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(translationValues[1], mRedSquare.getTranslationY(), 1f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(View.GONE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingImplodeBeforeStart() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        Explode implode = new Explode();
+        implode.setInterpolator(new LinearInterpolator());
+        transition.addTransition(implode);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        rule.runOnUiThread(() -> {
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            mRedSquare.setVisibility(View.VISIBLE);
+        });
+
+        float[] translationValues = new float[2];
+
+        rule.runOnUiThread(() -> {
+            translationValues[0] = mRedSquare.getTranslationX();
+            translationValues[1] = mRedSquare.getTranslationY();
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from all the way out
+            assertEquals(translationValues[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(translationValues[1], mRedSquare.getTranslationY(), 1f);
+            assertEquals(View.VISIBLE, mRedSquare.getVisibility());
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(View.GONE, mRedSquare.getVisibility());
+            assertEquals(0f, mRedSquare.getTranslationX(), 0f);
+            assertEquals(0f, mRedSquare.getTranslationY(), 0f);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekWithTranslation() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        rule.runOnUiThread(() -> {
+            mRedSquare.setTranslationX(1f);
+            mRedSquare.setTranslationY(5f);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        final float[] interruptedTranslation = new float[2];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, mRedSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, mRedSquare.getTranslationY(), 0.01f);
+
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(150);
+            interruptedTranslation[0] = mRedSquare.getTranslationX();
+            interruptedTranslation[1] = mRedSquare.getTranslationY();
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and increase
+            assertEquals(interruptedTranslation[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(interruptedTranslation[1], mRedSquare.getTranslationY(), 1f);
+
+            // make sure it would go to the start value
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(1f, mRedSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, mRedSquare.getTranslationY(), 0.01f);
+
+            // Now go back to the interrupted position again:
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            assertEquals(interruptedTranslation[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(interruptedTranslation[1], mRedSquare.getTranslationY(), 1f);
+
+            // Send it back to GONE
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(interruptedTranslation[0], mRedSquare.getTranslationX(), 1f);
+            assertEquals(interruptedTranslation[1], mRedSquare.getTranslationY(), 1f);
+
+            // it should move away (toward the top-left)
+            seekControllerArr[0].setCurrentPlayTimeMillis(299);
+            assertTrue(mRedSquare.getTranslationX() < interruptedTranslation[0]);
+            assertTrue(mRedSquare.getTranslationY() < interruptedTranslation[1]);
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Explode());
+            mRedSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should end up at the initial translation
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(1f, mRedSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, mRedSquare.getTranslationY(), 0.01f);
+        });
+    }
+
     private Matcher<View> hasVisibility(final int visibility) {
         return new TypeSafeMatcher<View>() {
             @Override
diff --git a/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java b/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
index 16a9bbe..a55c8c5 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/FadeTest.java
@@ -25,9 +25,11 @@
 import static org.hamcrest.Matchers.lessThan;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -40,8 +42,10 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.os.BuildCompat;
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.testutils.AnimationDurationScaleRule;
 import androidx.transition.test.R;
@@ -126,7 +130,7 @@
         float[] valuesOut = new float[2];
         final InterruptibleFade fadeOut = new InterruptibleFade(Fade.MODE_OUT, interrupt,
                 valuesOut);
-        final Transition.TransitionListener listenerOut = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerOut = spy(new TransitionListenerAdapter());
         fadeOut.addListener(listenerOut);
         changeVisibility(fadeOut, mRoot, mView, View.INVISIBLE);
         verify(listenerOut, timeout(3000)).onTransitionStart(any(Transition.class));
@@ -137,7 +141,7 @@
         // Fade in
         float[] valuesIn = new float[2];
         final InterruptibleFade fadeIn = new InterruptibleFade(Fade.MODE_IN, null, valuesIn);
-        final Transition.TransitionListener listenerIn = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerIn = spy(new TransitionListenerAdapter());
         fadeIn.addListener(listenerIn);
         changeVisibility(fadeIn, mRoot, mView, View.VISIBLE);
         verify(listenerOut, timeout(3000)).onTransitionPause(any(Transition.class));
@@ -162,7 +166,7 @@
         final Runnable interrupt = mock(Runnable.class);
         float[] valuesIn = new float[2];
         final InterruptibleFade fadeIn = new InterruptibleFade(Fade.MODE_IN, interrupt, valuesIn);
-        final Transition.TransitionListener listenerIn = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerIn = spy(new TransitionListenerAdapter());
         fadeIn.addListener(listenerIn);
         changeVisibility(fadeIn, mRoot, mView, View.VISIBLE);
         verify(listenerIn, timeout(3000)).onTransitionStart(any(Transition.class));
@@ -173,7 +177,7 @@
         // Fade out
         float[] valuesOut = new float[2];
         final InterruptibleFade fadeOut = new InterruptibleFade(Fade.MODE_OUT, null, valuesOut);
-        final Transition.TransitionListener listenerOut = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerOut = spy(new TransitionListenerAdapter());
         fadeOut.addListener(listenerOut);
         changeVisibility(fadeOut, mRoot, mView, View.INVISIBLE);
         verify(listenerIn, timeout(3000)).onTransitionPause(any(Transition.class));
@@ -199,14 +203,14 @@
         });
         // Fade out
         final Fade fadeOut = new Fade(Fade.OUT);
-        final Transition.TransitionListener listenerOut = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerOut = spy(new TransitionListenerAdapter());
         fadeOut.addListener(listenerOut);
         changeVisibility(fadeOut, mRoot, mView, View.INVISIBLE);
         verify(listenerOut, timeout(3000)).onTransitionStart(any(Transition.class));
         verify(listenerOut, timeout(3000)).onTransitionEnd(any(Transition.class));
         // Fade in
         final Fade fadeIn = new Fade(Fade.IN);
-        final Transition.TransitionListener listenerIn = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listenerIn = spy(new TransitionListenerAdapter());
         fadeIn.addListener(listenerIn);
         changeVisibility(fadeIn, mRoot, mView, View.VISIBLE);
         verify(listenerIn, timeout(3000)).onTransitionStart(any(Transition.class));
@@ -237,7 +241,7 @@
         // We don't really care how short the duration is, so let's make it really short
         final Fade fade = new Fade();
         fade.setDuration(1);
-        Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
+        Transition.TransitionListener listener = spy(new TransitionListenerAdapter());
         fade.addListener(listener);
 
         rule.runOnUiThread(new Runnable() {
@@ -262,6 +266,194 @@
         assertNotNull(activity.findViewById(R.id.redSquare));
     }
 
+    @Test
+    public void seekingFadeIn() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new Fade());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+
+        final View view = viewArr[0];
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(0f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+
+            // Seek past the always there transition before the fade
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(0f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.LAYER_TYPE_HARDWARE, view.getLayerType());
+
+            // Seek to half through the fade
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(0.5f, ViewUtils.getTransitionAlpha(view), 0.01f);
+
+            // Seek past the fade
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+            assertEquals(1f, ViewUtils.getTransitionAlpha(view), 0f);
+
+            // Seek back to half through the fade
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(View.LAYER_TYPE_HARDWARE, view.getLayerType());
+            assertEquals(0.5f, ViewUtils.getTransitionAlpha(view), 0f);
+
+            // Seek before the fade:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(0f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, new Fade());
+            view.setVisibility(View.INVISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 0.5 and then fade out
+            assertTrue(ViewUtils.getTransitionAlpha(view) <= 0.5f);
+        });
+    }
+
+    @Test
+    public void seekingFadeOut() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new Fade());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View[] viewArr = new View[1];
+
+        rule.runOnUiThread(() -> {
+            viewArr[0] = new View(activity);
+            mRoot.addView(viewArr[0], new ViewGroup.LayoutParams(100, 100));
+        });
+
+        final View view = viewArr[0];
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            view.setVisibility(View.GONE);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+
+            // Seek past the always there transition before the fade
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(1f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.LAYER_TYPE_HARDWARE, view.getLayerType());
+
+            // Seek to half through the fade
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(0.5f, ViewUtils.getTransitionAlpha(view), 0.01f);
+
+            // Seek past the fade
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+            assertEquals(1f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.GONE, view.getVisibility());
+
+            // Seek back to half through the fade
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(View.LAYER_TYPE_HARDWARE, view.getLayerType());
+            assertEquals(0.5f, ViewUtils.getTransitionAlpha(view), 0f);
+
+            // Seek before the fade:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(1f, ViewUtils.getTransitionAlpha(view), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+            assertEquals(View.LAYER_TYPE_NONE, view.getLayerType());
+
+            seekController.setCurrentPlayTimeMillis(450);
+            TransitionManager.beginDelayedTransition(mRoot, transition);
+            view.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from 0.5 and then fade in
+            assertTrue(ViewUtils.getTransitionAlpha(view) >= 0.5f);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingFadeInBeforeStart() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new Fade());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View view = new View(rule.getActivity());
+
+        // Animate it in
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            mRoot.addView(view, new ViewGroup.LayoutParams(100, 100));
+        });
+
+        rule.runOnUiThread(() -> {
+            // Starts off invisible
+            assertEquals(0f, view.getTransitionAlpha(), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+
+            // Fade all the way in
+            seekControllerArr[0].setCurrentPlayTimeMillis(600);
+            assertEquals(1f, view.getTransitionAlpha(), 0f);
+            assertEquals(View.VISIBLE, view.getVisibility());
+
+            // Fade out again
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            assertEquals(0f, view.getTransitionAlpha(), 0f);
+
+            // Animate to GONE
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Fade());
+            view.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It is already not shown, so it can just go straight to GONE
+            assertEquals(1f, view.getTransitionAlpha(), 0f);
+            assertEquals(View.GONE, view.getVisibility());
+        });
+    }
+
     private void changeVisibility(final Fade fade, final ViewGroup container, final View target,
             final int visibility) throws Throwable {
         rule.runOnUiThread(new Runnable() {
diff --git a/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionSupportTest.java b/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionSupportTest.java
index 70e3f16..91efb1c 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionSupportTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionSupportTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -213,8 +213,8 @@
         }
 
         private Transition createTransition(int type) {
-            final Transition.TransitionListener listener = mock(
-                    Transition.TransitionListener.class);
+            final Transition.TransitionListener listener = spy(
+                    new TransitionListenerAdapter());
             final AutoTransition transition = new AutoTransition();
             transition.addListener(listener);
             transition.setDuration(10);
diff --git a/transition/transition/src/androidTest/java/androidx/transition/MultipleRootsTest.java b/transition/transition/src/androidTest/java/androidx/transition/MultipleRootsTest.java
index 131351b..57ea293 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/MultipleRootsTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/MultipleRootsTest.java
@@ -19,7 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -98,9 +98,9 @@
         final ActivityScenario<TransitionActivity> scenario = prepareScenario(views);
 
         final Transition.TransitionListener innerListener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
         final Transition.TransitionListener outerListener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
 
         final Fade innerTransition = new Fade();
         innerTransition.setDuration(300);
@@ -143,9 +143,9 @@
         final ActivityScenario<TransitionActivity> scenario = prepareScenario(views);
 
         final Transition.TransitionListener innerListener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
         final Transition.TransitionListener outerListener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
 
         final Fade outerTransition = new Fade();
         outerTransition.setDuration(300);
@@ -188,9 +188,9 @@
         final ActivityScenario<TransitionActivity> scenario = prepareScenario(views);
 
         final Transition.TransitionListener row1Listener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
         final Transition.TransitionListener row2Listener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
 
         final Fade row1Transition = new Fade();
         row1Transition.setDuration(300);
@@ -234,7 +234,7 @@
 
         // For Row 1, we run a subsequent transition at the end of the first transition.
         final Transition.TransitionListener row1SecondListener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
         final Fade row1SecondTransition = new Fade();
         row1SecondTransition.setDuration(250);
         row1SecondTransition.addListener(row1SecondListener);
@@ -253,7 +253,7 @@
 
         // Only one transition for row 2.
         final Transition.TransitionListener row2Listener =
-                mock(Transition.TransitionListener.class);
+                spy(new TransitionListenerAdapter());
         final Slide row2Transition = new Slide();
         row2Transition.setDuration(300);
         row2Transition.addListener(row2Listener);
diff --git a/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt b/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
new file mode 100644
index 0000000..36f41b2
--- /dev/null
+++ b/transition/transition/src/androidTest/java/androidx/transition/SeekTransitionTest.kt
@@ -0,0 +1,946 @@
+/*
+ * 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.transition
+
+import android.graphics.Color
+import android.os.Build
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.LinearInterpolator
+import android.widget.LinearLayout
+import androidx.core.os.BuildCompat
+import androidx.core.util.Consumer
+import androidx.test.annotation.UiThreadTest
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.testutils.AnimationDurationScaleRule.Companion.createForAllTests
+import androidx.transition.Transition.TransitionListener
+import androidx.transition.test.R
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.fail
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.any
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.timeout
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+@MediumTest
+class SeekTransitionTest : BaseTest() {
+    @get:Rule
+    val animationDurationScaleRule = createForAllTests(1f)
+
+    lateinit var view: View
+    lateinit var root: LinearLayout
+    lateinit var transition: Transition
+
+    @UiThreadTest
+    @Before
+    fun setUp() {
+        InstrumentationRegistry.getInstrumentation().setInTouchMode(false)
+        root = rule.activity.findViewById<View>(R.id.root) as LinearLayout
+        transition = Fade().also {
+            it.interpolator = LinearInterpolator()
+        }
+        view = View(root.context)
+        view.setBackgroundColor(Color.BLUE)
+        root.addView(view, ViewGroup.LayoutParams(100, 100))
+    }
+
+    @Test(expected = IllegalArgumentException::class)
+    @UiThreadTest
+    fun onlySeekingTransitions() {
+        if (!BuildCompat.isAtLeastU()) throw IllegalArgumentException()
+        transition = object : Visibility() {}
+        TransitionManager.controlDelayedTransition(root, transition)
+        fail("Expected IllegalArgumentException")
+    }
+
+    @Test
+    fun waitForReady() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        @Suppress("UNCHECKED_CAST")
+        val readyCall: Consumer<TransitionSeekController> =
+            mock(Consumer::class.java) as Consumer<TransitionSeekController>
+
+        rule.runOnUiThread {
+            val controller = TransitionManager.controlDelayedTransition(root, transition)
+            assertThat(controller).isNotNull()
+            seekController = controller!!
+            assertThat(seekController.isReady).isFalse()
+            seekController.addOnReadyListener(readyCall)
+            view.visibility = View.GONE
+        }
+
+        verify(readyCall, timeout(3000)).accept(seekController)
+        assertThat(seekController.isReady).isTrue()
+    }
+
+    @Test
+    fun waitForReadyNoChange() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        @Suppress("UNCHECKED_CAST")
+        val readyCall: Consumer<TransitionSeekController> =
+            mock(Consumer::class.java) as Consumer<TransitionSeekController>
+
+        rule.runOnUiThread {
+            val controller = TransitionManager.controlDelayedTransition(root, transition)
+            assertThat(controller).isNotNull()
+            seekController = controller!!
+            assertThat(seekController.isReady).isFalse()
+            seekController.addOnReadyListener(readyCall)
+            view.requestLayout()
+        }
+
+        verify(readyCall, timeout(3000)).accept(seekController)
+    }
+
+    @Test
+    fun addListenerAfterReady() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        @Suppress("UNCHECKED_CAST")
+        val readyCall: Consumer<TransitionSeekController> =
+            mock(Consumer::class.java) as Consumer<TransitionSeekController>
+
+        rule.runOnUiThread {
+            val controller = TransitionManager.controlDelayedTransition(root, transition)
+            assertThat(controller).isNotNull()
+            seekController = controller!!
+            assertThat(seekController.isReady).isFalse()
+            seekController.addOnReadyListener(readyCall)
+            view.visibility = View.GONE
+        }
+
+        verify(readyCall, timeout(3000)).accept(seekController)
+
+        @Suppress("UNCHECKED_CAST")
+        val readyCall2: Consumer<TransitionSeekController> =
+            mock(Consumer::class.java) as Consumer<TransitionSeekController>
+
+        seekController.addOnReadyListener(readyCall2)
+        verify(readyCall, times(1)).accept(seekController)
+    }
+
+    @Test
+    fun seekTransition() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        rule.runOnUiThread {
+            val controller = TransitionManager.controlDelayedTransition(root, transition)
+            assertThat(controller).isNotNull()
+            seekController = controller!!
+            assertThat(seekController.isReady).isFalse()
+            view.visibility = View.GONE
+        }
+
+        verify(listener, timeout(1000)).onTransitionStart(any())
+        verify(listener, times(0)).onTransitionEnd(any())
+
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+
+            assertThat(seekController.durationMillis).isEqualTo(300)
+            assertThat(seekController.currentPlayTimeMillis).isEqualTo(0)
+
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+
+            seekController.currentPlayTimeMillis = 150
+            assertThat(view.transitionAlpha).isEqualTo(0.5f)
+            seekController.currentPlayTimeMillis = 299
+            assertThat(view.transitionAlpha).isWithin(0.001f).of(1f / 300f)
+            seekController.currentPlayTimeMillis = 300
+
+            verify(listener, times(1)).onTransitionEnd(any())
+
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun animationDoesNotTakeOverSeek() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val stateListener1 = spy(TransitionListenerAdapter())
+        transition.addListener(stateListener1)
+        rule.runOnUiThread {
+            val controller = TransitionManager.controlDelayedTransition(root, transition)
+            assertThat(controller).isNotNull()
+            seekController = controller!!
+            assertThat(seekController.isReady).isFalse()
+            view.visibility = View.GONE
+        }
+
+        verify(stateListener1, timeout(3000)).onTransitionStart(any())
+
+        val stateListener2 = spy(TransitionListenerAdapter())
+        val transition2 = Fade()
+        transition2.addListener(stateListener2)
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            TransitionManager.beginDelayedTransition(root, transition2)
+            view.visibility = View.GONE
+        }
+
+        verify(stateListener2, timeout(3000)).onTransitionStart(any())
+        verify(stateListener2, timeout(3000)).onTransitionEnd(any())
+        verify(stateListener1, times(0)).onTransitionEnd(any())
+        verify(stateListener1, times(0)).onTransitionCancel(any())
+
+        rule.runOnUiThread {
+            // Seek is still controlling the visibility
+            assertThat(view.transitionAlpha).isEqualTo(0.5f)
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+
+            seekController.currentPlayTimeMillis = 300
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun seekCannotTakeOverAnimation() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val stateListener1 = spy(TransitionListenerAdapter())
+        transition.addListener(stateListener1)
+        transition.duration = 1000
+        transition.addListener(TransitionListenerAdapter())
+        rule.runOnUiThread {
+            TransitionManager.beginDelayedTransition(root, transition)
+            view.visibility = View.GONE
+        }
+
+        verify(stateListener1, timeout(3000)).onTransitionStart(any())
+
+        val stateListener2 = spy(TransitionListenerAdapter())
+        val transition2 = Fade()
+        transition2.duration = 3000
+        transition2.addListener(stateListener2)
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition2)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            // The second transition doesn't have any animations in it because it didn't take over.
+            assertThat(seekController.isReady).isTrue()
+            assertThat(seekController.durationMillis).isEqualTo(0)
+        }
+
+        // The first animation should continue
+        verify(stateListener1, timeout(3000)).onTransitionEnd(any())
+
+        // The animation is ended
+        assertThat(view.transitionAlpha).isEqualTo(1f)
+        assertThat(view.visibility).isEqualTo(View.GONE)
+    }
+
+    @Test
+    fun seekCannotTakeOverSeek() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController1: TransitionSeekController
+
+        val stateListener1 = spy(TransitionListenerAdapter())
+        transition.addListener(stateListener1)
+        transition.duration = 3000
+        rule.runOnUiThread {
+            seekController1 = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            assertThat(seekController1.isReady).isTrue()
+        }
+
+        val stateListener2 = spy(TransitionListenerAdapter())
+        val transition2 = Fade()
+        transition2.duration = 3000
+        transition2.addListener(stateListener2)
+
+        rule.runOnUiThread {
+            seekController1.currentPlayTimeMillis = 1500
+            // First transition should be started now
+            verify(stateListener1, times(1)).onTransitionStart(any())
+            TransitionManager.controlDelayedTransition(root, transition2)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            // second transition should just start/end immediately
+            verify(stateListener2, times(1)).onTransitionStart(any())
+            verify(stateListener2, times(1)).onTransitionEnd(any())
+
+            // first transition should still be controllable
+            verify(stateListener1, times(0)).onTransitionEnd(any())
+
+            // second transition should be ready and taking over the previous animation
+            assertThat(view.transitionAlpha).isEqualTo(0.5f)
+            seekController1.currentPlayTimeMillis = 3000
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun seekReplacesSeek() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController1: TransitionSeekController
+
+        val stateListener1 = spy(TransitionListenerAdapter())
+        transition.addListener(stateListener1)
+        transition.duration = 3000
+        rule.runOnUiThread {
+            seekController1 = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        verify(stateListener1, timeout(3000)).onTransitionStart(any())
+
+        val stateListener2 = spy(TransitionListenerAdapter())
+        val transition2 = Fade()
+        transition2.duration = 3000
+        transition2.addListener(stateListener2)
+
+        lateinit var seekController2: TransitionSeekController
+        rule.runOnUiThread {
+            seekController1.currentPlayTimeMillis = 1500
+            seekController2 = TransitionManager.controlDelayedTransition(root, transition2)!!
+            view.visibility = View.VISIBLE
+        }
+
+        verify(stateListener2, timeout(3000)).onTransitionStart(any())
+        rule.runOnUiThread {}
+        verify(stateListener1, times(1)).onTransitionEnd(any())
+        assertThat(seekController2.isReady).isTrue()
+
+        rule.runOnUiThread {
+            verify(stateListener2, never()).onTransitionEnd(any())
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(0.5f)
+            seekController2.currentPlayTimeMillis = 3000
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            verify(stateListener2, times(1)).onTransitionEnd(any())
+        }
+    }
+
+    @Test
+    fun animateToEnd() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            seekController.animateToEnd()
+        }
+
+        verify(listener, timeout(3000)).onTransitionEnd(any())
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            val runningTransitions = TransitionManager.getRunningTransitions()
+            assertThat(runningTransitions[root]).isEmpty()
+        }
+    }
+
+    @Test
+    fun animateToStart() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            seekController.animateToStart()
+        }
+
+        verify(listener, timeout(3000)).onTransitionEnd(any())
+        val listener2 = spy(TransitionListenerAdapter())
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+
+            // Now set it back to the original state with a fast transition
+            transition.removeListener(listener)
+            transition.addListener(listener2)
+            transition.duration = 0
+            TransitionManager.beginDelayedTransition(root, transition)
+            view.visibility = View.VISIBLE
+            root.invalidate()
+        }
+        verify(listener2, timeout(3000)).onTransitionStart(any())
+        rule.runOnUiThread {
+            verify(listener2, times(1)).onTransitionEnd(any())
+            // All transitions should be ended
+            val runningTransitions = TransitionManager.getRunningTransitions()
+            assertThat(runningTransitions[root]).isEmpty()
+        }
+    }
+
+    @Test
+    fun animateToStartAfterAnimateToEnd() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            seekController.animateToEnd()
+        }
+
+        rule.runOnUiThread {
+            seekController.animateToStart()
+        }
+
+        verify(listener, timeout(3000)).onTransitionEnd(any())
+
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+        }
+    }
+
+    @Test
+    fun animateToEndAfterAnimateToStart() {
+        if (!BuildCompat.isAtLeastU()) return
+        lateinit var seekController: TransitionSeekController
+
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            seekController.animateToStart()
+        }
+
+        rule.runOnUiThread {
+            seekController.animateToEnd()
+        }
+
+        verify(listener, timeout(3000)).onTransitionEnd(any())
+
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+        }
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun seekAfterAnimate() {
+        if (!BuildCompat.isAtLeastU()) throw IllegalStateException("Not supported before U")
+        lateinit var seekController: TransitionSeekController
+        transition.duration = 5000
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 150
+            seekController.animateToEnd()
+        }
+
+        rule.runOnUiThread {
+            seekController.currentPlayTimeMillis = 120
+        }
+    }
+
+    @Test
+    fun seekTransitionSet() {
+        if (!BuildCompat.isAtLeastU()) return
+        transition = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+        }
+        val view2 = View(root.context)
+        view2.setBackgroundColor(Color.GREEN)
+
+        val view3 = View(root.context)
+        view3.setBackgroundColor(Color.RED)
+
+        rule.runOnUiThread {
+            root.addView(view2, ViewGroup.LayoutParams(100, 100))
+            root.addView(view3, ViewGroup.LayoutParams(100, 100))
+            view2.visibility = View.GONE
+        }
+
+        lateinit var seekController: TransitionSeekController
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view2.visibility = View.VISIBLE
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            assertThat(seekController.durationMillis).isEqualTo(600)
+            assertThat(seekController.currentPlayTimeMillis).isEqualTo(0)
+            seekController.currentPlayTimeMillis = 0
+
+            // We should be at the start
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(0f)
+
+            // seek to the end of the fade out
+            seekController.currentPlayTimeMillis = 300
+
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(0f)
+
+            // seek to the end of transition
+            seekController.currentPlayTimeMillis = 600
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(1f)
+
+            // seek back to the middle
+            seekController.currentPlayTimeMillis = 300
+
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(0f)
+
+            // back to the beginning
+            seekController.currentPlayTimeMillis = 0
+
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(1f)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(0f)
+        }
+    }
+
+    @Test
+    fun animateToEndTransitionSet() {
+        if (!BuildCompat.isAtLeastU()) return
+        transition = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+        }
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        val view2 = View(root.context)
+        view2.setBackgroundColor(Color.GREEN)
+
+        val view3 = View(root.context)
+        view3.setBackgroundColor(Color.RED)
+
+        rule.runOnUiThread {
+            root.addView(view2, ViewGroup.LayoutParams(100, 100))
+            root.addView(view3, ViewGroup.LayoutParams(100, 100))
+            view2.visibility = View.GONE
+        }
+
+        lateinit var seekController: TransitionSeekController
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view2.visibility = View.VISIBLE
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            verify(listener, times(0)).onTransitionEnd(any())
+            // seek to the end of the fade out
+            seekController.currentPlayTimeMillis = 300
+            verify(listener, times(0)).onTransitionEnd(any())
+
+            seekController.animateToEnd()
+        }
+        verify(listener, timeout(3000)).onTransitionEnd(any())
+
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.GONE)
+            assertThat(view2.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view2.transitionAlpha).isEqualTo(1f)
+            val runningTransitions = TransitionManager.getRunningTransitions()
+            assertThat(runningTransitions[root]).isEmpty()
+        }
+    }
+
+    @Test
+    fun animateToStartTransitionSet() {
+        if (!BuildCompat.isAtLeastU()) return
+        transition = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+        }
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        val view2 = View(root.context)
+        view2.setBackgroundColor(Color.GREEN)
+
+        val view3 = View(root.context)
+        view3.setBackgroundColor(Color.RED)
+
+        rule.runOnUiThread {
+            root.addView(view2, ViewGroup.LayoutParams(100, 100))
+            root.addView(view3, ViewGroup.LayoutParams(100, 100))
+            view2.visibility = View.GONE
+        }
+
+        lateinit var seekController: TransitionSeekController
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view2.visibility = View.VISIBLE
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            // seek to near the end of the fade out
+            seekController.currentPlayTimeMillis = 299
+
+            seekController.animateToStart()
+        }
+        verify(listener, timeout(3000)).onTransitionEnd(any(), eq(true))
+        verify(listener, never()).onTransitionEnd(any(), eq(false))
+        verify(listener, times(1)).onTransitionEnd(any(), eq(true))
+
+        val transition2 = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+            it.duration = 0
+        }
+
+        val listener2 = spy(TransitionListenerAdapter())
+        transition2.addListener(listener2)
+        rule.runOnUiThread {
+            TransitionManager.beginDelayedTransition(root, transition2)
+            view.visibility = View.VISIBLE
+            view2.visibility = View.GONE
+        }
+        verify(listener2, timeout(3000)).onTransitionStart(any(), eq(false))
+
+        rule.runOnUiThread {
+            verify(listener, times(1)).onTransitionCancel(any())
+            verify(listener, times(1)).onTransitionEnd(any(), eq(false))
+            verify(listener2, times(1)).onTransitionEnd(any())
+            val runningTransitions = TransitionManager.getRunningTransitions()
+            assertThat(runningTransitions[root]).isEmpty()
+        }
+    }
+
+    @Test
+    fun cancelPartOfTransitionSet() {
+        if (!BuildCompat.isAtLeastU()) return
+        transition = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+        }
+        val listener = spy(TransitionListenerAdapter())
+        transition.addListener(listener)
+
+        val view2 = View(root.context)
+        view2.setBackgroundColor(Color.GREEN)
+
+        val view3 = View(root.context)
+        view3.setBackgroundColor(Color.RED)
+
+        rule.runOnUiThread {
+            root.addView(view2, ViewGroup.LayoutParams(100, 100))
+            root.addView(view3, ViewGroup.LayoutParams(100, 100))
+            view2.visibility = View.GONE
+        }
+
+        lateinit var seekController: TransitionSeekController
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view2.visibility = View.VISIBLE
+            view.visibility = View.GONE
+        }
+
+        val transition2 = TransitionSet().also {
+            it.addTransition(Fade(Fade.MODE_OUT))
+                .addTransition(Fade(Fade.MODE_IN))
+                .ordering = TransitionSet.ORDERING_SEQUENTIAL
+        }
+
+        val listener2 = spy(TransitionListenerAdapter())
+        transition2.addListener(listener2)
+
+        rule.runOnUiThread {
+            // seek to the end of the fade out
+            seekController.currentPlayTimeMillis = 300
+            TransitionManager.beginDelayedTransition(root, transition2)
+            // Undo making the view visible
+            view2.visibility = View.GONE
+        }
+        verify(listener2, timeout(3000)).onTransitionStart(any())
+        verify(listener2, timeout(3000)).onTransitionEnd(any())
+
+        // The first transition shouldn't end. You can still control it.
+        verify(listener, times(0)).onTransitionEnd(any())
+
+        rule.runOnUiThread {
+            // view2 should now be gone
+            assertThat(view2.visibility).isEqualTo(View.GONE)
+            assertThat(view2.transitionAlpha).isEqualTo(1f)
+
+            // Try to seek further. It should not affect view2 because that transition should be
+            // canceled.
+            seekController.currentPlayTimeMillis = 600
+            assertThat(view2.visibility).isEqualTo(View.GONE)
+            assertThat(view2.transitionAlpha).isEqualTo(1f)
+
+            verify(listener, times(1)).onTransitionEnd(any())
+        }
+    }
+
+    @Test
+    fun onTransitionCallsForwardAndReversed() {
+        if (!BuildCompat.isAtLeastU()) return
+        val listener = spy(TransitionListenerAdapter())
+        transition = Fade()
+        transition.addListener(listener)
+
+        lateinit var seekController: TransitionSeekController
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+        rule.runOnUiThread {
+            verifyCallCounts(listener, startForward = 1)
+            seekController.currentPlayTimeMillis = 300
+            verifyCallCounts(listener, startForward = 1, endForward = 1)
+            seekController.currentPlayTimeMillis = 150
+            verifyCallCounts(listener, startForward = 1, endForward = 1, startReverse = 1)
+            seekController.currentPlayTimeMillis = 0
+            verifyCallCounts(
+                listener,
+                startForward = 1,
+                endForward = 1,
+                startReverse = 1,
+                endReverse = 1
+            )
+        }
+    }
+
+    @Test
+    fun onTransitionCallsForwardAndReversedTransitionSet() {
+        if (!BuildCompat.isAtLeastU()) return
+        val fadeOut = Fade(Fade.MODE_OUT)
+        val outListener = spy(TransitionListenerAdapter())
+        fadeOut.addListener(outListener)
+        val fadeIn = Fade(Fade.MODE_IN)
+        val inListener = spy(TransitionListenerAdapter())
+        fadeIn.addListener(inListener)
+        val set = TransitionSet()
+        set.addTransition(fadeOut)
+        set.addTransition(fadeIn)
+        set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL)
+        val setListener = spy(TransitionListenerAdapter())
+        set.addListener(setListener)
+
+        val view2 = View(view.context)
+
+        lateinit var seekController: TransitionSeekController
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, set)!!
+            view.visibility = View.GONE
+            root.addView(view2, ViewGroup.LayoutParams(100, 100))
+        }
+
+        rule.runOnUiThread {
+            verifyCallCounts(setListener, startForward = 1)
+            verifyCallCounts(outListener, startForward = 1)
+            verifyCallCounts(inListener)
+            seekController.currentPlayTimeMillis = 301
+            verifyCallCounts(setListener, startForward = 1)
+            verifyCallCounts(outListener, startForward = 1, endForward = 1)
+            verifyCallCounts(inListener, startForward = 1)
+            seekController.currentPlayTimeMillis = 600
+            verifyCallCounts(setListener, startForward = 1, endForward = 1)
+            verifyCallCounts(outListener, startForward = 1, endForward = 1)
+            verifyCallCounts(inListener, startForward = 1, endForward = 1)
+            seekController.currentPlayTimeMillis = 301
+            verifyCallCounts(setListener, startForward = 1, endForward = 1, startReverse = 1)
+            verifyCallCounts(outListener, startForward = 1, endForward = 1)
+            verifyCallCounts(inListener, startForward = 1, endForward = 1, startReverse = 1)
+            seekController.currentPlayTimeMillis = 299
+            verifyCallCounts(setListener, startForward = 1, endForward = 1, startReverse = 1)
+            verifyCallCounts(outListener, startForward = 1, endForward = 1, startReverse = 1)
+            verifyCallCounts(
+                inListener,
+                startForward = 1,
+                endForward = 1,
+                startReverse = 1,
+                endReverse = 1
+            )
+            seekController.currentPlayTimeMillis = 0
+            verifyCallCounts(
+                setListener,
+                startForward = 1,
+                endForward = 1,
+                startReverse = 1,
+                endReverse = 1
+            )
+            verifyCallCounts(
+                outListener,
+                startForward = 1,
+                endForward = 1,
+                startReverse = 1,
+                endReverse = 1
+            )
+            verifyCallCounts(
+                inListener,
+                startForward = 1,
+                endForward = 1,
+                startReverse = 1,
+                endReverse = 1
+            )
+        }
+    }
+
+    private fun verifyCallCounts(
+        listener: TransitionListener,
+        startForward: Int = 0,
+        endForward: Int = 0,
+        startReverse: Int = 0,
+        endReverse: Int = 0
+    ) {
+        verify(listener, times(startForward)).onTransitionStart(any(), eq(false))
+        verify(listener, times(endForward)).onTransitionEnd(any(), eq(false))
+        verify(listener, times(startReverse)).onTransitionStart(any(), eq(true))
+        verify(listener, times(endReverse)).onTransitionEnd(any(), eq(true))
+    }
+
+    @Test
+    fun pauseResumeOnSeek() {
+        if (!BuildCompat.isAtLeastU()) return
+        var pauseCount = 0
+        var resumeCount = 0
+        var setPauseCount = 0
+        var setResumeCount = 0
+        val set = TransitionSet().also {
+            it.addTransition(Fade().apply {
+                addListener(object : TransitionListenerAdapter() {
+                    override fun onTransitionPause(transition: Transition) {
+                        pauseCount++
+                    }
+
+                    override fun onTransitionResume(transition: Transition) {
+                        resumeCount++
+                    }
+                })
+            })
+            it.addListener(object : TransitionListenerAdapter() {
+                override fun onTransitionPause(transition: Transition) {
+                    setPauseCount++
+                }
+
+                override fun onTransitionResume(transition: Transition) {
+                    setResumeCount++
+                }
+            })
+        }
+        transition = TransitionSet().also {
+            it.addTransition(AlwaysTransition("before"))
+            it.addTransition(set)
+            it.setOrdering(TransitionSet.ORDERING_SEQUENTIAL)
+        }
+
+        lateinit var seekController: TransitionSeekController
+        lateinit var view: View
+
+        rule.runOnUiThread {
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view = View(rule.activity)
+            root.addView(view, ViewGroup.LayoutParams(100, 100))
+        }
+
+        rule.runOnUiThread {
+            assertThat(view.visibility).isEqualTo(View.VISIBLE)
+            assertThat(view.transitionAlpha).isEqualTo(0f)
+
+            // Move it to the end and then back to the beginning:
+            seekController.currentPlayTimeMillis = 600
+            seekController.currentPlayTimeMillis = 0
+
+            seekController = TransitionManager.controlDelayedTransition(root, transition)!!
+            view.visibility = View.GONE
+        }
+
+        rule.runOnUiThread {
+            assertThat(pauseCount).isEqualTo(1)
+            assertThat(resumeCount).isEqualTo(1)
+            assertThat(setPauseCount).isEqualTo(1)
+            assertThat(setResumeCount).isEqualTo(1)
+        }
+    }
+}
diff --git a/transition/transition/src/androidTest/java/androidx/transition/SlideEdgeTest.java b/transition/transition/src/androidTest/java/androidx/transition/SlideEdgeTest.java
index 7858f8c..e0af8b2 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/SlideEdgeTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/SlideEdgeTest.java
@@ -19,23 +19,29 @@
 import static androidx.transition.AtLeastOnceWithin.atLeastOnceWithin;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.AdditionalMatchers.and;
 import static org.mockito.AdditionalMatchers.eq;
 import static org.mockito.AdditionalMatchers.gt;
 import static org.mockito.AdditionalMatchers.lt;
 import static org.mockito.AdditionalMatchers.not;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
 import android.graphics.Color;
+import android.os.Build;
 import android.view.Gravity;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.LinearInterpolator;
 
+import androidx.core.os.BuildCompat;
 import androidx.core.util.Pair;
 import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -81,7 +87,7 @@
             int slideEdge = SLIDE_EDGES.get(i).first;
             final Slide slide = new Slide(slideEdge);
             final Transition.TransitionListener listener =
-                    mock(Transition.TransitionListener.class);
+                    spy(new TransitionListenerAdapter());
             slide.addListener(listener);
 
             final View redSquare = spy(new View(rule.getActivity()));
@@ -149,7 +155,7 @@
             int slideEdge = pair.first;
             final Slide slide = new Slide(slideEdge);
             final Transition.TransitionListener listener =
-                    mock(Transition.TransitionListener.class);
+                    spy(new TransitionListenerAdapter());
             slide.addListener(listener);
 
 
@@ -212,6 +218,249 @@
         }
     }
 
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingSlideOut() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        transition.addTransition(new Slide());
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View redSquare = new View(activity);
+        redSquare.setBackgroundColor(Color.RED);
+        rule.runOnUiThread(() -> {
+            mRoot.addView(redSquare, new ViewGroup.LayoutParams(100, 100));
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            redSquare.setVisibility(View.GONE);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        float[] translationValues = new float[1];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, ViewUtils.getTransitionAlpha(redSquare), 0f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+
+            // Seek past the always there transition before the slide
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+
+            // Seek half way:
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(0f, redSquare.getTranslationX(), 0.01f);
+            assertNotEquals(0f, redSquare.getTranslationY(), 0.01f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            translationValues[0] = redSquare.getTranslationY();
+
+            // Seek past the end
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+            assertEquals(View.GONE, redSquare.getVisibility());
+
+            // Seek before the slide:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+
+            seekController.setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and decrease
+            assertEquals(0, redSquare.getTranslationX(), 0.01f);
+            assertEquals(translationValues[0], redSquare.getTranslationY(), 1f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+        });
+    }
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekingSlideIn() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+
+        TransitionSet transition = new TransitionSet();
+        transition.addTransition(new AlwaysTransition("before"));
+        Slide slide = new Slide();
+        slide.setInterpolator(new LinearInterpolator());
+        transition.addTransition(slide);
+        transition.addTransition(new AlwaysTransition("after"));
+        transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
+
+        View redSquare = new View(activity);
+        redSquare.setBackgroundColor(Color.RED);
+        rule.runOnUiThread(() -> {
+            mRoot.addView(redSquare, new ViewGroup.LayoutParams(100, 100));
+            redSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, transition);
+            redSquare.setVisibility(View.VISIBLE);
+        });
+
+        final TransitionSeekController seekController = seekControllerArr[0];
+
+        float[] translationValues = new float[1];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, ViewUtils.getTransitionAlpha(redSquare), 0f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0.01f);
+            assertTrue(redSquare.getTranslationY() >= mRoot.getHeight());
+
+            float startY = redSquare.getTranslationY();
+
+            // Seek past the always there transition before the slide
+            seekController.setCurrentPlayTimeMillis(300);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(startY, redSquare.getTranslationY(), 0f);
+
+            // Seek half way:
+            seekController.setCurrentPlayTimeMillis(450);
+            assertEquals(0f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(startY / 2f, redSquare.getTranslationY(), 0.01f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            translationValues[0] = redSquare.getTranslationY();
+
+            // Seek past the end
+            seekController.setCurrentPlayTimeMillis(800);
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+
+            // Seek before the slide:
+            seekController.setCurrentPlayTimeMillis(250);
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+            assertEquals(0, redSquare.getTranslationX(), 0f);
+            assertEquals(startY, redSquare.getTranslationY(), 0f);
+
+            seekController.setCurrentPlayTimeMillis(450);
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and increase
+            assertEquals(0f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(translationValues[0], redSquare.getTranslationY(), 1f);
+
+            assertEquals(View.VISIBLE, redSquare.getVisibility());
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(View.GONE, redSquare.getVisibility());
+            assertEquals(0f, redSquare.getTranslationX(), 0f);
+            assertEquals(0f, redSquare.getTranslationY(), 0f);
+        });
+    }
+
+
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    @Test
+    public void seekWithTranslation() throws Throwable {
+        if (!BuildCompat.isAtLeastU()) {
+            return; // only supported on U+
+        }
+        final TransitionActivity activity = rule.getActivity();
+        TransitionSeekController[] seekControllerArr = new TransitionSeekController[1];
+        View redSquare = new View(activity);
+        redSquare.setBackgroundColor(Color.RED);
+        rule.runOnUiThread(() -> {
+            mRoot.addView(redSquare, new ViewGroup.LayoutParams(100, 100));
+            redSquare.setTranslationX(1f);
+            redSquare.setTranslationY(5f);
+        });
+
+        rule.runOnUiThread(() -> {
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.GONE);
+        });
+
+        final float[] interruptedTranslation = new float[1];
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, redSquare.getTranslationY(), 0.01f);
+
+
+            seekControllerArr[0].setCurrentPlayTimeMillis(150);
+            interruptedTranslation[0] = redSquare.getTranslationY();
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should start from half way values and increase
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(interruptedTranslation[0], redSquare.getTranslationY(), 1f);
+
+            // make sure it would go to the start value
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, redSquare.getTranslationY(), 0.01f);
+
+            // Now go back to the interrupted position again:
+            seekControllerArr[0].setCurrentPlayTimeMillis(0);
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(interruptedTranslation[0], redSquare.getTranslationY(), 1f);
+
+            // Send it back to GONE
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(interruptedTranslation[0], redSquare.getTranslationY(), 1f);
+
+            // it should move away (toward the top-left)
+            seekControllerArr[0].setCurrentPlayTimeMillis(299);
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertTrue(redSquare.getTranslationY() > interruptedTranslation[0]);
+
+            seekControllerArr[0] = TransitionManager.controlDelayedTransition(mRoot, new Slide());
+            redSquare.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            // It should end up at the initial translation
+            seekControllerArr[0].setCurrentPlayTimeMillis(300);
+            assertEquals(1f, redSquare.getTranslationX(), 0.01f);
+            assertEquals(5f, redSquare.getTranslationY(), 0.01f);
+        });
+    }
+
     private void verifyNoTranslation(View view) {
         assertEquals(0f, view.getTranslationX(), 0.01f);
         assertEquals(0f, view.getTranslationY(), 0.01f);
diff --git a/transition/transition/src/androidTest/java/androidx/transition/TransitionActivity.java b/transition/transition/src/androidTest/java/androidx/transition/TransitionActivity.java
index 002c7d4..86f7240 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/TransitionActivity.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/TransitionActivity.java
@@ -41,6 +41,7 @@
         overridePendingTransition(0, 0);
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public void finish() {
         super.finish();
diff --git a/transition/transition/src/androidTest/java/androidx/transition/TransitionManagerTest.java b/transition/transition/src/androidTest/java/androidx/transition/TransitionManagerTest.java
index 3d4397e..c80073a 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/TransitionManagerTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/TransitionManagerTest.java
@@ -21,8 +21,8 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.sameInstance;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -181,7 +181,7 @@
         final Transition transition = new AutoTransition();
         // This transition is very long, but will be forced to end as soon as it starts
         transition.setDuration(30000);
-        final Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listener = spy(new TransitionListenerAdapter());
         transition.addListener(listener);
         rule.runOnUiThread(new Runnable() {
             @Override
@@ -204,7 +204,7 @@
         final ViewGroup root = rule.getActivity().getRoot();
         final Transition transition = new AutoTransition();
         transition.setDuration(0);
-        final Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
+        final Transition.TransitionListener listener = spy(new TransitionListenerAdapter());
         transition.addListener(listener);
         rule.runOnUiThread(new Runnable() {
             @Override
diff --git a/transition/transition/src/androidTest/java/androidx/transition/TransitionTest.java b/transition/transition/src/androidTest/java/androidx/transition/TransitionTest.java
index 4c586a5..30a88f5 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/TransitionTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/TransitionTest.java
@@ -35,6 +35,7 @@
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.graphics.Rect;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -377,6 +378,61 @@
         assertThat(transition.isTransitionRequired(start, end), is(true));
     }
 
+    // Any listener that is added by the transition itself should not be in the global set of
+    // listeners. They should be limited to the executing transition.
+    @Test
+    public void internalListenersNotGlobal() throws Throwable {
+        rule.runOnUiThread(() -> {
+            mScenes[0].enter();
+        });
+        View view = rule.getActivity().findViewById(R.id.view0);
+
+        int[] startCount = new int[1];
+        Transition transition = new Visibility() {
+            private Animator createAnimator() {
+                addListener(new TransitionListenerAdapter() {
+                    @Override
+                    public void onTransitionStart(@NonNull Transition transition) {
+                        startCount[0]++;
+                    }
+                });
+                return ValueAnimator.ofFloat(0f, 100f);
+            }
+
+            @Nullable
+            @Override
+            public Animator onDisappear(@NonNull ViewGroup sceneRoot, @NonNull View view,
+                    @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+                return createAnimator();
+            }
+
+            @Nullable
+            @Override
+            public Animator onAppear(@NonNull ViewGroup sceneRoot, @NonNull View view,
+                    @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
+                return createAnimator();
+            }
+        };
+
+        rule.runOnUiThread(() -> {
+            ViewGroup root = rule.getActivity().getRoot();
+            TransitionManager.beginDelayedTransition(root, transition);
+            view.setVisibility(View.GONE);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(1, startCount[0]);
+
+            ViewGroup root = rule.getActivity().getRoot();
+            TransitionManager.beginDelayedTransition(root, transition);
+            view.setVisibility(View.VISIBLE);
+        });
+
+        rule.runOnUiThread(() -> {
+            assertEquals(2, startCount[0]);
+        });
+    }
+
     private void showInitialScene() throws Throwable {
         SyncRunnable enter0 = new SyncRunnable();
         mScenes[0].setEnterAction(enter0);
diff --git a/transition/transition/src/androidTest/java/androidx/transition/TranslationAnimationCreatorTest.java b/transition/transition/src/androidTest/java/androidx/transition/TranslationAnimationCreatorTest.java
index 976277a..207880f 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/TranslationAnimationCreatorTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/TranslationAnimationCreatorTest.java
@@ -53,7 +53,7 @@
         assertEquals(20, view.getTranslationX(), 0.01);
 
         verify(transition).addListener(listenerCaptor.capture());
-        listenerCaptor.getValue().onTransitionEnd(transition);
+        listenerCaptor.getValue().onTransitionEnd(transition, false);
         // but onTransitionEnd does
         assertEquals(0, view.getTranslationX(), 0.01);
     }
diff --git a/transition/transition/src/androidTest/java/androidx/transition/VisibilityTest.java b/transition/transition/src/androidTest/java/androidx/transition/VisibilityTest.java
index c433a98..73ce42f 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/VisibilityTest.java
+++ b/transition/transition/src/androidTest/java/androidx/transition/VisibilityTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -124,7 +124,7 @@
                 return ValueAnimator.ofFloat(0, 1);
             }
         });
-        Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
+        Transition.TransitionListener listener = spy(new TransitionListenerAdapter());
         set.addListener(listener);
 
         // remove view
@@ -177,7 +177,7 @@
                 return ValueAnimator.ofFloat(0, 1);
             }
         };
-        Transition.TransitionListener listener = mock(Transition.TransitionListener.class);
+        Transition.TransitionListener listener = spy(new TransitionListenerAdapter());
         visibility.addListener(listener);
 
         // remove view
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeBounds.java b/transition/transition/src/main/java/androidx/transition/ChangeBounds.java
index a0fcc2c..e72333d 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeBounds.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeBounds.java
@@ -20,18 +20,13 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Property;
 import android.view.View;
@@ -66,24 +61,6 @@
             PROPNAME_WINDOW_Y
     };
 
-    private static final Property<Drawable, PointF> DRAWABLE_ORIGIN_PROPERTY =
-            new Property<Drawable, PointF>(PointF.class, "boundsOrigin") {
-                private Rect mBounds = new Rect();
-
-                @Override
-                public void set(Drawable object, PointF value) {
-                    object.copyBounds(mBounds);
-                    mBounds.offsetTo(Math.round(value.x), Math.round(value.y));
-                    object.setBounds(mBounds);
-                }
-
-                @Override
-                public PointF get(Drawable object) {
-                    object.copyBounds(mBounds);
-                    return new PointF(mBounds.left, mBounds.top);
-                }
-            };
-
     private static final Property<ViewBounds, PointF> TOP_LEFT_PROPERTY =
             new Property<ViewBounds, PointF>(PointF.class, "topLeft") {
                 @Override
@@ -161,11 +138,9 @@
                 }
             };
 
-    private int[] mTempLocation = new int[2];
     private boolean mResizeClip = false;
-    private boolean mReparent = false;
 
-    private static RectEvaluator sRectEvaluator = new RectEvaluator();
+    private static final RectEvaluator sRectEvaluator = new RectEvaluator();
 
     public ChangeBounds() {
     }
@@ -182,6 +157,11 @@
         setResizeClip(resizeClip);
     }
 
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
     @NonNull
     @Override
     public String[] getTransitionProperties() {
@@ -223,11 +203,6 @@
             values.values.put(PROPNAME_BOUNDS, new Rect(view.getLeft(), view.getTop(),
                     view.getRight(), view.getBottom()));
             values.values.put(PROPNAME_PARENT, values.view.getParent());
-            if (mReparent) {
-                values.view.getLocationInWindow(mTempLocation);
-                values.values.put(PROPNAME_WINDOW_X, mTempLocation[0]);
-                values.values.put(PROPNAME_WINDOW_Y, mTempLocation[1]);
-            }
             if (mResizeClip) {
                 values.values.put(PROPNAME_CLIP, ViewCompat.getClipBounds(view));
             }
@@ -237,6 +212,13 @@
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
         captureValues(transitionValues);
+        if (mResizeClip) {
+            Rect clipSize =
+                    (Rect) transitionValues.view.getTag(R.id.transition_clip);
+            if (clipSize != null) {
+                transitionValues.values.put(PROPNAME_CLIP, clipSize);
+            }
+        }
     }
 
     @Override
@@ -244,19 +226,6 @@
         captureValues(transitionValues);
     }
 
-    private boolean parentMatches(View startParent, View endParent) {
-        boolean parentMatches = true;
-        if (mReparent) {
-            TransitionValues endValues = getMatchedTransitionValues(startParent, true);
-            if (endValues == null) {
-                parentMatches = startParent == endParent;
-            } else {
-                parentMatches = endParent == endValues.view;
-            }
-        }
-        return parentMatches;
-    }
-
     @Override
     @Nullable
     public Animator createAnimator(@NonNull final ViewGroup sceneRoot,
@@ -272,188 +241,118 @@
             return null;
         }
         final View view = endValues.view;
-        if (parentMatches(startParent, endParent)) {
-            Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
-            Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
-            final int startLeft = startBounds.left;
-            final int endLeft = endBounds.left;
-            final int startTop = startBounds.top;
-            final int endTop = endBounds.top;
-            final int startRight = startBounds.right;
-            final int endRight = endBounds.right;
-            final int startBottom = startBounds.bottom;
-            final int endBottom = endBounds.bottom;
-            final int startWidth = startRight - startLeft;
-            final int startHeight = startBottom - startTop;
-            final int endWidth = endRight - endLeft;
-            final int endHeight = endBottom - endTop;
-            Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP);
-            Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP);
-            int numChanges = 0;
-            if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
-                if (startLeft != endLeft || startTop != endTop) ++numChanges;
-                if (startRight != endRight || startBottom != endBottom) ++numChanges;
-            }
-            if ((startClip != null && !startClip.equals(endClip))
-                    || (startClip == null && endClip != null)) {
-                ++numChanges;
-            }
-            if (numChanges > 0) {
-                Animator anim;
-                if (!mResizeClip) {
-                    ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startRight,
-                            startBottom);
-                    if (numChanges == 2) {
-                        if (startWidth == endWidth && startHeight == endHeight) {
-                            Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft,
-                                    endTop);
-                            anim = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY,
-                                    topLeftPath);
-                        } else {
-                            final ViewBounds viewBounds = new ViewBounds(view);
-                            Path topLeftPath = getPathMotion().getPath(startLeft, startTop,
-                                    endLeft, endTop);
-                            ObjectAnimator topLeftAnimator = ObjectAnimatorUtils
-                                    .ofPointF(viewBounds, TOP_LEFT_PROPERTY, topLeftPath);
-
-                            Path bottomRightPath = getPathMotion().getPath(startRight, startBottom,
-                                    endRight, endBottom);
-                            ObjectAnimator bottomRightAnimator = ObjectAnimatorUtils.ofPointF(
-                                    viewBounds, BOTTOM_RIGHT_PROPERTY, bottomRightPath);
-                            AnimatorSet set = new AnimatorSet();
-                            set.playTogether(topLeftAnimator, bottomRightAnimator);
-                            anim = set;
-                            set.addListener(new AnimatorListenerAdapter() {
-                                // We need a strong reference to viewBounds until the
-                                // animator ends (The ObjectAnimator holds only a weak reference).
-                                @SuppressWarnings("unused")
-                                private ViewBounds mViewBounds = viewBounds;
-                            });
-                        }
-                    } else if (startLeft != endLeft || startTop != endTop) {
-                        Path topLeftPath = getPathMotion().getPath(startLeft, startTop,
-                                endLeft, endTop);
-                        anim = ObjectAnimatorUtils.ofPointF(view, TOP_LEFT_ONLY_PROPERTY,
-                                topLeftPath);
-                    } else {
-                        Path bottomRight = getPathMotion().getPath(startRight, startBottom,
-                                endRight, endBottom);
-                        anim = ObjectAnimatorUtils.ofPointF(view, BOTTOM_RIGHT_ONLY_PROPERTY,
-                                bottomRight);
-                    }
-                } else {
-                    int maxWidth = Math.max(startWidth, endWidth);
-                    int maxHeight = Math.max(startHeight, endHeight);
-
-                    ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startLeft + maxWidth,
-                            startTop + maxHeight);
-
-                    ObjectAnimator positionAnimator = null;
-                    if (startLeft != endLeft || startTop != endTop) {
+        Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
+        Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
+        final int startLeft = startBounds.left;
+        final int endLeft = endBounds.left;
+        final int startTop = startBounds.top;
+        final int endTop = endBounds.top;
+        final int startRight = startBounds.right;
+        final int endRight = endBounds.right;
+        final int startBottom = startBounds.bottom;
+        final int endBottom = endBounds.bottom;
+        final int startWidth = startRight - startLeft;
+        final int startHeight = startBottom - startTop;
+        final int endWidth = endRight - endLeft;
+        final int endHeight = endBottom - endTop;
+        Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP);
+        Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP);
+        int numChanges = 0;
+        if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) {
+            if (startLeft != endLeft || startTop != endTop) ++numChanges;
+            if (startRight != endRight || startBottom != endBottom) ++numChanges;
+        }
+        if ((startClip != null && !startClip.equals(endClip))
+                || (startClip == null && endClip != null)) {
+            ++numChanges;
+        }
+        if (numChanges > 0) {
+            Animator anim;
+            if (!mResizeClip) {
+                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startRight,
+                        startBottom);
+                if (numChanges == 2) {
+                    if (startWidth == endWidth && startHeight == endHeight) {
                         Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft,
                                 endTop);
-                        positionAnimator = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY,
+                        anim = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY,
                                 topLeftPath);
-                    }
-                    final Rect finalClip = endClip;
-                    if (startClip == null) {
-                        startClip = new Rect(0, 0, startWidth, startHeight);
-                    }
-                    if (endClip == null) {
-                        endClip = new Rect(0, 0, endWidth, endHeight);
-                    }
-                    ObjectAnimator clipAnimator = null;
-                    if (!startClip.equals(endClip)) {
-                        ViewCompat.setClipBounds(view, startClip);
-                        clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator,
-                                startClip, endClip);
-                        clipAnimator.addListener(new AnimatorListenerAdapter() {
-                            private boolean mIsCanceled;
+                    } else {
+                        final ViewBounds viewBounds = new ViewBounds(view);
+                        Path topLeftPath = getPathMotion().getPath(startLeft, startTop,
+                                endLeft, endTop);
+                        ObjectAnimator topLeftAnimator = ObjectAnimatorUtils
+                                .ofPointF(viewBounds, TOP_LEFT_PROPERTY, topLeftPath);
 
-                            @Override
-                            public void onAnimationCancel(Animator animation) {
-                                mIsCanceled = true;
-                            }
-
-                            @Override
-                            public void onAnimationEnd(Animator animation) {
-                                if (!mIsCanceled) {
-                                    ViewCompat.setClipBounds(view, finalClip);
-                                    ViewUtils.setLeftTopRightBottom(view, endLeft, endTop, endRight,
-                                            endBottom);
-                                }
-                            }
+                        Path bottomRightPath = getPathMotion().getPath(startRight, startBottom,
+                                endRight, endBottom);
+                        ObjectAnimator bottomRightAnimator = ObjectAnimatorUtils.ofPointF(
+                                viewBounds, BOTTOM_RIGHT_PROPERTY, bottomRightPath);
+                        AnimatorSet set = new AnimatorSet();
+                        set.playTogether(topLeftAnimator, bottomRightAnimator);
+                        anim = set;
+                        set.addListener(new AnimatorListenerAdapter() {
+                            // We need a strong reference to viewBounds until the
+                            // animator ends (The ObjectAnimator holds only a weak reference).
+                            @SuppressWarnings("unused")
+                            private final ViewBounds mViewBounds = viewBounds;
                         });
                     }
-                    anim = TransitionUtils.mergeAnimators(positionAnimator,
-                            clipAnimator);
+                } else if (startLeft != endLeft || startTop != endTop) {
+                    Path topLeftPath = getPathMotion().getPath(startLeft, startTop,
+                            endLeft, endTop);
+                    anim = ObjectAnimatorUtils.ofPointF(view, TOP_LEFT_ONLY_PROPERTY,
+                            topLeftPath);
+                } else {
+                    Path bottomRight = getPathMotion().getPath(startRight, startBottom,
+                            endRight, endBottom);
+                    anim = ObjectAnimatorUtils.ofPointF(view, BOTTOM_RIGHT_ONLY_PROPERTY,
+                            bottomRight);
                 }
-                if (view.getParent() instanceof ViewGroup) {
-                    final ViewGroup parent = (ViewGroup) view.getParent();
-                    ViewGroupUtils.suppressLayout(parent, true);
-                    TransitionListener transitionListener = new TransitionListenerAdapter() {
-                        boolean mCanceled = false;
+            } else {
+                int maxWidth = Math.max(startWidth, endWidth);
+                int maxHeight = Math.max(startHeight, endHeight);
 
-                        @Override
-                        public void onTransitionCancel(@NonNull Transition transition) {
-                            ViewGroupUtils.suppressLayout(parent, false);
-                            mCanceled = true;
-                        }
+                ViewUtils.setLeftTopRightBottom(view, startLeft, startTop, startLeft + maxWidth,
+                        startTop + maxHeight);
 
-                        @Override
-                        public void onTransitionEnd(@NonNull Transition transition) {
-                            if (!mCanceled) {
-                                ViewGroupUtils.suppressLayout(parent, false);
-                            }
-                            transition.removeListener(this);
-                        }
-
-                        @Override
-                        public void onTransitionPause(@NonNull Transition transition) {
-                            ViewGroupUtils.suppressLayout(parent, false);
-                        }
-
-                        @Override
-                        public void onTransitionResume(@NonNull Transition transition) {
-                            ViewGroupUtils.suppressLayout(parent, true);
-                        }
-                    };
-                    addListener(transitionListener);
+                ObjectAnimator positionAnimator = null;
+                if (startLeft != endLeft || startTop != endTop) {
+                    Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft,
+                            endTop);
+                    positionAnimator = ObjectAnimatorUtils.ofPointF(view, POSITION_PROPERTY,
+                            topLeftPath);
                 }
-                return anim;
+                boolean startClipIsNull = startClip == null;
+                if (startClipIsNull) {
+                    startClip = new Rect(0, 0, startWidth, startHeight);
+                }
+                boolean endClipIsNull = endClip == null;
+                if (endClipIsNull) {
+                    endClip = new Rect(0, 0, endWidth, endHeight);
+                }
+                ObjectAnimator clipAnimator = null;
+                if (!startClip.equals(endClip)) {
+                    ViewCompat.setClipBounds(view, startClip);
+                    clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator,
+                            startClip, endClip);
+                    ClipListener listener = new ClipListener(view,
+                            startClip, startClipIsNull, endClip, endClipIsNull,
+                            startLeft, startTop, startRight, startBottom,
+                            endLeft, endTop, endRight, endBottom
+                    );
+                    clipAnimator.addListener(listener);
+                    addListener(listener);
+                }
+                anim = TransitionUtils.mergeAnimators(positionAnimator,
+                        clipAnimator);
             }
-        } else {
-            int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X);
-            int startY = (Integer) startValues.values.get(PROPNAME_WINDOW_Y);
-            int endX = (Integer) endValues.values.get(PROPNAME_WINDOW_X);
-            int endY = (Integer) endValues.values.get(PROPNAME_WINDOW_Y);
-            // TODO: also handle size changes: check bounds and animate size changes
-            if (startX != endX || startY != endY) {
-                sceneRoot.getLocationInWindow(mTempLocation);
-                Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
-                        Bitmap.Config.ARGB_8888);
-                Canvas canvas = new Canvas(bitmap);
-                view.draw(canvas);
-                @SuppressWarnings("deprecation") final BitmapDrawable drawable = new BitmapDrawable(
-                        bitmap);
-                final float transitionAlpha = ViewUtils.getTransitionAlpha(view);
-                ViewUtils.setTransitionAlpha(view, 0);
-                ViewUtils.getOverlay(sceneRoot).add(drawable);
-                Path topLeftPath = getPathMotion().getPath(startX - mTempLocation[0],
-                        startY - mTempLocation[1], endX - mTempLocation[0],
-                        endY - mTempLocation[1]);
-                PropertyValuesHolder origin = PropertyValuesHolderUtils.ofPointF(
-                        DRAWABLE_ORIGIN_PROPERTY, topLeftPath);
-                ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(drawable, origin);
-                anim.addListener(new AnimatorListenerAdapter() {
-                    @Override
-                    public void onAnimationEnd(Animator animation) {
-                        ViewUtils.getOverlay(sceneRoot).remove(drawable);
-                        ViewUtils.setTransitionAlpha(view, transitionAlpha);
-                    }
-                });
-                return anim;
+            if (view.getParent() instanceof ViewGroup) {
+                final ViewGroup parent = (ViewGroup) view.getParent();
+                ViewGroupUtils.suppressLayout(parent, true);
+                getRootTransition().addListener(new SuppressLayoutListener(parent));
             }
+            return anim;
         }
         return null;
     }
@@ -464,7 +363,7 @@
         private int mTop;
         private int mRight;
         private int mBottom;
-        private View mView;
+        private final View mView;
         private int mTopLeftCalls;
         private int mBottomRightCalls;
 
@@ -495,7 +394,149 @@
             mTopLeftCalls = 0;
             mBottomRightCalls = 0;
         }
-
     }
 
+    private static class ClipListener
+            extends AnimatorListenerAdapter implements TransitionListener {
+        private final View mView;
+        private final Rect mStartClip;
+        private final boolean mStartClipIsNull;
+        private final Rect mEndClip;
+        private final boolean mEndClipIsNull;
+        private final int mStartLeft, mStartTop, mStartRight, mStartBottom;
+        private final int mEndLeft, mEndTop, mEndRight, mEndBottom;
+
+        private boolean mIsCanceled;
+
+        ClipListener(View view,
+                Rect startClip,
+                boolean startClipIsNull,
+                Rect endClip,
+                boolean endClipIsNull,
+                int startLeft,
+                int startTop,
+                int startRight,
+                int startBottom,
+                int endLeft,
+                int endTop,
+                int endRight,
+                int endBottom
+        ) {
+            mView = view;
+            mStartClip = startClip;
+            mStartClipIsNull = startClipIsNull;
+            mEndClip = endClip;
+            mEndClipIsNull = endClipIsNull;
+            mStartLeft = startLeft;
+            mStartTop = startTop;
+            mStartRight = startRight;
+            mStartBottom = startBottom;
+            mEndLeft = endLeft;
+            mEndTop = endTop;
+            mEndRight = endRight;
+            mEndBottom = endBottom;
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            onAnimationStart(animation, false);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            onAnimationEnd(animation, false);
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation, boolean isReverse) {
+            int maxWidth = Math.max(mStartRight - mStartLeft, mEndRight - mEndLeft);
+            int maxHeight = Math.max(mStartBottom - mStartTop, mEndBottom - mEndTop);
+
+            int left = isReverse ? mEndLeft : mStartLeft;
+            int top = isReverse ? mEndTop : mStartTop;
+            ViewUtils.setLeftTopRightBottom(mView, left, top, left + maxWidth, top + maxHeight);
+
+            Rect clip = isReverse ? mEndClip : mStartClip;
+            ViewCompat.setClipBounds(mView, clip);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation, boolean isReverse) {
+            if (mIsCanceled) {
+                return;
+            }
+            Rect clip = isReverse
+                    ? (mStartClipIsNull ? null : mStartClip)
+                    : (mEndClipIsNull ? null : mEndClip);
+            ViewCompat.setClipBounds(mView, clip);
+            if (isReverse) {
+                ViewUtils.setLeftTopRightBottom(mView, mStartLeft, mStartTop, mStartRight,
+                        mStartBottom);
+            } else {
+                ViewUtils.setLeftTopRightBottom(mView, mEndLeft, mEndTop, mEndRight, mEndBottom);
+            }
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+            mIsCanceled = true;
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+            Rect pauseClip = ViewCompat.getClipBounds(mView);
+            mView.setTag(R.id.transition_clip, pauseClip);
+            Rect clip = mEndClipIsNull ? null : mEndClip;
+            ViewCompat.setClipBounds(mView, clip);
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+            Rect pauseClip = (Rect) mView.getTag(R.id.transition_clip);
+            mView.setTag(R.id.transition_clip, null);
+            ViewCompat.setClipBounds(mView, pauseClip);
+        }
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+        }
+    }
+
+    private static class SuppressLayoutListener extends TransitionListenerAdapter {
+        boolean mCanceled = false;
+
+        final ViewGroup mParent;
+
+        SuppressLayoutListener(@NonNull ViewGroup parent) {
+            mParent = parent;
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+            ViewGroupUtils.suppressLayout(mParent, false);
+            mCanceled = true;
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+            if (!mCanceled) {
+                ViewGroupUtils.suppressLayout(mParent, false);
+            }
+            transition.removeListener(this);
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+            ViewGroupUtils.suppressLayout(mParent, false);
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+            ViewGroupUtils.suppressLayout(mParent, true);
+        }
+    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeClipBounds.java b/transition/transition/src/main/java/androidx/transition/ChangeClipBounds.java
index b568ae2..bcd40a3 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeClipBounds.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeClipBounds.java
@@ -44,6 +44,10 @@
             PROPNAME_CLIP,
     };
 
+    // Represents a null Rect in the tag. If null were used instead, we would treat it
+    // as not set.
+    static final Rect NULL_SENTINEL = new Rect();
+
     @Override
     @NonNull
     public String[] getTransitionProperties() {
@@ -57,13 +61,28 @@
         super(context, attrs);
     }
 
-    private void captureValues(TransitionValues values) {
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
+    @SuppressWarnings("ReferenceEquality") // Reference comparison with NULL_SENTINEL
+    private void captureValues(TransitionValues values, boolean clipFromTag) {
         View view = values.view;
         if (view.getVisibility() == View.GONE) {
             return;
         }
 
-        Rect clip = ViewCompat.getClipBounds(view);
+        Rect clip = null;
+        if (clipFromTag) {
+            clip = (Rect) view.getTag(R.id.transition_clip);
+        }
+        if (clip == null) {
+            clip = ViewCompat.getClipBounds(view);
+        }
+        if (clip == NULL_SENTINEL) {
+            clip = null;
+        }
         values.values.put(PROPNAME_CLIP, clip);
         if (clip == null) {
             Rect bounds = new Rect(0, 0, view.getWidth(), view.getHeight());
@@ -73,12 +92,12 @@
 
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        captureValues(transitionValues);
+        captureValues(transitionValues, true);
     }
 
     @Override
     public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        captureValues(transitionValues);
+        captureValues(transitionValues, false);
     }
 
     @Nullable
@@ -93,33 +112,83 @@
         }
         Rect start = (Rect) startValues.values.get(PROPNAME_CLIP);
         Rect end = (Rect) endValues.values.get(PROPNAME_CLIP);
-        final boolean endIsNull = end == null;
         if (start == null && end == null) {
             return null; // No animation required since there is no clip.
         }
 
-        if (start == null) {
-            start = (Rect) startValues.values.get(PROPNAME_BOUNDS);
-        } else if (end == null) {
-            end = (Rect) endValues.values.get(PROPNAME_BOUNDS);
-        }
-        if (start.equals(end)) {
+        Rect startClip = start == null ? (Rect) startValues.values.get(PROPNAME_BOUNDS) : start;
+        Rect endClip = end == null ? (Rect) endValues.values.get(PROPNAME_BOUNDS) : end;
+
+        if (startClip.equals(endClip)) {
             return null;
         }
 
         ViewCompat.setClipBounds(endValues.view, start);
         RectEvaluator evaluator = new RectEvaluator(new Rect());
         ObjectAnimator animator = ObjectAnimator.ofObject(endValues.view, ViewUtils.CLIP_BOUNDS,
-                evaluator, start, end);
-        if (endIsNull) {
-            final View endView = endValues.view;
-            animator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    ViewCompat.setClipBounds(endView, null);
-                }
-            });
-        }
+                evaluator, startClip, endClip);
+        View view = endValues.view;
+        Listener listener = new Listener(view, start, end);
+        animator.addListener(listener);
+        addListener(listener);
         return animator;
     }
+
+    private static class Listener extends AnimatorListenerAdapter implements TransitionListener {
+        private final Rect mStart;
+        private final Rect mEnd;
+        private final View mView;
+
+        Listener(View view, Rect start, Rect end) {
+            mView = view;
+            mStart = start;
+            mEnd = end;
+        }
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+            Rect clipBounds = ViewCompat.getClipBounds(mView);
+            if (clipBounds == null) {
+                clipBounds = NULL_SENTINEL;
+            }
+            mView.setTag(R.id.transition_clip, clipBounds);
+            ViewCompat.setClipBounds(mView, mEnd);
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+            Rect clipBounds = (Rect) mView.getTag(R.id.transition_clip);
+            ViewCompat.setClipBounds(mView, clipBounds);
+            mView.setTag(R.id.transition_clip, null);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            onAnimationEnd(animation, false);
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation, boolean isReverse) {
+            if (!isReverse) {
+                ViewCompat.setClipBounds(mView, mEnd);
+            } else {
+                ViewCompat.setClipBounds(mView, mStart);
+            }
+        }
+    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java b/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
index cfdbbd3..1d6b6d0 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeImageTransform.java
@@ -17,6 +17,7 @@
 package androidx.transition;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.TypeEvaluator;
 import android.content.Context;
@@ -79,7 +80,12 @@
         super(context, attrs);
     }
 
-    private void captureValues(TransitionValues transitionValues) {
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
+    private void captureValues(TransitionValues transitionValues, boolean useIntermediate) {
         View view = transitionValues.view;
         if (!(view instanceof ImageView) || view.getVisibility() != View.VISIBLE) {
             return;
@@ -98,17 +104,24 @@
 
         Rect bounds = new Rect(left, top, right, bottom);
         values.put(PROPNAME_BOUNDS, bounds);
-        values.put(PROPNAME_MATRIX, copyImageMatrix(imageView));
+        Matrix matrix = null;
+        if (useIntermediate) {
+            matrix = (Matrix) imageView.getTag(R.id.transition_image_transform);
+        }
+        if (matrix == null) {
+            matrix = copyImageMatrix(imageView);
+        }
+        values.put(PROPNAME_MATRIX, matrix);
     }
 
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
-        captureValues(transitionValues);
+        captureValues(transitionValues, true);
     }
 
     @Override
     public void captureEndValues(@NonNull TransitionValues transitionValues) {
-        captureValues(transitionValues);
+        captureValues(transitionValues, false);
     }
 
     @Override
@@ -168,6 +181,10 @@
             }
             ANIMATED_TRANSFORM_PROPERTY.set(imageView, startMatrix);
             animator = createMatrixAnimator(imageView, startMatrix, endMatrix);
+            Listener listener = new Listener(imageView, startMatrix, endMatrix);
+            animator.addListener(listener);
+            AnimatorUtils.addPauseListener(animator, listener);
+            addListener(listener);
         }
 
         return animator;
@@ -241,4 +258,85 @@
         return matrix;
     }
 
+    private static class Listener extends AnimatorListenerAdapter implements TransitionListener,
+            AnimatorUtils.AnimatorPauseListenerCompat {
+        private final ImageView mImageView;
+        private final Matrix mStartMatrix;
+        private final Matrix mEndMatrix;
+        private boolean mIsBeforeAnimator = true;
+
+        Listener(ImageView imageView, Matrix startMatrix, Matrix endMatrix) {
+            mImageView = imageView;
+            mStartMatrix = startMatrix;
+            mEndMatrix = endMatrix;
+        }
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+            if (mIsBeforeAnimator) {
+                saveMatrix(mStartMatrix);
+            }
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+            restoreMatrix();
+        }
+
+        @Override
+        public void onAnimationStart(@NonNull Animator animation, boolean isReverse) {
+            mIsBeforeAnimator = false;
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            mIsBeforeAnimator = false;
+        }
+
+        @Override
+        public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) {
+            mIsBeforeAnimator = isReverse;
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mIsBeforeAnimator = false;
+        }
+
+        @Override
+        public void onAnimationPause(Animator animation) {
+            Matrix pauseMatrix = (Matrix) ((ObjectAnimator) animation).getAnimatedValue();
+            saveMatrix(pauseMatrix);
+        }
+
+        @Override
+        public void onAnimationResume(Animator animation) {
+            restoreMatrix();
+        }
+
+        private void restoreMatrix() {
+            Matrix pauseMatrix = (Matrix) mImageView.getTag(R.id.transition_image_transform);
+            if (pauseMatrix != null) {
+                ImageViewUtils.animateTransform(mImageView, pauseMatrix);
+                mImageView.setTag(R.id.transition_image_transform, null);
+            }
+        }
+
+        private void saveMatrix(Matrix pauseMatrix) {
+            mImageView.setTag(R.id.transition_image_transform, pauseMatrix);
+            ImageViewUtils.animateTransform(mImageView, mEndMatrix);
+        }
+    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeScroll.java b/transition/transition/src/main/java/androidx/transition/ChangeScroll.java
index d2b9a21..03fa492 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeScroll.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeScroll.java
@@ -57,6 +57,11 @@
         captureValues(transitionValues);
     }
 
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
     @Nullable
     @Override
     public String[] getTransitionProperties() {
diff --git a/transition/transition/src/main/java/androidx/transition/ChangeTransform.java b/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
index 84b869f..0d0cd09 100644
--- a/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
+++ b/transition/transition/src/main/java/androidx/transition/ChangeTransform.java
@@ -326,48 +326,8 @@
         ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(pathAnimatorMatrix,
                 valuesProperty, translationProperty);
 
-        final Matrix finalEndMatrix = endMatrix;
-
-        AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
-            private boolean mIsCanceled;
-            private Matrix mTempMatrix = new Matrix();
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                mIsCanceled = true;
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!mIsCanceled) {
-                    if (handleParentChange && mUseOverlay) {
-                        setCurrentMatrix(finalEndMatrix);
-                    } else {
-                        view.setTag(R.id.transition_transform, null);
-                        view.setTag(R.id.parent_matrix, null);
-                    }
-                }
-                ViewUtils.setAnimationMatrix(view, null);
-                transforms.restore(view);
-            }
-
-            @Override
-            public void onAnimationPause(Animator animation) {
-                Matrix currentMatrix = pathAnimatorMatrix.getMatrix();
-                setCurrentMatrix(currentMatrix);
-            }
-
-            @Override
-            public void onAnimationResume(Animator animation) {
-                setIdentityTransforms(view);
-            }
-
-            private void setCurrentMatrix(Matrix currentMatrix) {
-                mTempMatrix.set(currentMatrix);
-                view.setTag(R.id.transition_transform, mTempMatrix);
-                transforms.restore(view);
-            }
-        };
+        Listener listener = new Listener(view, transforms, pathAnimatorMatrix, endMatrix,
+                handleParentChange, mUseOverlay);
 
         animator.addListener(listener);
         AnimatorUtils.addPauseListener(animator, listener);
@@ -591,4 +551,61 @@
         }
     }
 
+    private static class Listener extends AnimatorListenerAdapter implements
+            AnimatorUtils.AnimatorPauseListenerCompat {
+        private boolean mIsCanceled;
+        private final Matrix mTempMatrix = new Matrix();
+        private final boolean mHandleParentChange;
+        private final boolean mUseOverlay;
+        private final View mView;
+        private final Transforms mTransforms;
+        private final PathAnimatorMatrix mPathAnimatorMatrix;
+        private final Matrix mEndMatrix;
+
+        Listener(View view, Transforms transforms, PathAnimatorMatrix pathAnimatorMatrix,
+                Matrix endMatrix, boolean handleParentChange, boolean useOverlay) {
+            mHandleParentChange = handleParentChange;
+            mUseOverlay = useOverlay;
+            mView = view;
+            mTransforms = transforms;
+            mPathAnimatorMatrix = pathAnimatorMatrix;
+            mEndMatrix = endMatrix;
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            mIsCanceled = true;
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            if (!mIsCanceled) {
+                if (mHandleParentChange && mUseOverlay) {
+                    setCurrentMatrix(mEndMatrix);
+                } else {
+                    mView.setTag(R.id.transition_transform, null);
+                    mView.setTag(R.id.parent_matrix, null);
+                }
+            }
+            ViewUtils.setAnimationMatrix(mView, null);
+            mTransforms.restore(mView);
+        }
+
+        @Override
+        public void onAnimationPause(Animator animation) {
+            Matrix currentMatrix = mPathAnimatorMatrix.getMatrix();
+            setCurrentMatrix(currentMatrix);
+        }
+
+        @Override
+        public void onAnimationResume(Animator animation) {
+            setIdentityTransforms(mView);
+        }
+
+        private void setCurrentMatrix(Matrix currentMatrix) {
+            mTempMatrix.set(currentMatrix);
+            mView.setTag(R.id.transition_transform, mTempMatrix);
+            mTransforms.restore(mView);
+        }
+    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/Explode.java b/transition/transition/src/main/java/androidx/transition/Explode.java
index ea53bc2..a671288 100644
--- a/transition/transition/src/main/java/androidx/transition/Explode.java
+++ b/transition/transition/src/main/java/androidx/transition/Explode.java
@@ -79,6 +79,11 @@
         captureValues(transitionValues);
     }
 
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
     @Nullable
     @Override
     public Animator onAppear(@NonNull ViewGroup sceneRoot, @NonNull View view,
diff --git a/transition/transition/src/main/java/androidx/transition/Fade.java b/transition/transition/src/main/java/androidx/transition/Fade.java
index ac1f499..a264655 100644
--- a/transition/transition/src/main/java/androidx/transition/Fade.java
+++ b/transition/transition/src/main/java/androidx/transition/Fade.java
@@ -118,6 +118,11 @@
                 ViewUtils.getTransitionAlpha(transitionValues.view));
     }
 
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
     /**
      * Utility method to handle creating and running the Animator.
      */
@@ -133,14 +138,6 @@
         }
         FadeAnimatorListener listener = new FadeAnimatorListener(view);
         anim.addListener(listener);
-        addListener(new TransitionListenerAdapter() {
-            @Override
-            public void onTransitionEnd(@NonNull Transition transition) {
-                ViewUtils.setTransitionAlpha(view, 1);
-                ViewUtils.clearNonTransitionAlpha(view);
-                transition.removeListener(this);
-            }
-        });
         return anim;
     }
 
@@ -153,6 +150,7 @@
             Log.d(LOG_TAG, "Fade.onAppear: startView, startVis, endView, endVis = "
                     + startView + ", " + view);
         }
+        ViewUtils.saveNonTransitionAlpha(view);
         float startAlpha = getStartAlpha(startValues, 0);
         if (startAlpha == 1) {
             startAlpha = 0;
@@ -166,7 +164,11 @@
             @Nullable TransitionValues startValues, @Nullable TransitionValues endValues) {
         ViewUtils.saveNonTransitionAlpha(view);
         float startAlpha = getStartAlpha(startValues, 1);
-        return createAnimation(view, startAlpha, 0);
+        Animator animator = createAnimation(view, startAlpha, 0);
+        if (animator == null) {
+            ViewUtils.setTransitionAlpha(view, getStartAlpha(endValues, 1f));
+        }
+        return animator;
     }
 
     private static float getStartAlpha(TransitionValues startValues, float fallbackValue) {
@@ -201,11 +203,22 @@
         @Override
         public void onAnimationEnd(Animator animation) {
             ViewUtils.setTransitionAlpha(mView, 1);
+            ViewUtils.clearNonTransitionAlpha(mView);
             if (mLayerTypeChanged) {
                 mView.setLayerType(View.LAYER_TYPE_NONE, null);
             }
         }
 
+        @Override
+        public void onAnimationEnd(Animator animation, boolean isReverse) {
+            if (!isReverse) {
+                ViewUtils.setTransitionAlpha(mView, 1);
+                ViewUtils.clearNonTransitionAlpha(mView);
+            }
+            if (mLayerTypeChanged) {
+                mView.setLayerType(View.LAYER_TYPE_NONE, null);
+            }
+        }
     }
 
 }
diff --git a/transition/transition/src/main/java/androidx/transition/Slide.java b/transition/transition/src/main/java/androidx/transition/Slide.java
index ae54f98..62d2dcf 100644
--- a/transition/transition/src/main/java/androidx/transition/Slide.java
+++ b/transition/transition/src/main/java/androidx/transition/Slide.java
@@ -194,6 +194,11 @@
         captureValues(transitionValues);
     }
 
+    @Override
+    public boolean isSeekingSupported() {
+        return true;
+    }
+
     /**
      * Change the edge that Views appear and disappear from.
      *
diff --git a/transition/transition/src/main/java/androidx/transition/Transition.java b/transition/transition/src/main/java/androidx/transition/Transition.java
index fc1a168..8c32506 100644
--- a/transition/transition/src/main/java/androidx/transition/Transition.java
+++ b/transition/transition/src/main/java/androidx/transition/Transition.java
@@ -20,13 +20,16 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
@@ -40,14 +43,19 @@
 import android.widget.ListView;
 import android.widget.Spinner;
 
+import androidx.annotation.DoNotInline;
 import androidx.annotation.IdRes;
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.collection.ArrayMap;
 import androidx.collection.LongSparseArray;
 import androidx.core.content.res.TypedArrayUtils;
+import androidx.core.os.BuildCompat;
+import androidx.core.util.Consumer;
 import androidx.core.view.ViewCompat;
 
 import java.lang.annotation.Retention;
@@ -200,6 +208,7 @@
     private int[] mMatchOrder = DEFAULT_MATCH_ORDER;
     private ArrayList<TransitionValues> mStartValuesList; // only valid after playTransition starts
     private ArrayList<TransitionValues> mEndValuesList; // only valid after playTransitions starts
+    private TransitionListener[] mListenersCache;
 
     // Per-animator information used for later canceling when future transitions overlap
     private static ThreadLocal<ArrayMap<Animator, Transition.AnimationInfo>> sRunningAnimators =
@@ -220,21 +229,21 @@
 
     // Number of per-target instances of this Transition currently running. This count is
     // determined by calls to start() and end()
-    private int mNumInstances = 0;
+    int mNumInstances = 0;
 
     // Whether this transition is currently paused, due to a call to pause()
     private boolean mPaused = false;
 
     // Whether this transition has ended. Used to avoid pause/resume on transitions
     // that have completed
-    private boolean mEnded = false;
+    boolean mEnded = false;
 
     // The set of listeners to be sent transition lifecycle events.
     private ArrayList<Transition.TransitionListener> mListeners = null;
 
     // The set of animators collected from calls to createAnimator(),
     // to be run in runAnimators()
-    private ArrayList<Animator> mAnimators = new ArrayList<>();
+    ArrayList<Animator> mAnimators = new ArrayList<>();
 
     // The function for calculating the Animation start delay.
     TransitionPropagation mPropagation;
@@ -251,6 +260,18 @@
     // for adding curves to x/y View motion.
     private PathMotion mPathMotion = STRAIGHT_PATH_MOTION;
 
+    // The total duration of this Transition, in milliseconds. This is used only if
+    // TransitionManager.controlDelayedTransition() is called to begin a seekable Transition.
+    long mTotalDuration;
+
+    // The SeekController created in TransitionManager.controlDelayedTransition() on the
+    // root TransitionSet.
+    SeekController mSeekController;
+
+    // For Transitions in a TransitionSet that are played sequentially, this is the offset
+    // (in milliseconds) from the start of the containing TransitionSet of this Transition
+    long mSeekOffsetInParent;
+
     /**
      * Constructs a Transition object with no target objects. A transition with
      * no targets defaults to running on all target objects in the scene hierarchy
@@ -328,6 +349,19 @@
     }
 
     /**
+     * If this Transition is not part of a TransitionSet, this is returned. If it is part
+     * of a TransitionSet, the parent TransitionSets are walked until a TransitionSet is found
+     * that isn't contained in another TransitionSet.
+     */
+    @NonNull
+    public final Transition getRootTransition() {
+        if (mParent != null) {
+            return mParent.getRootTransition();
+        }
+        return this;
+    }
+
+    /**
      * Sets the duration of this transition. By default, there is no duration
      * (indicated by a negative number), which means that the Animator created by
      * the transition will have its own specified duration. If the duration of a
@@ -487,6 +521,20 @@
     }
 
     /**
+     * Creates and returns a new TransitionSeekController, tied it to this Transition.
+     * This should only be called once on the cloned transition for controlling the
+     * Transition's progress. The Transition will begin without starting any of the
+     * animations.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @NonNull
+    TransitionSeekController createSeekController() {
+        mSeekController = new SeekController();
+        addListener(mSeekController);
+        return mSeekController;
+    }
+
+    /**
      * Sets the order in which Transition matches View start and end values.
      * <p>
      * The default behavior is to match first by {@link android.view.View#getTransitionName()},
@@ -664,6 +712,7 @@
         ArrayMap<View, TransitionValues> unmatchedStart = new ArrayMap<>(startValues.mViewValues);
         ArrayMap<View, TransitionValues> unmatchedEnd = new ArrayMap<>(endValues.mViewValues);
 
+        //noinspection ForLoopReplaceableByForEach
         for (int i = 0; i < mMatchOrder.length; i++) {
             switch (mMatchOrder[i]) {
                 case MATCH_INSTANCE:
@@ -695,6 +744,7 @@
      * TransitionSet subclass overrides this method and delegates it to
      * each of its children in succession.
      */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
     void createAnimators(@NonNull ViewGroup sceneRoot, @NonNull TransitionValuesMaps startValues,
             @NonNull TransitionValuesMaps endValues,
             @NonNull ArrayList<TransitionValues> startValuesList,
@@ -706,6 +756,7 @@
         long minStartDelay = Long.MAX_VALUE;
         SparseIntArray startDelays = new SparseIntArray();
         int startValuesListCount = startValuesList.size();
+        boolean hasSeekController = getRootTransition().mSeekController != null;
         for (int i = 0; i < startValuesListCount; ++i) {
             TransitionValues start = startValuesList.get(i);
             TransitionValues end = endValuesList.get(i);
@@ -780,7 +831,12 @@
                             minStartDelay = Math.min(delay, minStartDelay);
                         }
                         AnimationInfo info = new AnimationInfo(view, getName(), this,
-                                ViewUtils.getWindowId(sceneRoot), infoValues);
+                                ViewUtils.getWindowId(sceneRoot), infoValues, animator);
+                        if (hasSeekController) {
+                            AnimatorSet set = new AnimatorSet();
+                            set.play(animator);
+                            animator = set;
+                        }
                         runningAnimators.put(animator, info);
                         mAnimators.add(animator);
                     }
@@ -791,8 +847,10 @@
             for (int i = 0; i < startDelays.size(); i++) {
                 int index = startDelays.keyAt(i);
                 Animator animator = mAnimators.get(index);
-                long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay();
-                animator.setStartDelay(delay);
+                AnimationInfo info = runningAnimators.get(animator);
+                long delay = startDelays.valueAt(i) - minStartDelay
+                        + info.mAnimator.getStartDelay();
+                info.mAnimator.setStartDelay(delay);
             }
         }
     }
@@ -801,7 +859,7 @@
      * Internal utility method for checking whether a given view/id
      * is valid for this transition, where "valid" means that either
      * the Transition has no target/targetId list (the default, in which
-     * cause the transition should act on all views in the hiearchy), or
+     * cause the transition should act on all views in the hierarchy), or
      * the given view is in the target list or the view id is in the
      * targetId list. If the target parameter is null, then the target list
      * is not checked (this is in the case of ListView items, where the
@@ -861,7 +919,7 @@
 
     /**
      * This is called internally once all animations have been set up by the
-     * transition hierarchy. \
+     * transition hierarchy.
      *
      */
     @RestrictTo(LIBRARY_GROUP_PREFIX)
@@ -906,6 +964,42 @@
     }
 
     /**
+     * Configures the animators to be ready for animation.
+     *
+     * The animators' start delay, duration, and interpolator are set based on the Transition's
+     * values. The duration is calculated. It also adds the animators to mCurrentAnimators so that
+     * each animator can support seeking.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    void prepareAnimatorsForSeeking() {
+        ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
+        // Now prepare every Animator that was previously created for this transition
+        mTotalDuration = 0;
+        for (int i = 0; i < mAnimators.size(); i++) {
+            Animator anim = mAnimators.get(i);
+            if (DBG) {
+                Log.d(LOG_TAG, "  anim: " + anim);
+            }
+            AnimationInfo info = runningAnimators.get(anim);
+            if (anim != null && info != null) {
+                if (getDuration() >= 0) {
+                    info.mAnimator.setDuration(getDuration());
+                }
+                if (getStartDelay() >= 0) {
+                    info.mAnimator.setStartDelay(
+                            getStartDelay() + info.mAnimator.getStartDelay());
+                }
+                if (getInterpolator() != null) {
+                    info.mAnimator.setInterpolator(getInterpolator());
+                }
+                mCurrentAnimators.add(anim);
+                mTotalDuration = Math.max(mTotalDuration, Impl26.getTotalDuration(anim));
+            }
+        }
+        mAnimators.clear();
+    }
+
+    /**
      * Captures the values in the start scene for the properties that this
      * transition monitors. These values are then passed as the startValues
      * structure in a later call to
@@ -1454,6 +1548,20 @@
     }
 
     /**
+     * Returns {@code true} if the Transition can be used by
+     * {@link TransitionManager#controlDelayedTransition(ViewGroup, Transition)}. This means
+     * that any the state must be ready before any {@link Animator} returned by
+     * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} has started and
+     * if the Animator has ended, it must be able to restore the state when starting in reverse.
+     * If a Transition must know when the entire transition has ended, a {@link TransitionListener}
+     * can be added to {@link #getRootTransition()} and it can listen for
+     * {@link TransitionListener#onTransitionEnd(Transition)}.
+     */
+    public boolean isSeekingSupported() {
+        return false;
+    }
+
+    /**
      * Recursive method that captures values for the given view and the
      * hierarchy underneath it.
      *
@@ -1715,14 +1823,7 @@
                 Animator animator = mCurrentAnimators.get(i);
                 AnimatorUtils.pause(animator);
             }
-            if (mListeners != null && mListeners.size() > 0) {
-                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionPause(this);
-                }
-            }
+            notifyListeners(TransitionNotification.ON_PAUSE, false);
             mPaused = true;
         }
     }
@@ -1742,14 +1843,7 @@
                     Animator animator = mCurrentAnimators.get(i);
                     AnimatorUtils.resume(animator);
                 }
-                if (mListeners != null && mListeners.size() > 0) {
-                    @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
-                            (ArrayList<TransitionListener>) mListeners.clone();
-                    int numListeners = tmpListeners.size();
-                    for (int i = 0; i < numListeners; ++i) {
-                        tmpListeners.get(i).onTransitionResume(this);
-                    }
-                }
+                notifyListeners(TransitionNotification.ON_RESUME, false);
             }
             mPaused = false;
         }
@@ -1760,6 +1854,7 @@
      * createAnimators() to set things up and create all of the animations and then
      * runAnimations() to actually start the animations.
      */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
     void playTransition(@NonNull ViewGroup sceneRoot) {
         mStartValuesList = new ArrayList<>();
         mEndValuesList = new ArrayList<>();
@@ -1784,7 +1879,22 @@
                     boolean cancel = (startValues != null || endValues != null)
                             && oldInfo.mTransition.isTransitionRequired(oldValues, endValues);
                     if (cancel) {
-                        if (anim.isRunning() || anim.isStarted()) {
+                        Transition transition = oldInfo.mTransition;
+                        if (transition.getRootTransition().mSeekController != null) {
+                            // Seeking, so cancel the transition directly rather than going through
+                            // a listener
+                            anim.cancel();
+                            transition.mCurrentAnimators.remove(anim);
+                            runningAnimators.remove(anim);
+                            if (transition.mCurrentAnimators.size() == 0) {
+                                transition.notifyListeners(TransitionNotification.ON_CANCEL, false);
+                                if (!transition.mEnded) {
+                                    transition.mEnded = true;
+                                    transition.notifyListeners(TransitionNotification.ON_END,
+                                            false);
+                                }
+                            }
+                        } else if (anim.isRunning() || anim.isStarted()) {
                             if (DBG) {
                                 Log.d(LOG_TAG, "Canceling anim " + anim);
                             }
@@ -1801,7 +1911,13 @@
         }
 
         createAnimators(sceneRoot, mStartValues, mEndValues, mStartValuesList, mEndValuesList);
-        runAnimators();
+        if (mSeekController == null) {
+            runAnimators();
+        } else if (BuildCompat.isAtLeastU()) {
+            prepareAnimatorsForSeeking();
+            mSeekController.setCurrentPlayTimeMillis(0);
+            mSeekController.ready();
+        }
     }
 
     /**
@@ -1909,14 +2025,7 @@
     @RestrictTo(LIBRARY_GROUP_PREFIX)
     protected void start() {
         if (mNumInstances == 0) {
-            if (mListeners != null && mListeners.size() > 0) {
-                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionStart(this);
-                }
-            }
+            notifyListeners(TransitionNotification.ON_START, false);
             mEnded = false;
         }
         mNumInstances++;
@@ -1936,14 +2045,7 @@
     protected void end() {
         --mNumInstances;
         if (mNumInstances == 0) {
-            if (mListeners != null && mListeners.size() > 0) {
-                @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
-                        (ArrayList<TransitionListener>) mListeners.clone();
-                int numListeners = tmpListeners.size();
-                for (int i = 0; i < numListeners; ++i) {
-                    tmpListeners.get(i).onTransitionEnd(this);
-                }
-            }
+            notifyListeners(TransitionNotification.ON_END, false);
             for (int i = 0; i < mStartValues.mItemIdValues.size(); ++i) {
                 View view = mStartValues.mItemIdValues.valueAt(i);
                 if (view != null) {
@@ -1996,14 +2098,7 @@
             Animator animator = mCurrentAnimators.get(i);
             animator.cancel();
         }
-        if (mListeners != null && mListeners.size() > 0) {
-            @SuppressWarnings("unchecked") ArrayList<TransitionListener> tmpListeners =
-                    (ArrayList<TransitionListener>) mListeners.clone();
-            int numListeners = tmpListeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                tmpListeners.get(i).onTransitionCancel(this);
-            }
-        }
+        notifyListeners(TransitionNotification.ON_CANCEL, false);
     }
 
     /**
@@ -2169,6 +2264,7 @@
                 return;
             }
             boolean containsAll = true;
+            //noinspection ForLoopReplaceableByForEach
             for (int i = 0; i < propertyNames.length; i++) {
                 if (!transitionValues.values.containsKey(propertyNames[i])) {
                     containsAll = false;
@@ -2201,6 +2297,10 @@
             clone.mEndValues = new TransitionValuesMaps();
             clone.mStartValuesList = null;
             clone.mEndValuesList = null;
+            clone.mSeekController = null;
+            if (mListeners != null) {
+                clone.mListeners = new ArrayList<>(mListeners);
+            }
             return clone;
         } catch (CloneNotSupportedException e) {
             throw new RuntimeException(e);
@@ -2224,39 +2324,114 @@
         return mName;
     }
 
+    /**
+     * Calls notification on each listener.
+     */
+    void notifyListeners(TransitionNotification notification, boolean isReversed) {
+        if (mListeners != null && !mListeners.isEmpty()) {
+            // Use a cache so that we don't have to keep allocating on every notification
+            int size = mListeners.size();
+            TransitionListener[] listeners = mListenersCache == null
+                    ? new TransitionListener[size] : mListenersCache;
+            mListenersCache = null;
+            listeners = mListeners.toArray(listeners);
+            for (int i = 0; i < size; i++) {
+                notification.notifyListener(listeners[i], Transition.this, isReversed);
+                listeners[i] = null;
+            }
+            mListenersCache = listeners;
+        }
+    }
+
+    /**
+     * Returns the total duration of this Transition. This is only valid after the transition has
+     * been started.
+     */
+    final long getTotalDurationMillis() {
+        return mTotalDuration;
+    }
+
+    /**
+     * Seek the Transition to playTimeMillis.
+     *
+     * @param playTimeMillis The current time (in milliseconds) of the transition. If it is less
+     *                       than 0, the transition will be set to the beginning. If it is
+     *                       larger than getTotalDurationMillis(), it will be set to the end.
+     * @param lastPlayTimeMillis The previous play time that was set. This can be negative to
+     *                           indicate that the transition hasn't been played yet or larger
+     *                           than getTotalDurationMillis() to indicate that it is playing
+     *                           backwards.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    void setCurrentPlayTimeMillis(long playTimeMillis, long lastPlayTimeMillis) {
+        long duration = getTotalDurationMillis();
+        boolean isReversed = playTimeMillis < lastPlayTimeMillis;
+        if ((lastPlayTimeMillis < 0 && playTimeMillis >= 0)
+                || (lastPlayTimeMillis > duration && playTimeMillis <= duration)) {
+            mEnded = false;
+            notifyListeners(TransitionNotification.ON_START, isReversed);
+        }
+        for (int i = 0; i < mCurrentAnimators.size(); i++) {
+            Animator animator = mCurrentAnimators.get(i);
+            long animDuration = Impl26.getTotalDuration(animator);
+            long playTime = Math.min(Math.max(0, playTimeMillis), animDuration);
+            Impl26.setCurrentPlayTime(animator, playTime);
+        }
+
+        if ((playTimeMillis > duration && lastPlayTimeMillis <= duration)
+                || (playTimeMillis < 0 && lastPlayTimeMillis >= 0)
+        ) {
+            if (playTimeMillis > duration) {
+                // Only mark it as finished after the end. Otherwise, it won't
+                // receive pause/resume calls.
+                mEnded = true;
+            }
+            notifyListeners(TransitionNotification.ON_END, isReversed);
+        }
+    }
+
     String toString(String indent) {
-        String result = indent + getClass().getSimpleName() + "@"
-                + Integer.toHexString(hashCode()) + ": ";
+        StringBuilder result = new StringBuilder(indent)
+                .append(getClass().getSimpleName())
+                .append("@")
+                .append(Integer.toHexString(hashCode()))
+                .append(": ");
         if (mDuration != -1) {
-            result += "dur(" + mDuration + ") ";
+            result.append("dur(")
+                    .append(mDuration)
+                    .append(") ");
         }
         if (mStartDelay != -1) {
-            result += "dly(" + mStartDelay + ") ";
+            result.append("dly(")
+                    .append(mStartDelay)
+                    .append(") ");
         }
         if (mInterpolator != null) {
-            result += "interp(" + mInterpolator + ") ";
+            result.append("interp(")
+                    .append(mInterpolator)
+                    .append(") ");
         }
         if (mTargetIds.size() > 0 || mTargets.size() > 0) {
-            result += "tgts(";
+            result.append("tgts(");
             if (mTargetIds.size() > 0) {
                 for (int i = 0; i < mTargetIds.size(); ++i) {
                     if (i > 0) {
-                        result += ", ";
+                        result.append(", ");
                     }
-                    result += mTargetIds.get(i);
+                    result.append(mTargetIds.get(i));
                 }
             }
             if (mTargets.size() > 0) {
                 for (int i = 0; i < mTargets.size(); ++i) {
                     if (i > 0) {
-                        result += ", ";
+                        result.append(", ");
                     }
-                    result += mTargets.get(i);
+                    result.append(mTargets.get(i));
                 }
             }
-            result += ")";
+            result.append(")");
         }
-        return result;
+        return result.toString();
     }
 
     /**
@@ -2273,6 +2448,16 @@
         void onTransitionStart(@NonNull Transition transition);
 
         /**
+         * Notification about the start of the transition.
+         *
+         * @param transition The started transition.
+         * @param isReverse {@code true} when seeking the transition backwards from the end.
+         */
+        default void onTransitionStart(@NonNull Transition transition, boolean isReverse) {
+            onTransitionStart(transition);
+        }
+
+        /**
          * Notification about the end of the transition. Canceled transitions
          * will always notify listeners of both the cancellation and end
          * events. That is, {@link #onTransitionEnd(Transition)} is always called,
@@ -2284,6 +2469,21 @@
         void onTransitionEnd(@NonNull Transition transition);
 
         /**
+         * Notification about the end of the transition. Canceled transitions
+         * will always notify listeners of both the cancellation and end
+         * events. That is, {@link #onTransitionEnd(Transition, boolean)} is always called,
+         * regardless of whether the transition was canceled or played
+         * through to completion. Canceled transitions will have {@code isReverse}
+         * set to {@code false}.
+         *
+         * @param transition The transition which reached its end.
+         * @param isReverse {@code true} when seeking the transition backwards past the start.
+         */
+        default void onTransitionEnd(@NonNull Transition transition, boolean isReverse) {
+            onTransitionEnd(transition);
+        }
+
+        /**
          * Notification about the cancellation of the transition.
          * Note that cancel may be called by a parent {@link TransitionSet} on
          * a child transition which has not yet started. This allows the child
@@ -2338,13 +2538,16 @@
 
         Transition mTransition;
 
+        Animator mAnimator;
+
         AnimationInfo(View view, String name, Transition transition, WindowIdImpl windowId,
-                TransitionValues values) {
+                TransitionValues values, Animator animator) {
             mView = view;
             mName = name;
             mValues = values;
             mWindowId = windowId;
             mTransition = transition;
+            mAnimator = animator;
         }
     }
 
@@ -2420,4 +2623,212 @@
         public abstract Rect onGetEpicenter(@NonNull Transition transition);
     }
 
+    /**
+     * Used internally by notifyListener() to call TransitionListener methods for this transition.
+     */
+    interface TransitionNotification {
+        /**
+         * Make a call on a TransitionListener
+         * @param listener The listener that this should call on.
+         * @param transition The Transition making the call.
+         */
+        void notifyListener(
+                @NonNull TransitionListener listener,
+                @NonNull Transition transition,
+                boolean isReversed
+        );
+
+        /**
+         * Call for TransitionListener#onTransitionStart()
+         */
+        TransitionNotification ON_START = TransitionListener::onTransitionStart;
+
+        /**
+         * Call for TransitionListener#onTransitionEnd()
+         */
+        TransitionNotification ON_END = TransitionListener::onTransitionEnd;
+
+        /**
+         * Call for TransitionListener#onTransitionCancel()
+         */
+        TransitionNotification ON_CANCEL =
+                (listener, transition, isReversed) -> listener.onTransitionCancel(transition);
+
+        /**
+         * Call for TransitionListener#onTransitionPause()
+         */
+        TransitionNotification ON_PAUSE =
+                (listener, transition, isReversed) -> listener.onTransitionPause(transition);
+
+        /**
+         * Call for TransitionListener#onTransitionResume()
+         */
+        TransitionNotification ON_RESUME =
+                (listener, transition, isReversed) -> listener.onTransitionResume(transition);
+    }
+
+    @RequiresApi(Build.VERSION_CODES.O)
+    private static class Impl26 {
+        @DoNotInline
+        static long getTotalDuration(Animator animator) {
+            return animator.getTotalDuration();
+        }
+
+        @DoNotInline
+        static void setCurrentPlayTime(Animator animator, long playTimeMillis) {
+            ((AnimatorSet) animator).setCurrentPlayTime(playTimeMillis);
+        }
+    }
+
+    /**
+     * Internal implementation of TransitionSeekController.
+     */
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    class SeekController extends TransitionListenerAdapter implements TransitionSeekController,
+            ValueAnimator.AnimatorUpdateListener {
+        private long mCurrentPlayTime = -1;
+        private ArrayList<Consumer<TransitionSeekController>> mOnReadyListeners = null;
+        private boolean mIsReady;
+        private boolean mIsCanceled;
+
+        private ValueAnimator mAnimator;
+        private boolean mIsAnimatingReversed;
+
+        @Override
+        public long getDurationMillis() {
+            return Transition.this.getTotalDurationMillis();
+        }
+
+        @Override
+        public long getCurrentPlayTimeMillis() {
+            return Math.min(getDurationMillis(), Math.max(0, mCurrentPlayTime));
+        }
+
+        @Override
+        public boolean isReady() {
+            return mIsReady;
+        }
+
+        public void ready() {
+            mIsReady = true;
+            if (mOnReadyListeners != null) {
+                ArrayList<Consumer<TransitionSeekController>> onReadyListeners = mOnReadyListeners;
+                mOnReadyListeners = null;
+                for (int i = 0; i < onReadyListeners.size(); i++) {
+                    onReadyListeners.get(i).accept(this);
+                }
+            }
+        }
+
+        @Override
+        public void setCurrentPlayTimeMillis(long playTimeMillis) {
+            if (mAnimator != null) {
+                throw new IllegalStateException("setCurrentPlayTimeMillis() called after animation "
+                        + "has been started");
+            }
+            if (playTimeMillis == mCurrentPlayTime) {
+                return; // no change
+            }
+
+            if (!mIsCanceled) {
+                if (playTimeMillis == 0 && mCurrentPlayTime > 0) {
+                    // Force the transition to end
+                    playTimeMillis = -1;
+                } else {
+                    long duration = getDurationMillis();
+                    // Force the transition to the end
+                    if (playTimeMillis == duration && mCurrentPlayTime < duration) {
+                        playTimeMillis = duration + 1;
+                    }
+                }
+                if (playTimeMillis != mCurrentPlayTime) {
+                    Transition.this.setCurrentPlayTimeMillis(playTimeMillis, mCurrentPlayTime);
+                    mCurrentPlayTime = playTimeMillis;
+                }
+            }
+        }
+
+        @Override
+        public void addOnReadyListener(
+                @NonNull Consumer<TransitionSeekController> onReadyListener
+        ) {
+            if (isReady()) {
+                onReadyListener.accept(this);
+                return;
+            }
+            if (mOnReadyListeners == null) {
+                mOnReadyListeners = new ArrayList<>();
+            }
+            mOnReadyListeners.add(onReadyListener);
+        }
+
+        @Override
+        public void removeOnReadyListener(
+                @NonNull Consumer<TransitionSeekController> onReadyListener
+        ) {
+            if (mOnReadyListeners != null) {
+                mOnReadyListeners.remove(onReadyListener);
+                if (mOnReadyListeners.isEmpty()) {
+                    mOnReadyListeners = null;
+                }
+            }
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+            mIsCanceled = true;
+        }
+
+        @Override
+        public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) {
+            long time = Math.max(-1,
+                    Math.min(getDurationMillis() + 1, mAnimator.getCurrentPlayTime())
+            );
+            if (mIsAnimatingReversed) {
+                time = getDurationMillis() - time;
+            }
+            Transition.this.setCurrentPlayTimeMillis(time, mCurrentPlayTime);
+            mCurrentPlayTime = time;
+        }
+
+        private void createAnimator() {
+            long duration = getDurationMillis() + 1;
+            mAnimator = ValueAnimator.ofInt((int) duration);
+            mAnimator.setInterpolator(null);
+            mAnimator.setDuration(duration);
+            mAnimator.addUpdateListener(this);
+        }
+
+        @Override
+        public void animateToEnd() {
+            if (mAnimator != null) {
+                mAnimator.cancel();
+            }
+            final long duration = getDurationMillis();
+            if (mCurrentPlayTime > duration) {
+                return; // we're already at the end
+            }
+            createAnimator();
+            mIsAnimatingReversed = false;
+            mAnimator.setCurrentPlayTime(mCurrentPlayTime);
+            mAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    notifyListeners(TransitionNotification.ON_END, false);
+                }
+            });
+            mAnimator.start();
+        }
+
+        @Override
+        public void animateToStart() {
+            if (mAnimator != null) {
+                mAnimator.cancel();
+            }
+            createAnimator();
+            mAnimator.setCurrentPlayTime(getDurationMillis() - mCurrentPlayTime);
+            mIsAnimatingReversed = true;
+            mAnimator.start();
+        }
+    }
 }
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionManager.java b/transition/transition/src/main/java/androidx/transition/TransitionManager.java
index ccfd27b..ea86ef7 100644
--- a/transition/transition/src/main/java/androidx/transition/TransitionManager.java
+++ b/transition/transition/src/main/java/androidx/transition/TransitionManager.java
@@ -24,7 +24,10 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.OptIn;
+import androidx.annotation.VisibleForTesting;
 import androidx.collection.ArrayMap;
+import androidx.core.os.BuildCompat;
 import androidx.core.view.ViewCompat;
 
 import java.lang.ref.WeakReference;
@@ -193,6 +196,7 @@
         }
     }
 
+    @VisibleForTesting
     static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
         WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
                 sRunningTransitions.get();
@@ -419,6 +423,60 @@
     }
 
     /**
+     * Create a {@link TransitionSeekController} to allow seeking an animation to a new
+     * scene defined by all changes within the given scene root between calling this method and
+     * the next rendered frame. Calling this method causes TransitionManager to capture current
+     * values in the scene root and then post a request to run a transition on the next frame.
+     * At that time, the new values in the scene root will be captured and changes
+     * will be animated. There is no need to create a Scene; it is implied by
+     * changes which take place between calling this method and the next frame when
+     * the transition begins.
+     *
+     * <p>Calling this method several times before the next frame (for example, if
+     * unrelated code also wants to make dynamic changes and run a transition on
+     * the same scene root), only the first call will trigger capturing values
+     * and exiting the current scene. Subsequent calls to the method with the
+     * same scene root during the same frame will be ignored.</p>
+     *
+     * @param sceneRoot  The root of the View hierarchy to run the transition on.
+     * @param transition The transition to use for this change.
+     * @return a {@link TransitionSeekController} that can be used control the animation to the
+     * destination scene. {@code null} is returned when seeking is not supported on the scene,
+     * either because it is running on {@link android.os.Build.VERSION_CODES.TIRAMISU} or earlier,
+     * another Transition is being captured for {@code sceneRoot}, or {@code sceneRoot} hasn't
+     * had a layout yet.
+     * @throws IllegalArgumentException if {@code transition} returns {@code false} from
+     * {@link Transition#isSeekingSupported()}.
+     */
+    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
+    @Nullable
+    public static TransitionSeekController controlDelayedTransition(
+            @NonNull final ViewGroup sceneRoot,
+            @NonNull Transition transition
+    ) {
+        if (sPendingTransitions.contains(sceneRoot) || !ViewCompat.isLaidOut(sceneRoot)
+                || !BuildCompat.isAtLeastU()) {
+            return null;
+        }
+        if (!transition.isSeekingSupported()) {
+            throw new IllegalArgumentException("The Transition must support seeking.");
+        }
+        if (Transition.DBG) {
+            Log.d(LOG_TAG, "controlDelayedTransition: root, transition = "
+                    + sceneRoot + ", " + transition);
+        }
+        sPendingTransitions.add(sceneRoot);
+        final Transition transitionClone = transition.clone();
+        final TransitionSet set = new TransitionSet();
+        set.addTransition(transitionClone);
+        sceneChangeSetup(sceneRoot, set);
+        Scene.setCurrentScene(sceneRoot, null);
+        sceneChangeRunTransition(sceneRoot, set);
+        sceneRoot.invalidate();
+        return set.createSeekController();
+    }
+
+    /**
      * Ends all pending and ongoing transitions on the specified scene root.
      *
      * @param sceneRoot The root of the View hierarchy to end transitions on.
@@ -435,5 +493,4 @@
             }
         }
     }
-
 }
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java b/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java
new file mode 100644
index 0000000..bcede11
--- /dev/null
+++ b/transition/transition/src/main/java/androidx/transition/TransitionSeekController.java
@@ -0,0 +1,102 @@
+/*
+ * 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.transition;
+
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.core.util.Consumer;
+
+/**
+ * Returned from {@link TransitionManager#controlDelayedTransition(ViewGroup, Transition)}
+ * to allow manually controlling the animations within a Transition using
+ * {@link #setCurrentPlayTimeMillis(long)}. The transition will be ready to seek when
+ * {@link #isReady()} is {@code true}.
+ */
+public interface TransitionSeekController {
+    /**
+     * @return The total duration, in milliseconds, of the Transition's animations.
+     */
+    long getDurationMillis();
+
+    /**
+     * @return The time, in milliseconds, of the animation. This will be between 0
+     * and {@link #getDurationMillis()}.
+     */
+    long getCurrentPlayTimeMillis();
+
+    /**
+     * Returns {@code true} when the Transition is ready to seek or {@code false}
+     * when the Transition's animations have yet to be built.
+     */
+    boolean isReady();
+
+    /**
+     * Runs the animation backwards toward the start. {@link #setCurrentPlayTimeMillis(long)}
+     * will not be allowed after executing this. When the animation completes,
+     * {@link androidx.transition.Transition.TransitionListener#onTransitionEnd(Transition)}
+     * will be called with the {@code isReverse} parameter {@code true}.
+     *
+     * The developer will likely want to run
+     * {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)} to set the state
+     * back to the beginning state after it ends.
+     *
+     * After calling this, {@link #setCurrentPlayTimeMillis(long)} may not be called.
+     */
+    void animateToStart();
+
+    /**
+     * Runs the animation forwards toward the end. {@link #setCurrentPlayTimeMillis(long)}
+     * will not be allowed after executing this. When the animation completes,
+     * {@link androidx.transition.Transition.TransitionListener#onTransitionEnd(Transition)}
+     * will be called with the {@code isReverse} parameter {@code false}.
+     *
+     * After the Transition ends, the state will reach the final state set after
+     * {@link TransitionManager#controlDelayedTransition(ViewGroup, Transition)}.
+     *
+     * After calling this, {@link #setCurrentPlayTimeMillis(long)} may not be called.
+     */
+    void animateToEnd();
+
+    /**
+     * Sets the position of the Transition's animation. {@code playTimeMillis} should be
+     * between 0 and {@link #getDurationMillis()}. This should not be called when
+     * {@link #isReady()} is {@code false}.
+     *
+     * @param playTimeMillis The time, between 0 and {@link #getDurationMillis()} that the
+     *                       animation should play.
+     */
+    void setCurrentPlayTimeMillis(long playTimeMillis);
+
+    /**
+     * Adds a listener to know when {@link #isReady()} is {@code true}. The listener will
+     * be removed once notified as {@link #isReady()} can only be made true once. If
+     * {@link #isReady()} is already {@code true}, then it will be notified immediately.
+     *
+     * @param onReadyListener The listener to be notified when the Transition is ready.
+     */
+    void addOnReadyListener(@NonNull Consumer<TransitionSeekController> onReadyListener);
+
+    /**
+     * Removes {@code onReadyListener} that was previously added in
+     * {@link #addOnReadyListener(Consumer)} so that it won't be called.
+     *
+     * @param onReadyListener The listener to be removed so that it won't be notified when ready.
+     */
+    void removeOnReadyListener(@NonNull Consumer<TransitionSeekController> onReadyListener);
+}
+
diff --git a/transition/transition/src/main/java/androidx/transition/TransitionSet.java b/transition/transition/src/main/java/androidx/transition/TransitionSet.java
index b1a1a3e..c875b2b 100644
--- a/transition/transition/src/main/java/androidx/transition/TransitionSet.java
+++ b/transition/transition/src/main/java/androidx/transition/TransitionSet.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.os.Build;
 import android.util.AndroidRuntimeException;
 import android.util.AttributeSet;
 import android.view.View;
@@ -31,6 +32,7 @@
 import androidx.annotation.IdRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 import androidx.core.content.res.TypedArrayUtils;
 
@@ -77,7 +79,7 @@
      */
     private static final int FLAG_CHANGE_EPICENTER = 0x08;
 
-    private ArrayList<Transition> mTransitions = new ArrayList<>();
+    ArrayList<Transition> mTransitions = new ArrayList<>();
     private boolean mPlayTogether = true;
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     int mCurrentListeners;
@@ -515,6 +517,124 @@
         }
     }
 
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @Override
+    void prepareAnimatorsForSeeking() {
+        mTotalDuration = 0;
+        TransitionListenerAdapter listener = new TransitionListenerAdapter() {
+            @Override
+            public void onTransitionCancel(@NonNull Transition transition) {
+                mTransitions.remove(transition);
+                if (mTransitions.isEmpty()) {
+                    notifyListeners(TransitionNotification.ON_CANCEL, false);
+                    if (!mEnded) {
+                        mEnded = true;
+                        notifyListeners(TransitionNotification.ON_END, false);
+                    }
+                }
+            }
+        };
+        for (int i = 0; i < mTransitions.size(); ++i) {
+            Transition transition = mTransitions.get(i);
+            transition.addListener(listener);
+            transition.prepareAnimatorsForSeeking();
+            long duration = transition.getTotalDurationMillis();
+            if (mPlayTogether) {
+                mTotalDuration = Math.max(mTotalDuration, duration);
+            } else {
+                transition.mSeekOffsetInParent = mTotalDuration;
+                mTotalDuration += duration;
+            }
+        }
+    }
+
+    /**
+     * Returns the index of the Transition that is playing at playTime. If no such transition
+     * exists, either because that Transition has been canceled or the TransitionSet is empty,
+     * the index of the one prior, or 0 will be returned.
+     */
+    private int indexOfTransition(long playTime) {
+        for (int i = 1; i < mTransitions.size(); i++) {
+            Transition transition = mTransitions.get(i);
+            if (transition.mSeekOffsetInParent > playTime) {
+                return i - 1;
+            }
+        }
+        return mTransitions.size() - 1;
+    }
+
+    @RequiresApi(Build.VERSION_CODES.TIRAMISU)
+    @Override
+    void setCurrentPlayTimeMillis(long playTimeMillis, long lastPlayTimeMillis) {
+        long duration = getTotalDurationMillis();
+        if (mParent != null && ((playTimeMillis < 0 && lastPlayTimeMillis < 0)
+                || (playTimeMillis > duration && lastPlayTimeMillis > duration))
+        ) {
+            return;
+        }
+        boolean isReverse = playTimeMillis < lastPlayTimeMillis;
+        if ((playTimeMillis >= 0 && lastPlayTimeMillis < 0)
+                || (playTimeMillis <= duration && lastPlayTimeMillis > duration)
+            ) {
+            mEnded = false;
+            notifyListeners(TransitionNotification.ON_START, isReverse);
+        }
+        if (mPlayTogether) {
+            for (int i = 0; i < mTransitions.size(); i++) {
+                Transition transition = mTransitions.get(i);
+                transition.setCurrentPlayTimeMillis(playTimeMillis, lastPlayTimeMillis);
+            }
+        } else {
+            // find the Transition that lastPlayTimeMillis was using
+            int startIndex = indexOfTransition(lastPlayTimeMillis);
+
+            if (playTimeMillis >= lastPlayTimeMillis) {
+                // move forward through transitions
+                for (int i = startIndex; i < mTransitions.size(); i++) {
+                    Transition transition = mTransitions.get(i);
+                    long transitionStart = transition.mSeekOffsetInParent;
+                    long playTime = playTimeMillis - transitionStart;
+                    if (playTime < 0) {
+                        break; // went past
+                    }
+                    long lastPlayTime = lastPlayTimeMillis - transitionStart;
+                    transition.setCurrentPlayTimeMillis(playTime, lastPlayTime);
+                }
+            } else {
+                // move backwards through transitions
+                for (int i = startIndex; i >= 0; i--) {
+                    Transition transition = mTransitions.get(i);
+                    long transitionStart = transition.mSeekOffsetInParent;
+                    long playTime = playTimeMillis - transitionStart;
+                    long lastPlayTime = lastPlayTimeMillis - transitionStart;
+                    transition.setCurrentPlayTimeMillis(playTime, lastPlayTime);
+                    if (playTime >= 0) {
+                        break;
+                    }
+                }
+            }
+        }
+        if (mParent != null && ((playTimeMillis > duration && lastPlayTimeMillis <= duration)
+                || (playTimeMillis < 0 && lastPlayTimeMillis >= 0))
+        ) {
+            if (playTimeMillis > duration) {
+                mEnded = true;
+            }
+            notifyListeners(TransitionNotification.ON_END, isReverse);
+        }
+    }
+
+    @Override
+    public boolean isSeekingSupported() {
+        int numTransitions = mTransitions.size();
+        for (int i = 0; i < numTransitions; i++) {
+            if (!mTransitions.get(i).isSeekingSupported()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Override
     public void captureStartValues(@NonNull TransitionValues transitionValues) {
         if (isValidTarget(transitionValues.view)) {
diff --git a/transition/transition/src/main/java/androidx/transition/TranslationAnimationCreator.java b/transition/transition/src/main/java/androidx/transition/TranslationAnimationCreator.java
index 7a24a33..114674c 100644
--- a/transition/transition/src/main/java/androidx/transition/TranslationAnimationCreator.java
+++ b/transition/transition/src/main/java/androidx/transition/TranslationAnimationCreator.java
@@ -77,7 +77,6 @@
                 startPosX, startPosY, terminalX, terminalY);
         transition.addListener(listener);
         anim.addListener(listener);
-        AnimatorUtils.addPauseListener(anim, listener);
         anim.setInterpolator(interpolator);
         return anim;
     }
@@ -87,20 +86,17 @@
 
         private final View mViewInHierarchy;
         private final View mMovingView;
-        private final int mStartX;
-        private final int mStartY;
         private int[] mTransitionPosition;
         private float mPausedX;
         private float mPausedY;
         private final float mTerminalX;
         private final float mTerminalY;
+        private boolean mIsAnimationCancelCalled;
 
         TransitionPositionListener(View movingView, View viewInHierarchy,
                 int startX, int startY, float terminalX, float terminalY) {
             mMovingView = movingView;
             mViewInHierarchy = viewInHierarchy;
-            mStartX = startX - Math.round(mMovingView.getTranslationX());
-            mStartY = startY - Math.round(mMovingView.getTranslationY());
             mTerminalX = terminalX;
             mTerminalY = terminalY;
             mTransitionPosition = (int[]) mViewInHierarchy.getTag(R.id.transition_position);
@@ -111,26 +107,8 @@
 
         @Override
         public void onAnimationCancel(Animator animation) {
-            if (mTransitionPosition == null) {
-                mTransitionPosition = new int[2];
-            }
-            mTransitionPosition[0] = Math.round(mStartX + mMovingView.getTranslationX());
-            mTransitionPosition[1] = Math.round(mStartY + mMovingView.getTranslationY());
-            mViewInHierarchy.setTag(R.id.transition_position, mTransitionPosition);
-        }
-
-        @Override
-        public void onAnimationPause(Animator animator) {
-            mPausedX = mMovingView.getTranslationX();
-            mPausedY = mMovingView.getTranslationY();
-            mMovingView.setTranslationX(mTerminalX);
-            mMovingView.setTranslationY(mTerminalY);
-        }
-
-        @Override
-        public void onAnimationResume(Animator animator) {
-            mMovingView.setTranslationX(mPausedX);
-            mMovingView.setTranslationY(mPausedY);
+            setInterruptedPosition();
+            mIsAnimationCancelCalled = true;
         }
 
         @Override
@@ -138,22 +116,48 @@
         }
 
         @Override
+        public void onTransitionEnd(@NonNull Transition transition, boolean isReverse) {
+            if (!isReverse) {
+                mMovingView.setTranslationX(mTerminalX);
+                mMovingView.setTranslationY(mTerminalY);
+            }
+        }
+
+        @Override
         public void onTransitionEnd(@NonNull Transition transition) {
-            mMovingView.setTranslationX(mTerminalX);
-            mMovingView.setTranslationY(mTerminalY);
-            transition.removeListener(this);
         }
 
         @Override
         public void onTransitionCancel(@NonNull Transition transition) {
+            if (!mIsAnimationCancelCalled) {
+                setInterruptedPosition();
+            }
+            mMovingView.setTranslationX(mTerminalX);
+            mMovingView.setTranslationY(mTerminalY);
+            int[] pos = new int[2];
+            mMovingView.getLocationOnScreen(pos);
         }
 
         @Override
         public void onTransitionPause(@NonNull Transition transition) {
+            mPausedX = mMovingView.getTranslationX();
+            mPausedY = mMovingView.getTranslationY();
+            mMovingView.setTranslationX(mTerminalX);
+            mMovingView.setTranslationY(mTerminalY);
         }
 
         @Override
         public void onTransitionResume(@NonNull Transition transition) {
+            mMovingView.setTranslationX(mPausedX);
+            mMovingView.setTranslationY(mPausedY);
+        }
+
+        private void setInterruptedPosition() {
+            if (mTransitionPosition == null) {
+                mTransitionPosition = new int[2];
+            }
+            mMovingView.getLocationOnScreen(mTransitionPosition);
+            mViewInHierarchy.setTag(R.id.transition_position, mTransitionPosition);
         }
     }
 
diff --git a/transition/transition/src/main/java/androidx/transition/Visibility.java b/transition/transition/src/main/java/androidx/transition/Visibility.java
index a9f85bd..8b3fc2e 100644
--- a/transition/transition/src/main/java/androidx/transition/Visibility.java
+++ b/transition/transition/src/main/java/androidx/transition/Visibility.java
@@ -436,31 +436,13 @@
                     ViewGroupUtils.getOverlay(sceneRoot).remove(overlayView);
                 } else {
                     startView.setTag(R.id.save_overlay_view, overlayView);
-                    final View finalOverlayView = overlayView;
-                    final ViewGroup overlayHost = sceneRoot;
-                    addListener(new TransitionListenerAdapter() {
 
-                        @Override
-                        public void onTransitionPause(@NonNull Transition transition) {
-                            ViewGroupUtils.getOverlay(overlayHost).remove(finalOverlayView);
-                        }
+                    OverlayListener listener = new OverlayListener(sceneRoot, overlayView,
+                            startView);
 
-                        @Override
-                        public void onTransitionResume(@NonNull Transition transition) {
-                            if (finalOverlayView.getParent() == null) {
-                                ViewGroupUtils.getOverlay(overlayHost).add(finalOverlayView);
-                            } else {
-                                cancel();
-                            }
-                        }
-
-                        @Override
-                        public void onTransitionEnd(@NonNull Transition transition) {
-                            startView.setTag(R.id.save_overlay_view, null);
-                            ViewGroupUtils.getOverlay(overlayHost).remove(finalOverlayView);
-                            transition.removeListener(this);
-                        }
-                    });
+                    animator.addListener(listener);
+                    AnimatorUtils.addPauseListener(animator, listener);
+                    getRootTransition().addListener(listener);
                 }
             }
             return animator;
@@ -474,8 +456,7 @@
                 DisappearListener disappearListener = new DisappearListener(viewToKeep,
                         endVisibility, true);
                 animator.addListener(disappearListener);
-                AnimatorUtils.addPauseListener(animator, disappearListener);
-                addListener(disappearListener);
+                getRootTransition().addListener(disappearListener);
             } else {
                 ViewUtils.setTransitionVisibility(viewToKeep, originalVisibility);
             }
@@ -525,7 +506,7 @@
     }
 
     private static class DisappearListener extends AnimatorListenerAdapter
-            implements TransitionListener, AnimatorUtils.AnimatorPauseListenerCompat {
+            implements TransitionListener {
 
         private final View mView;
         private final int mFinalVisibility;
@@ -544,24 +525,6 @@
             suppressLayout(true);
         }
 
-        // This overrides both AnimatorListenerAdapter and
-        // AnimatorUtilsApi14.AnimatorPauseListenerCompat
-        @Override
-        public void onAnimationPause(Animator animation) {
-            if (!mCanceled) {
-                ViewUtils.setTransitionVisibility(mView, mFinalVisibility);
-            }
-        }
-
-        // This overrides both AnimatorListenerAdapter and
-        // AnimatorUtilsApi14.AnimatorPauseListenerCompat
-        @Override
-        public void onAnimationResume(Animator animation) {
-            if (!mCanceled) {
-                ViewUtils.setTransitionVisibility(mView, View.VISIBLE);
-            }
-        }
-
         @Override
         public void onAnimationCancel(Animator animation) {
             mCanceled = true;
@@ -581,13 +544,29 @@
         }
 
         @Override
+        public void onAnimationStart(@NonNull Animator animation, boolean isReverse) {
+            if (isReverse) {
+                ViewUtils.setTransitionVisibility(mView, View.VISIBLE);
+                if (mParent != null) {
+                    mParent.invalidate();
+                }
+            }
+        }
+
+        @Override
+        public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) {
+            if (!isReverse) {
+                hideViewWhenNotCanceled();
+            }
+        }
+
+        @Override
         public void onTransitionStart(@NonNull Transition transition) {
             // Do nothing
         }
 
         @Override
         public void onTransitionEnd(@NonNull Transition transition) {
-            hideViewWhenNotCanceled();
             transition.removeListener(this);
         }
 
@@ -598,11 +577,17 @@
         @Override
         public void onTransitionPause(@NonNull Transition transition) {
             suppressLayout(false);
+            if (!mCanceled) {
+                ViewUtils.setTransitionVisibility(mView, mFinalVisibility);
+            }
         }
 
         @Override
         public void onTransitionResume(@NonNull Transition transition) {
             suppressLayout(true);
+            if (!mCanceled) {
+                ViewUtils.setTransitionVisibility(mView, View.VISIBLE);
+            }
         }
 
         private void hideViewWhenNotCanceled() {
@@ -624,4 +609,83 @@
             }
         }
     }
+
+    private class OverlayListener extends AnimatorListenerAdapter implements TransitionListener,
+            AnimatorUtils.AnimatorPauseListenerCompat {
+        private final ViewGroup mOverlayHost;
+        private final View mOverlayView;
+        private final View mStartView;
+        private boolean mHasOverlay = true;
+
+        OverlayListener(ViewGroup overlayHost, View overlayView, View startView) {
+            mOverlayHost = overlayHost;
+            mOverlayView = overlayView;
+            mStartView = startView;
+        }
+
+        @Override
+        public void onAnimationPause(Animator animation) {
+            ViewGroupUtils.getOverlay(mOverlayHost).remove(mOverlayView);
+        }
+
+        @Override
+        public void onAnimationResume(Animator animation) {
+            if (mOverlayView.getParent() == null) {
+                ViewGroupUtils.getOverlay(mOverlayHost).add(mOverlayView);
+            } else {
+                cancel();
+            }
+        }
+
+        @Override
+        public void onAnimationStart(@NonNull Animator animation, boolean isReverse) {
+            if (isReverse) {
+                mStartView.setTag(R.id.save_overlay_view, mOverlayView);
+                ViewGroupUtils.getOverlay(mOverlayHost).add(mOverlayView);
+                mHasOverlay = true;
+            }
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            removeFromOverlay();
+        }
+
+        @Override
+        public void onAnimationEnd(@NonNull Animator animation, boolean isReverse) {
+            if (!isReverse) {
+                removeFromOverlay();
+            }
+        }
+
+        @Override
+        public void onTransitionEnd(@NonNull Transition transition) {
+            transition.removeListener(this);
+        }
+
+        @Override
+        public void onTransitionStart(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionPause(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(@NonNull Transition transition) {
+        }
+
+        @Override
+        public void onTransitionCancel(@NonNull Transition transition) {
+            if (mHasOverlay) {
+                removeFromOverlay();
+            }
+        }
+
+        private void removeFromOverlay() {
+            mStartView.setTag(R.id.save_overlay_view, null);
+            ViewGroupUtils.getOverlay(mOverlayHost).remove(mOverlayView);
+            mHasOverlay = false;
+        }
+    }
 }
diff --git a/transition/transition/src/main/res/values/ids.xml b/transition/transition/src/main/res/values/ids.xml
index b9dd584..c2f6195 100644
--- a/transition/transition/src/main/res/values/ids.xml
+++ b/transition/transition/src/main/res/values/ids.xml
@@ -20,6 +20,8 @@
     <item name="transition_layout_save" type="id"/>
     <item name="transition_position" type="id"/>
     <item name="transition_transform" type="id"/>
+    <item name="transition_image_transform" type="id"/>
+    <item name="transition_clip" type="id"/>
     <item name="parent_matrix" type="id"/>
     <item name="ghost_view" type="id"/>
     <item name="ghost_view_holder" type="id"/>
diff --git a/tv/integration-tests/playground/build.gradle b/tv/integration-tests/playground/build.gradle
index f8b1d68..b1da39a 100644
--- a/tv/integration-tests/playground/build.gradle
+++ b/tv/integration-tests/playground/build.gradle
@@ -35,6 +35,14 @@
 
     implementation(project(":tv:tv-foundation"))
     implementation(project(":tv:tv-material"))
+
+    // pull latest compose (if build fails in future, just comment the following compose deps until
+    // we fix this package)
+    implementation(project(":compose:animation:animation"))
+    implementation(project(":compose:runtime:runtime"))
+    implementation(project(":compose:ui:ui"))
+    implementation(project(":compose:foundation:foundation-layout"))
+    implementation(project(":compose:ui:ui"))
 }
 
 androidx {
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/FocusGroup.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/FocusGroup.kt
deleted file mode 100644
index 715033a..0000000
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/FocusGroup.kt
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.tv.integration.playground
-
-import android.annotation.SuppressLint
-import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.focusGroup
-import androidx.compose.foundation.layout.Box
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.currentCompositeKeyHash
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusDirection
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusProperties
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.platform.LocalFocusManager
-import androidx.tv.foundation.ExperimentalTvFoundationApi
-
-/**
- * Composable container that provides modifier extensions to allow focus to be restored to the
- * element that was previously focused within the TvFocusGroup.
- *
- * @param modifier the modifier to apply to this group.
- * @param content the content that is present within the group and can use focus-group modifier
- * extensions.
- */
-@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
-@ExperimentalTvFoundationApi
-@Composable
-fun FocusGroup(
-    modifier: Modifier = Modifier,
-    content: @Composable FocusGroupScope.() -> Unit
-) {
-    val focusGroupKeyHash = currentCompositeKeyHash
-
-    // TODO: Is this the intended way to call rememberSaveable
-    //  with key set to parentHash?
-    val previousFocusedItemHash: MutableState<Int?> = rememberSaveable(
-        key = focusGroupKeyHash.toString()
-    ) {
-        mutableStateOf(null)
-    }
-
-    val state = FocusGroupState(previousFocusedItemHash = previousFocusedItemHash)
-
-    Box(
-        modifier = modifier
-            .focusProperties {
-                enter = {
-                    if (state.hasRecordedState()) {
-                        state.focusRequester
-                    } else {
-                        FocusRequester.Default
-                    }
-                }
-            }
-            .focusGroup()
-    ) {
-        FocusGroupScope(state).content()
-    }
-}
-
-/**
- * Scope containing the modifier extensions to be used within [FocusGroup].
- */
-@ExperimentalTvFoundationApi
-class FocusGroupScope internal constructor(private val state: FocusGroupState) {
-    private var currentFocusableIdIndex = 0
-
-    private fun generateUniqueFocusableId(): Int = currentFocusableIdIndex++
-
-    /**
-     * Modifier that records if the item was in focus before it moved out of the group. When focus
-     * enters the [FocusGroup], the item will be returned focus.
-     */
-    @SuppressLint("ComposableModifierFactory")
-    @Composable
-    fun Modifier.restorableFocus(): Modifier =
-        this.restorableFocus(focusId = rememberSaveable { generateUniqueFocusableId() })
-
-    /**
-     * Modifier that marks the current composable as the item to gain focus initially when focus
-     * enters the [FocusGroup]. When focus enters the [FocusGroup], the item will be returned focus.
-     */
-    @SuppressLint("ComposableModifierFactory")
-    @Composable
-    fun Modifier.initiallyFocused(): Modifier {
-        val focusId = rememberSaveable { generateUniqueFocusableId() }
-        if (state.noRecordedState()) {
-            state.recordFocusedItemHash(focusId)
-        }
-        return this.restorableFocus(focusId)
-    }
-
-    @SuppressLint("ComposableModifierFactory")
-    @OptIn(ExperimentalComposeUiApi::class)
-    @Composable
-    private fun Modifier.restorableFocus(focusId: Int): Modifier {
-        val focusRequester = remember { FocusRequester() }
-        var isFocused = remember { false }
-        val isCurrentlyFocused by rememberUpdatedState(isFocused)
-        val focusManager = LocalFocusManager.current
-        state.associatedWith(focusId, focusRequester)
-        DisposableEffect(Unit) {
-            onDispose {
-                state.clearDisposedFocusRequester(focusId)
-                if (isCurrentlyFocused) {
-                    focusManager.moveFocus(FocusDirection.Exit)
-                    focusManager.moveFocus(FocusDirection.Enter)
-                }
-            }
-        }
-
-        return this
-            .focusRequester(focusRequester)
-            .onFocusChanged {
-                isFocused = it.isFocused || it.hasFocus
-                if (isFocused) {
-                    state.recordFocusedItemHash(focusId)
-                    state.associatedWith(focusId, focusRequester)
-                }
-            }
-    }
-}
-
-@Stable
-@ExperimentalTvFoundationApi
-internal class FocusGroupState(
-    private var previousFocusedItemHash: MutableState<Int?>
-) {
-    internal var focusRequester: FocusRequester = FocusRequester.Default
-        private set
-
-    internal fun recordFocusedItemHash(itemHash: Int) {
-        previousFocusedItemHash.value = itemHash
-    }
-
-    internal fun clearDisposedFocusRequester(itemHash: Int) {
-        if (previousFocusedItemHash.value == itemHash) {
-            focusRequester = FocusRequester.Default
-        }
-    }
-
-    internal fun associatedWith(itemHash: Int, focusRequester: FocusRequester) {
-        if (previousFocusedItemHash.value == itemHash) {
-            this.focusRequester = focusRequester
-        }
-    }
-
-    internal fun hasRecordedState(): Boolean = !noRecordedState()
-
-    internal fun noRecordedState(): Boolean =
-        previousFocusedItemHash.value == null && focusRequester == FocusRequester.Default
-}
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ImmersiveList.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ImmersiveList.kt
index ac3d021..94240b6 100644
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ImmersiveList.kt
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ImmersiveList.kt
@@ -30,7 +30,6 @@
 import androidx.compose.ui.semantics.collectionItemInfo
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
-import androidx.tv.foundation.ExperimentalTvFoundationApi
 import androidx.tv.foundation.lazy.list.TvLazyColumn
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.ImmersiveList
@@ -44,7 +43,7 @@
     }
 }
 
-@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalTvFoundationApi::class)
+@OptIn(ExperimentalTvMaterial3Api::class)
 @Composable
 private fun SampleImmersiveList() {
     val immersiveListHeight = 300.dp
@@ -56,40 +55,37 @@
         Color.Magenta,
     )
 
-    FocusGroup {
-        ImmersiveList(
-            modifier = Modifier
-                .height(immersiveListHeight + cardHeight / 2)
-                .fillMaxWidth(),
-            background = { index, _ ->
-                Box(
-                    modifier = Modifier
-                        .background(backgrounds[index].copy(alpha = 0.3f))
-                        .height(immersiveListHeight)
-                        .fillMaxWidth()
-                )
-            }
-        ) {
-            LazyRow(
-                horizontalArrangement = Arrangement.spacedBy(cardSpacing),
-                modifier = Modifier.lazyListSemantics(1, backgrounds.count())
-            ) {
-                itemsIndexed(backgrounds) { index, backgroundColor ->
-                    val cardModifier =
-                        if (index == 0)
-                            Modifier.initiallyFocused()
-                        else
-                            Modifier.restorableFocus()
+    ImmersiveList(
+        modifier = Modifier
+            .height(immersiveListHeight + cardHeight / 2)
+            .fillMaxWidth(),
+        background = { index, _ ->
+            Box(
+                modifier = Modifier
+                    .background(backgrounds[index].copy(alpha = 0.3f))
+                    .height(immersiveListHeight)
+                    .fillMaxWidth()
+            )
+        }
+    ) {
+        val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
 
-                    Card(
-                        modifier = cardModifier
-                            .semantics {
-                                collectionItemInfo = CollectionItemInfo(0, 1, index, 1)
-                            }
-                            .immersiveListItem(index),
-                        backgroundColor = backgroundColor
-                    )
-                }
+        LazyRow(
+            horizontalArrangement = Arrangement.spacedBy(cardSpacing),
+            modifier = Modifier
+                .lazyListSemantics(1, backgrounds.count())
+                .then(focusRestorerModifiers.parentModifier)
+        ) {
+            itemsIndexed(backgrounds) { index, backgroundColor ->
+                Card(
+                    modifier = Modifier
+                        .semantics {
+                            collectionItemInfo = CollectionItemInfo(0, 1, index, 1)
+                        }
+                        .immersiveListItem(index)
+                        .ifElse(index == 0, focusRestorerModifiers.childModifier),
+                    backgroundColor = backgroundColor
+                )
             }
         }
     }
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
index 2fbddf4..20134a5 100644
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/LazyRowsAndColumns.kt
@@ -31,7 +31,6 @@
 import androidx.compose.ui.semantics.collectionItemInfo
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
-import androidx.tv.foundation.ExperimentalTvFoundationApi
 import androidx.tv.foundation.PivotOffsets
 import androidx.tv.foundation.lazy.list.TvLazyColumn
 import androidx.tv.foundation.lazy.list.TvLazyRow
@@ -57,31 +56,27 @@
     }
 }
 
-@OptIn(ExperimentalTvFoundationApi::class)
 @Composable
 fun SampleLazyRow(modifier: Modifier = Modifier) {
     val colors = listOf(Color.Red, Color.Magenta, Color.Green, Color.Yellow, Color.Blue, Color.Cyan)
     val backgroundColors = List(columnsCount) { colors.random() }
+    val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
 
-    FocusGroup {
-        TvLazyRow(
-            modifier = modifier.lazyListSemantics(1, columnsCount),
-            horizontalArrangement = Arrangement.spacedBy(10.dp)
-        ) {
-            itemsIndexed(backgroundColors) { index, item ->
-                val cardModifier =
-                    if (index == 0)
-                        Modifier.initiallyFocused()
-                    else
-                        Modifier.restorableFocus()
-
-                Card(
-                    modifier = cardModifier.semantics {
+    TvLazyRow(
+        modifier = modifier
+            .lazyListSemantics(1, columnsCount)
+            .then(focusRestorerModifiers.parentModifier),
+        horizontalArrangement = Arrangement.spacedBy(10.dp)
+    ) {
+        itemsIndexed(backgroundColors) { index, item ->
+            Card(
+                modifier = Modifier
+                    .ifElse(index == 0, focusRestorerModifiers.childModifier)
+                    .semantics {
                         collectionItemInfo = CollectionItemInfo(0, 1, index, 1)
                     },
-                    backgroundColor = item
-                )
-            }
+                backgroundColor = item
+            )
         }
     }
 }
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TopNavigation.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TopNavigation.kt
index 30b8f83..7a71b47 100644
--- a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TopNavigation.kt
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/TopNavigation.kt
@@ -20,13 +20,13 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import androidx.tv.foundation.ExperimentalTvFoundationApi
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.Tab
 import androidx.tv.material3.TabRow
@@ -34,66 +34,69 @@
 import kotlinx.coroutines.delay
 
 enum class Navigation(val displayName: String, val action: @Composable () -> Unit) {
-  StandardNavigationDrawer("Standard Navigation Drawer", { StandardNavigationDrawer() }),
-  ModalNavigationDrawer("Modal Navigation Drawer", { ModalNavigationDrawer() }),
-  LazyRowsAndColumns("Lazy Rows and Columns", { LazyRowsAndColumns() }),
-  FeaturedCarousel("Featured Carousel", { FeaturedCarouselContent() }),
-  ImmersiveList("Immersive List", { ImmersiveListContent() }),
-  TextField("Text Field", { TextFieldContent() }),
-  StickyHeader("Sticky Header", { StickyHeaderContent() }),
+    StandardNavigationDrawer("Standard Navigation Drawer", { StandardNavigationDrawer() }),
+    ModalNavigationDrawer("Modal Navigation Drawer", { ModalNavigationDrawer() }),
+    LazyRowsAndColumns("Lazy Rows and Columns", { LazyRowsAndColumns() }),
+    FeaturedCarousel("Featured Carousel", { FeaturedCarouselContent() }),
+    ImmersiveList("Immersive List", { ImmersiveListContent() }),
+    TextField("Text Field", { TextFieldContent() }),
+    StickyHeader("Sticky Header", { StickyHeaderContent() }),
 }
 
 @Composable
 internal fun TopNavigation(
-  updateSelectedTab: (Navigation) -> Unit = {},
+    updateSelectedTab: (Navigation) -> Unit = {},
 ) {
-  var selectedTabIndex by remember { mutableStateOf(0) }
-  val tabs = Navigation.values().map { it.displayName }
+    var selectedTabIndex by remember { mutableStateOf(0) }
+    val tabs = Navigation.values().map { it.displayName }
 
-  // Pill indicator
-  PillIndicatorTabRow(
-    tabs = tabs,
-    selectedTabIndex = selectedTabIndex,
-    updateSelectedTab = { selectedTabIndex = it }
-  )
+    // Pill indicator
+    PillIndicatorTabRow(
+        tabs = tabs,
+        selectedTabIndex = selectedTabIndex,
+        updateSelectedTab = { selectedTabIndex = it }
+    )
 
-  LaunchedEffect(selectedTabIndex) {
-    // Only update the tab after 250 milliseconds to avoid loading intermediate tabs while
-    // fast scrolling in the TabRow
-    delay(250)
-    updateSelectedTab(Navigation.values()[selectedTabIndex])
-  }
+    LaunchedEffect(selectedTabIndex) {
+        // Only update the tab after 250 milliseconds to avoid loading intermediate tabs while
+        // fast scrolling in the TabRow
+        delay(250)
+        updateSelectedTab(Navigation.values()[selectedTabIndex])
+    }
 }
 
 /**
  * Pill indicator tab row for reference
  */
-@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalTvFoundationApi::class)
+@OptIn(ExperimentalTvMaterial3Api::class)
 @Composable
 fun PillIndicatorTabRow(
-  tabs: List<String>,
-  selectedTabIndex: Int,
-  updateSelectedTab: (Int) -> Unit
+    tabs: List<String>,
+    selectedTabIndex: Int,
+    updateSelectedTab: (Int) -> Unit
 ) {
-  FocusGroup {
-    TabRow(selectedTabIndex = selectedTabIndex) {
-      tabs.forEachIndexed { index, tab ->
-        Tab(
-          selected = index == selectedTabIndex,
-          onFocus = { updateSelectedTab(index) },
-          modifier =
-          if (tab == Navigation.StandardNavigationDrawer.displayName)
-            Modifier.initiallyFocused()
-          else
-            Modifier.restorableFocus()
-        ) {
-          Text(
-            text = tab,
-            fontSize = 12.sp,
-            modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
-          )
+    val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
+
+    TabRow(
+        selectedTabIndex = selectedTabIndex,
+        modifier = Modifier
+            .then(focusRestorerModifiers.parentModifier)
+    ) {
+        tabs.forEachIndexed { index, tab ->
+            key(index) {
+                Tab(
+                    selected = index == selectedTabIndex,
+                    onFocus = { updateSelectedTab(index) },
+                    modifier = Modifier
+                        .ifElse(index == 0, focusRestorerModifiers.childModifier)
+                ) {
+                    Text(
+                        text = tab,
+                        fontSize = 12.sp,
+                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
+                    )
+                }
+            }
         }
-      }
     }
-  }
 }
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/createCustomInitialFocusRestorerModifiers.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/createCustomInitialFocusRestorerModifiers.kt
new file mode 100644
index 0000000..3f3acbf
--- /dev/null
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/createCustomInitialFocusRestorerModifiers.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.tv.integration.playground
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusProperties
+import androidx.compose.ui.focus.focusRequester
+
+/**
+ * Assign the parentModifier to the container of items and assign the childModifier to the
+ * item that needs to first gain focus. For example, if you want the item at index 0 to get
+ * focus for the first time, you can do the following:
+ *
+ * LazyRow(modifier.then(modifiers.parentModifier) {
+ *   item1(modifier.then(modifiers.childModifier) {...}
+ *   item2 {...}
+ *   item3 {...}
+ *   ...
+ * }
+ */
+data class FocusRequesterModifiers(
+    val parentModifier: Modifier,
+    val childModifier: Modifier
+)
+
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun createCustomInitialFocusRestorerModifiers(): FocusRequesterModifiers {
+    val focusRequester = remember { FocusRequester() }
+    val childFocusRequester = remember { FocusRequester() }
+
+    val parentModifier = Modifier
+        .focusRequester(focusRequester)
+        .focusProperties {
+            exit = {
+                focusRequester.saveFocusedChild()
+                FocusRequester.Default
+            }
+            enter = {
+                if (!focusRequester.restoreFocusedChild())
+                    childFocusRequester
+                else
+                    FocusRequester.Cancel
+            }
+        }
+
+    val childModifier = Modifier.focusRequester(childFocusRequester)
+
+    return FocusRequesterModifiers(parentModifier, childModifier)
+}
diff --git a/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ifElse.kt b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ifElse.kt
new file mode 100644
index 0000000..eaeee61
--- /dev/null
+++ b/tv/integration-tests/playground/src/main/java/androidx/tv/integration/playground/ifElse.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.tv.integration.playground
+
+import androidx.compose.ui.Modifier
+
+/**
+ * Thanks, Plex 🦄 :)
+ */
+fun Modifier.ifElse(
+    condition: () -> Boolean,
+    ifTrueModifier: Modifier,
+    ifFalseModifier: Modifier = Modifier
+): Modifier = then(if (condition()) ifTrueModifier else ifFalseModifier)
+
+fun Modifier.ifElse(
+    condition: Boolean,
+    ifTrueModifier: Modifier,
+    ifFalseModifier: Modifier = Modifier
+): Modifier = ifElse({ condition }, ifTrueModifier, ifFalseModifier)
\ No newline at end of file
diff --git a/tv/integration-tests/presentation/build.gradle b/tv/integration-tests/presentation/build.gradle
index 142f5a0..5a9de93 100644
--- a/tv/integration-tests/presentation/build.gradle
+++ b/tv/integration-tests/presentation/build.gradle
@@ -39,6 +39,14 @@
 
     implementation(project(":tv:tv-foundation"))
     implementation(project(":tv:tv-material"))
+
+    // pull latest compose (if build fails in future, just comment the following compose deps until
+    // we fix this package)
+    implementation(project(":compose:animation:animation"))
+    implementation(project(":compose:runtime:runtime"))
+    implementation(project(":compose:ui:ui"))
+    implementation(project(":compose:foundation:foundation-layout"))
+    implementation(project(":compose:ui:ui"))
 }
 
 androidx {
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppLazyRow.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppLazyRow.kt
index 455dc59..07834cd 100644
--- a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppLazyRow.kt
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppLazyRow.kt
@@ -43,6 +43,8 @@
     val paddingLeft = 58.dp
     var hasFocus by remember { mutableStateOf(false) }
 
+    val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
+
     Column(modifier = modifier.onFocusChanged { hasFocus = it.hasFocus }) {
         Text(
             text = title,
@@ -55,7 +57,8 @@
 
         TvLazyRow(
             contentPadding = PaddingValues(horizontal = paddingLeft),
-            horizontalArrangement = Arrangement.spacedBy(20.dp)
+            horizontalArrangement = Arrangement.spacedBy(20.dp),
+            modifier = focusRestorerModifiers.parentModifier,
         ) {
             items.forEachIndexed { index, movie ->
                 item {
@@ -63,6 +66,7 @@
                         movie = movie,
                         index = index,
                         modifier = Modifier
+                            .ifElse(index == 0, focusRestorerModifiers.childModifier)
                     )
                 }
             }
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppTabRow.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppTabRow.kt
index b1a566e..a571a11 100644
--- a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppTabRow.kt
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/AppTabRow.kt
@@ -20,6 +20,7 @@
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.key
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
@@ -38,12 +39,15 @@
     onSelectedTabIndexChange: (Int) -> Unit,
     modifier: Modifier = Modifier
 ) {
+    val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
+
     AlignmentCenter(horizontalAxis = true) {
-        FocusGroup {
-            TabRow(
-                selectedTabIndex = selectedTabIndex,
-                separator = { Spacer(modifier = Modifier.width(4.dp)) },
-                modifier = modifier.padding(top = 20.dp),
+        TabRow(
+            selectedTabIndex = selectedTabIndex,
+            separator = { Spacer(modifier = Modifier.width(4.dp)) },
+            modifier = modifier
+                .padding(top = 20.dp)
+                .then(focusRestorerModifiers.parentModifier),
 //                indicator = @Composable { tabPositions ->
 //                    tabPositions.getOrNull(selectedTabIndex)?.let {
 //                        TabRowDefaults.PillIndicator(
@@ -52,12 +56,9 @@
 //                        )
 //                    }
 //                }
-            ) {
-                tabs.forEachIndexed { index, tabLabel ->
-                    val tabModifier = Modifier.restorableFocus()
-                    val firstTabModifier = Modifier.initiallyFocused()
-                    val isFirstTab = index == 0
-
+        ) {
+            tabs.forEachIndexed { index, tabLabel ->
+                key(index) {
                     Tab(
                         selected = selectedTabIndex == index,
                         onFocus = { onSelectedTabIndexChange(index) },
@@ -65,7 +66,8 @@
                             contentColor = LocalContentColor.current,
 //                            selectedContentColor = Color(0xFF313033),
                         ),
-                        modifier = if (isFirstTab) firstTabModifier else tabModifier
+                        modifier = Modifier
+                            .ifElse(index == 0, focusRestorerModifiers.childModifier),
                     ) {
                         Text(
                             text = tabLabel,
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/FocusGroup.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/FocusGroup.kt
deleted file mode 100644
index 928dcf9..0000000
--- a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/FocusGroup.kt
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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.tv.integration.presentation
-
-import android.annotation.SuppressLint
-import android.util.Log
-import androidx.compose.foundation.focusable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
-import androidx.compose.runtime.currentCompositeKeyHash
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberUpdatedState
-import androidx.compose.runtime.saveable.rememberSaveable
-import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusDirection
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.platform.LocalFocusManager
-
-/**
- * Composable container that provides modifier extensions to allow focus to be restored to the
- * element that was previously focused within the TvFocusGroup.
- *
- * @param modifier the modifier to apply to this group.
- * @param content the content that is present within the group and can use focus-group modifier
- * extensions.
- */
-@OptIn(ExperimentalComposeUiApi::class)
-@Composable
-fun FocusGroup(
-    modifier: Modifier = Modifier,
-    content: @Composable FocusGroupScope.() -> Unit
-) {
-    val focusManager = LocalFocusManager.current
-    val focusGroupKeyHash = currentCompositeKeyHash
-
-    // TODO: Is this the intended way to call rememberSaveable
-    //  with key set to parentHash?
-    val previousFocusedItemHash: MutableState<Int?> = rememberSaveable(
-        key = focusGroupKeyHash.toString()
-    ) {
-        mutableStateOf(null)
-    }
-
-    val state = FocusGroupState(previousFocusedItemHash = previousFocusedItemHash)
-
-    Box(
-        modifier = modifier
-            .onFocusChanged {
-                if (it.isFocused) {
-                    if (state.noRecordedState()) {
-                        focusManager.moveFocus(FocusDirection.Enter)
-                    } else {
-                        if (state.focusRequester != FocusRequester.Default) {
-                            try {
-                                state.focusRequester.requestFocus()
-                            } catch (e: Exception) {
-                                Log.w("TvFocusGroup", "TvFocusGroup: Failed to request focus", e)
-                            }
-                        } else {
-                            focusManager.moveFocus(FocusDirection.Enter)
-                        }
-                    }
-                }
-            }
-            .focusable(),
-        content = { FocusGroupScope(state).content() }
-    )
-}
-
-/**
- * Scope containing the modifier extensions to be used within [FocusGroup].
- */
-class FocusGroupScope internal constructor(private val state: FocusGroupState) {
-    private var currentFocusableIdIndex = 0
-
-    private fun generateUniqueFocusableId(): Int = currentFocusableIdIndex++
-
-    /**
-     * Modifier that records if the item was in focus before it moved out of the group. When focus
-     * enters the [FocusGroup], the item will be returned focus.
-     */
-    @SuppressLint("ComposableModifierFactory")
-    @Composable
-    fun Modifier.restorableFocus(): Modifier =
-        this.restorableFocus(focusId = rememberSaveable { generateUniqueFocusableId() })
-
-    /**
-     * Modifier that marks the current composable as the item to gain focus initially when focus
-     * enters the [FocusGroup]. When focus enters the [FocusGroup], the item will be returned focus.
-     */
-    @SuppressLint("ComposableModifierFactory")
-    @Composable
-    fun Modifier.initiallyFocused(): Modifier {
-        val focusId = rememberSaveable { generateUniqueFocusableId() }
-        if (state.noRecordedState()) {
-            state.recordFocusedItemHash(focusId)
-        }
-        return this.restorableFocus(focusId)
-    }
-
-    @SuppressLint("ComposableModifierFactory")
-    @OptIn(ExperimentalComposeUiApi::class)
-    @Composable
-    private fun Modifier.restorableFocus(focusId: Int): Modifier {
-        val focusRequester = remember { FocusRequester() }
-        var isFocused = remember { false }
-        val isCurrentlyFocused by rememberUpdatedState(isFocused)
-        val focusManager = LocalFocusManager.current
-        state.associatedWith(focusId, focusRequester)
-        DisposableEffect(Unit) {
-            onDispose {
-                state.clearDisposedFocusRequester(focusId)
-                if (isCurrentlyFocused) {
-                    focusManager.moveFocus(FocusDirection.Exit)
-                    focusManager.moveFocus(FocusDirection.Enter)
-                }
-            }
-        }
-
-        return this
-            .focusRequester(focusRequester)
-            .onFocusChanged {
-                isFocused = it.isFocused || it.hasFocus
-                if (isFocused) {
-                    state.recordFocusedItemHash(focusId)
-                    state.associatedWith(focusId, focusRequester)
-                }
-            }
-    }
-}
-
-@Stable
-internal class FocusGroupState(
-    private var previousFocusedItemHash: MutableState<Int?>
-) {
-    internal var focusRequester: FocusRequester = FocusRequester.Default
-        private set
-
-    internal fun recordFocusedItemHash(itemHash: Int) {
-        previousFocusedItemHash.value = itemHash
-    }
-
-    internal fun clearDisposedFocusRequester(itemHash: Int) {
-        if (previousFocusedItemHash.value == itemHash) {
-            focusRequester = FocusRequester.Default
-        }
-    }
-
-    internal fun associatedWith(itemHash: Int, focusRequester: FocusRequester) {
-        if (previousFocusedItemHash.value == itemHash) {
-            this.focusRequester = focusRequester
-        }
-    }
-
-    internal fun noRecordedState(): Boolean =
-        previousFocusedItemHash.value == null && focusRequester == FocusRequester.Default
-}
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ShowsGrid.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ShowsGrid.kt
index c9f982d..eecb500 100644
--- a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ShowsGrid.kt
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ShowsGrid.kt
@@ -24,7 +24,6 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
-import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.OutlinedTextField
 import androidx.compose.material3.OutlinedTextFieldDefaults
 import androidx.compose.runtime.Composable
@@ -40,7 +39,6 @@
 import androidx.tv.foundation.lazy.grid.TvLazyHorizontalGrid
 import androidx.tv.material3.Text
 
-@OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun ShowsGrid(modifier: Modifier = Modifier) {
     var keyword by remember { mutableStateOf("") }
@@ -88,28 +86,27 @@
             }
         }
 
-        FocusGroup {
-            TvLazyHorizontalGrid(
-                rows = TvGridCells.Fixed(3),
-                contentPadding = PaddingValues(horizontal = 58.dp),
-                verticalArrangement = Arrangement.spacedBy(10.dp),
-                modifier = Modifier
-                    .fillMaxSize()
-                    .bringIntoViewIfChildrenAreFocused(),
-            ) {
-                items(movies.size) {
-                    val movie = movies[it]
-                    val isFirstItem = it == 0
-                    val itemModifier = Modifier.restorableFocus()
-                    val firstItemModifier = Modifier.initiallyFocused()
+        val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
 
-                    Box(modifier = Modifier.padding(end = 30.dp)) {
-                        ImageCard(
-                            movie,
-                            customCardWidth = 150.dp,
-                            modifier = if (isFirstItem) firstItemModifier else itemModifier
-                        )
-                    }
+        TvLazyHorizontalGrid(
+            rows = TvGridCells.Fixed(3),
+            contentPadding = PaddingValues(horizontal = 58.dp),
+            verticalArrangement = Arrangement.spacedBy(10.dp),
+            modifier = Modifier
+                .fillMaxSize()
+                .bringIntoViewIfChildrenAreFocused()
+                .then(focusRestorerModifiers.parentModifier),
+        ) {
+            items(movies.size) {
+                val movie = movies[it]
+
+                Box(modifier = Modifier.padding(end = 30.dp)) {
+                    ImageCard(
+                        movie,
+                        customCardWidth = 150.dp,
+                        modifier = Modifier
+                            .ifElse(it == 0, focusRestorerModifiers.childModifier),
+                    )
                 }
             }
         }
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/Sidebar.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/Sidebar.kt
index 882b27b..562a149 100644
--- a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/Sidebar.kt
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/Sidebar.kt
@@ -16,8 +16,9 @@
 
 package androidx.tv.integration.presentation
 
+import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.background
-import androidx.compose.foundation.focusable
+import androidx.compose.foundation.focusGroup
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -33,6 +34,7 @@
 import androidx.compose.material3.IconButtonDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
@@ -47,7 +49,7 @@
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.Icon
 
-@OptIn(ExperimentalTvMaterial3Api::class)
+@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalFoundationApi::class)
 @Composable
 fun Sidebar(
     selectedIndex: Int,
@@ -101,30 +103,37 @@
             }
         }
 
-    FocusGroup {
-        Column(
-            modifier = Modifier
-                .width(60.dp)
-                .fillMaxHeight()
-                .background(pageColor)
-                .focusable(false),
-            horizontalAlignment = Alignment.CenterHorizontally,
-            verticalArrangement = Arrangement.Center,
-        ) {
+    val focusRestorerModifiers = createCustomInitialFocusRestorerModifiers()
+
+    Column(
+        modifier = Modifier
+            .width(60.dp)
+            .fillMaxHeight()
+            .background(pageColor)
+            .then(focusRestorerModifiers.parentModifier)
+            .focusGroup(),
+        horizontalAlignment = Alignment.CenterHorizontally,
+        verticalArrangement = Arrangement.Center,
+    ) {
+        key(0) {
             drawIcon(
                 imageVector = Icons.Outlined.Home,
                 index = 0,
-                modifier = Modifier.initiallyFocused(),
+                modifier = focusRestorerModifiers.childModifier,
             )
+        }
+        key(1) {
             drawIcon(
                 imageVector = Icons.Outlined.Movie,
                 index = 1,
-                modifier = Modifier.restorableFocus(),
+                modifier = Modifier,
             )
+        }
+        key(2) {
             drawIcon(
                 imageVector = Icons.Outlined.Tv,
                 index = 2,
-                modifier = Modifier.restorableFocus(),
+                modifier = Modifier,
             )
         }
     }
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/createCustomInitialFocusRestorerModifiers.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/createCustomInitialFocusRestorerModifiers.kt
new file mode 100644
index 0000000..6b00a52
--- /dev/null
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/createCustomInitialFocusRestorerModifiers.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.tv.integration.presentation
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusProperties
+import androidx.compose.ui.focus.focusRequester
+
+/**
+ * Assign the parentModifier to the container of items and assign the childModifier to the
+ * item that needs to first gain focus. For example, if you want the item at index 0 to get
+ * focus for the first time, you can do the following:
+ *
+ * LazyRow(modifier.then(modifiers.parentModifier) {
+ *   item1(modifier.then(modifiers.childModifier) {...}
+ *   item2 {...}
+ *   item3 {...}
+ *   ...
+ * }
+ */
+data class FocusRequesterModifiers(
+    val parentModifier: Modifier,
+    val childModifier: Modifier
+)
+
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun createCustomInitialFocusRestorerModifiers(): FocusRequesterModifiers {
+    val focusRequester = remember { FocusRequester() }
+    val childFocusRequester = remember { FocusRequester() }
+
+    val parentModifier = Modifier
+        .focusRequester(focusRequester)
+        .focusProperties {
+            exit = {
+                focusRequester.saveFocusedChild()
+                FocusRequester.Default
+            }
+            enter = {
+                if (!focusRequester.restoreFocusedChild())
+                    childFocusRequester
+                else
+                    FocusRequester.Cancel
+            }
+        }
+
+    val childModifier = Modifier.focusRequester(childFocusRequester)
+
+    return FocusRequesterModifiers(parentModifier, childModifier)
+}
diff --git a/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ifElse.kt b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ifElse.kt
new file mode 100644
index 0000000..4a29855
--- /dev/null
+++ b/tv/integration-tests/presentation/src/main/java/androidx/tv/integration/presentation/ifElse.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.tv.integration.presentation
+
+import androidx.compose.ui.Modifier
+
+/**
+ * Thanks, Plex 🦄 :)
+ */
+fun Modifier.ifElse(
+    condition: () -> Boolean,
+    ifTrueModifier: Modifier,
+    ifFalseModifier: Modifier = Modifier
+): Modifier = then(if (condition()) ifTrueModifier else ifFalseModifier)
+
+fun Modifier.ifElse(
+    condition: Boolean,
+    ifTrueModifier: Modifier,
+    ifFalseModifier: Modifier = Modifier
+): Modifier = ifElse({ condition }, ifTrueModifier, ifFalseModifier)
\ No newline at end of file
diff --git a/tv/samples/src/main/java/androidx/tv/samples/TabRowSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/TabRowSamples.kt
index b9d11bd..96c9535 100644
--- a/tv/samples/src/main/java/androidx/tv/samples/TabRowSamples.kt
+++ b/tv/samples/src/main/java/androidx/tv/samples/TabRowSamples.kt
@@ -26,10 +26,13 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.key
 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.focus.focusRestorer
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
@@ -45,7 +48,7 @@
 /**
  * Tab row with a Pill indicator
  */
-@OptIn(ExperimentalTvMaterial3Api::class)
+@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
 @Composable
 @Sampled
 fun PillIndicatorTabRow() {
@@ -55,17 +58,20 @@
   TabRow(
     selectedTabIndex = selectedTabIndex,
     separator = { Spacer(modifier = Modifier.width(12.dp)) },
+    modifier = Modifier.focusRestorer()
   ) {
     tabs.forEachIndexed { index, tab ->
-      Tab(
-        selected = index == selectedTabIndex,
-        onFocus = { selectedTabIndex = index },
-      ) {
-        Text(
-          text = tab,
-          fontSize = 12.sp,
-          modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
-        )
+      key(index) {
+        Tab(
+          selected = index == selectedTabIndex,
+          onFocus = { selectedTabIndex = index },
+        ) {
+          Text(
+            text = tab,
+            fontSize = 12.sp,
+            modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
+          )
+        }
       }
     }
   }
@@ -74,7 +80,7 @@
 /**
  * Tab row with an Underlined indicator
  */
-@OptIn(ExperimentalTvMaterial3Api::class)
+@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
 @Composable
 @Sampled
 fun UnderlinedIndicatorTabRow() {
@@ -88,19 +94,22 @@
       TabRowDefaults.UnderlinedIndicator(
         currentTabPosition = tabPositions[selectedTabIndex]
       )
-    }
+    },
+    modifier = Modifier.focusRestorer()
   ) {
     tabs.forEachIndexed { index, tab ->
-      Tab(
-        selected = index == selectedTabIndex,
-        onFocus = { selectedTabIndex = index },
-        colors = TabDefaults.underlinedIndicatorTabColors(),
-      ) {
-        Text(
-          text = tab,
-          fontSize = 12.sp,
-          modifier = Modifier.padding(bottom = 4.dp)
-        )
+      key(index) {
+        Tab(
+          selected = index == selectedTabIndex,
+          onFocus = { selectedTabIndex = index },
+          colors = TabDefaults.underlinedIndicatorTabColors(),
+        ) {
+          Text(
+            text = tab,
+            fontSize = 12.sp,
+            modifier = Modifier.padding(bottom = 4.dp)
+          )
+        }
       }
     }
   }
@@ -109,7 +118,7 @@
 /**
  * Tab row with delay between tab changes
  */
-@OptIn(ExperimentalTvMaterial3Api::class)
+@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
 @Composable
 @Sampled
 fun TabRowWithDebounce() {
@@ -128,17 +137,20 @@
   TabRow(
     selectedTabIndex = selectedTabIndex,
     separator = { Spacer(modifier = Modifier.width(12.dp)) },
+    modifier = Modifier.focusRestorer()
   ) {
     tabs.forEachIndexed { index, tab ->
-      Tab(
-        selected = index == selectedTabIndex,
-        onFocus = { selectedTabIndex = index },
-      ) {
-        Text(
-          text = tab,
-          fontSize = 12.sp,
-          modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
-        )
+      key(index) {
+        Tab(
+          selected = index == selectedTabIndex,
+          onFocus = { selectedTabIndex = index },
+        ) {
+          Text(
+            text = tab,
+            fontSize = 12.sp,
+            modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
+          )
+        }
       }
     }
   }
@@ -147,7 +159,7 @@
 /**
  * Tab changes onClick instead of onFocus
  */
-@OptIn(ExperimentalTvMaterial3Api::class)
+@OptIn(ExperimentalTvMaterial3Api::class, ExperimentalComposeUiApi::class)
 @Composable
 @Sampled
 fun OnClickNavigation() {
@@ -180,22 +192,25 @@
         TabRowDefaults.PillIndicator(
           currentTabPosition = tabPositions[activeTabIndex]
         )
-      }
+      },
+      modifier = Modifier.focusRestorer()
     ) {
       repeat(bgColors.size) {
-        Tab(
-          selected = activeTabIndex == it,
-          onFocus = { focusedTabIndex = it },
-          onClick = {
-            focusedTabIndex = it
-            activeTabIndex = it
+        key(it) {
+          Tab(
+            selected = activeTabIndex == it,
+            onFocus = { focusedTabIndex = it },
+            onClick = {
+              focusedTabIndex = it
+              activeTabIndex = it
+            }
+          ) {
+            Text(
+              text = "Tab ${it + 1}",
+              fontSize = 12.sp,
+              modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
+            )
           }
-        ) {
-          Text(
-            text = "Tab ${it + 1}",
-            fontSize = 12.sp,
-            modifier = Modifier.padding(horizontal = 16.dp, vertical = 6.dp)
-          )
         }
       }
     }
diff --git a/tv/tv-foundation/lint-baseline.xml b/tv/tv-foundation/lint-baseline.xml
index b094f99..1347079 100644
--- a/tv/tv-foundation/lint-baseline.xml
+++ b/tv/tv-foundation/lint-baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
 
     <issue
         id="BanThreadSleep"
@@ -37,4 +37,382 @@
             file="src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyScrollTest.kt"/>
     </issue>
 
+    <issue
+        id="ExceptionMessage"
+        message="Please specify a lazyMessage param for requireNotNull"
+        errorLine1="                            val keyFactory = requireNotNull(it.value.key)"
+        errorLine2="                                             ~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;contentType&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        contentType: (index: Int) -> Any? = { null },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super TvLazyListItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable TvLazyListItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;lineOf&apos; with type Function1&lt;? super Integer, ? extends Integer>."
+        errorLine1="        val lineOf: (Int) -> Int = {"
+        errorLine2="                    ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridAnimateScrollScope.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method item has parameter &apos;span&apos; with type Function1&lt;? super TvLazyGridItemSpanScope, TvGridItemSpan>."
+        errorLine1="        span: (TvLazyGridItemSpanScope.() -> TvGridItemSpan)? = null,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super Integer, TvGridItemSpan>."
+        errorLine1="        span: (TvLazyGridItemSpanScope.(index: Int) -> TvGridItemSpan)? = null,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;contentType&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        contentType: (index: Int) -> Any? = { null },"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super TvLazyGridItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable TvLazyGridItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super T, TvGridItemSpan>."
+        errorLine1="    noinline span: (TvLazyGridItemSpanScope.(item: T) -> TvGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function3&lt;? super TvLazyGridItemSpanScope, ? super Integer, ? super T, TvGridItemSpan>."
+        errorLine1="    noinline span: (TvLazyGridItemSpanScope.(index: Int, item: T) -> TvGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;span&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super T, TvGridItemSpan>."
+        errorLine1="    noinline span: (TvLazyGridItemSpanScope.(item: T) -> TvGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;span&apos; with type Function3&lt;? super TvLazyGridItemSpanScope, ? super Integer, ? super T, TvGridItemSpan>."
+        errorLine1="    noinline span: (TvLazyGridItemSpanScope.(index: Int, item: T) -> TvGridItemSpan)? = null,"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method measureLazyGrid has parameter &apos;layout&apos; with type Function3&lt;? super Integer, ? super Integer, ? super Function1&lt;? super PlacementScope, Unit>, ? extends MeasureResult>."
+        errorLine1="    layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/LazyGridMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor NearestRangeKeyIndexMapState has parameter &apos;firstVisibleItemIndex&apos; with type Function0&lt;Integer>."
+        errorLine1="    firstVisibleItemIndex: () -> Int,"
+        errorLine2="                           ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor NearestRangeKeyIndexMapState has parameter &apos;slidingWindowSize&apos; with type Function0&lt;Integer>."
+        errorLine1="    slidingWindowSize: () -> Int,"
+        errorLine2="                       ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor NearestRangeKeyIndexMapState has parameter &apos;extraItemCount&apos; with type Function0&lt;Integer>."
+        errorLine1="    extraItemCount: () -> Int,"
+        errorLine2="                    ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;keyFactory&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="                            val keyFactory = requireNotNull(it.value.key)"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;indexForKeyMapping&apos; with type Function1&lt;? super Object, ? extends Integer>."
+        errorLine1="            val indexForKeyMapping: (Any) -> Int = { needle ->"
+        errorLine2="                                    ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollByAction&apos; with type Function2&lt;? super Float, ? super Float, ? extends Boolean>."
+        errorLine1="            val scrollByAction: ((x: Float, y: Float) -> Boolean)? = if (userScrollEnabled) {"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollToIndexAction&apos; with type Function1&lt;? super Integer, ? extends Boolean>."
+        errorLine1="            val scrollToIndexAction: ((Int) -> Boolean)? = if (userScrollEnabled) {"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method measureLazyList has parameter &apos;layout&apos; with type Function3&lt;? super Integer, ? super Integer, ? super Function1&lt;? super PlacementScope, Unit>, ? extends MeasureResult>."
+        errorLine1="    layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/LazyListMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;var9cfa9825&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super Integer, ? extends TvGridItemSpan>."
+        errorLine1="                span = span?.let { { span() } } ?: DefaultSpan,"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;varcb3b0c51&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super Integer, ? extends TvGridItemSpan>."
+        errorLine1="                span = span ?: DefaultSpan,"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;TvLazyGridItemSpanScope, Integer, TvGridItemSpan> of &apos;getDefaultSpan&apos;."
+        errorLine1="        val DefaultSpan: TvLazyGridItemSpanScope.(Int) -> TvGridItemSpan = { TvGridItemSpan(1) }"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((index: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;span&apos; with type Function2&lt;? super TvLazyGridItemSpanScope, ? super Integer, TvGridItemSpan>."
+        errorLine1="    val span: TvLazyGridItemSpanScope.(Int) -> TvGridItemSpan,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;TvLazyGridItemSpanScope, Integer, TvGridItemSpan> of &apos;getSpan&apos;."
+        errorLine1="    val span: TvLazyGridItemSpanScope.(Int) -> TvGridItemSpan,"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;type&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val type: ((index: Int) -> Any?),"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor LazyGridInterval has parameter &apos;item&apos; with type Function2&lt;? super TvLazyGridItemScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable TvLazyGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;TvLazyGridItemScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable TvLazyGridItemScope.(Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setPrefetchInfoRetriever$lint_module has parameter &apos;&lt;set-?>&apos; with type Function1&lt;? super LineIndex, ? extends List&lt;Pair&lt;Integer, Constraints>>>."
+        errorLine1="    /**"
+        errorLine2="    ^">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;LineIndex, List&lt;Pair&lt;Integer, Constraints>>> of &apos;getPrefetchInfoRetriever$lint_module&apos;."
+        errorLine1="    internal var prefetchInfoRetriever: (line: LineIndex) -> List&lt;Pair&lt;Int, Constraints>> by"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor TvLazyListInterval has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val key: ((index: Int) -> Any)?,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor TvLazyListInterval has parameter &apos;type&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    override val type: ((index: Int) -> Any?),"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor TvLazyListInterval has parameter &apos;item&apos; with type Function2&lt;? super TvLazyListItemScope, ? super Integer, Unit>."
+        errorLine1="    val item: @Composable TvLazyListItemScope.(index: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;TvLazyListItemScope, Integer, Unit> of &apos;getItem&apos;."
+        errorLine1="    val item: @Composable TvLazyListItemScope.(index: Int) -> Unit"
+        errorLine2="              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt"/>
+    </issue>
+
 </issues>
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridAnimateScrollScope.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
index 170b00d..a96a483 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridAnimateScrollScope.kt
@@ -77,7 +77,6 @@
         visibleItems: List<TvLazyGridItemInfo>,
         isVertical: Boolean
     ): Int {
-        @Suppress("PrimitiveInLambda")
         val lineOf: (Int) -> Int = {
             if (isVertical) visibleItems[it].row else visibleItems[it].column
         }
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt
index 97b3af4..b197ea3 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridDsl.kt
@@ -316,7 +316,6 @@
      */
     fun item(
         key: Any? = null,
-        @Suppress("PrimitiveInLambda")
         span: (TvLazyGridItemSpanScope.() -> TvGridItemSpan)? = null,
         contentType: Any? = null,
         content: @Composable TvLazyGridItemScope.() -> Unit
@@ -342,13 +341,9 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         span: (TvLazyGridItemSpanScope.(index: Int) -> TvGridItemSpan)? = null,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any? = { null },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable TvLazyGridItemScope.(index: Int) -> Unit
     )
 }
@@ -374,7 +369,6 @@
 inline fun <T> TvLazyGridScope.items(
     items: List<T>,
     noinline key: ((item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (TvLazyGridItemSpanScope.(item: T) -> TvGridItemSpan)? = null,
     noinline contentType: (item: T) -> Any? = { null },
     crossinline itemContent: @Composable TvLazyGridItemScope.(item: T) -> Unit
@@ -407,9 +401,7 @@
  */
 inline fun <T> TvLazyGridScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (TvLazyGridItemSpanScope.(index: Int, item: T) -> TvGridItemSpan)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable TvLazyGridItemScope.(index: Int, item: T) -> Unit
@@ -443,7 +435,6 @@
 inline fun <T> TvLazyGridScope.items(
     items: Array<T>,
     noinline key: ((item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (TvLazyGridItemSpanScope.(item: T) -> TvGridItemSpan)? = null,
     noinline contentType: (item: T) -> Any? = { null },
     crossinline itemContent: @Composable TvLazyGridItemScope.(item: T) -> Unit
@@ -476,9 +467,7 @@
  */
 inline fun <T> TvLazyGridScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     noinline span: (TvLazyGridItemSpanScope.(index: Int, item: T) -> TvGridItemSpan)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable TvLazyGridItemScope.(index: Int, item: T) -> Unit
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridMeasure.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridMeasure.kt
index 837f940..d3863fd 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridMeasure.kt
@@ -62,7 +62,6 @@
     placementAnimator: LazyGridItemPlacementAnimator,
     spanLayoutProvider: LazyGridSpanLayoutProvider,
     pinnedItems: LazyLayoutPinnedItemList,
-    @Suppress("PrimitiveInLambda")
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): TvLazyGridMeasureResult {
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt
index 37af2f5..fb5c3d4 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridScopeImpl.kt
@@ -36,10 +36,8 @@
         apply(content)
     }
 
-    @Suppress("PrimitiveInLambda")
     override fun item(
         key: Any?,
-        @Suppress("PrimitiveInLambda")
         span: (TvLazyGridItemSpanScope.() -> TvGridItemSpan)?,
         contentType: Any?,
         content: @Composable TvLazyGridItemScope.() -> Unit
@@ -63,7 +61,6 @@
         contentType: (index: Int) -> Any?,
         itemContent: @Composable TvLazyGridItemScope.(index: Int) -> Unit
     ) {
-        @Suppress("PrimitiveInLambda")
         intervals.addInterval(
             count,
             LazyGridInterval(
@@ -77,19 +74,14 @@
     }
 
     private companion object {
-        @Suppress("PrimitiveInLambda")
         val DefaultSpan: TvLazyGridItemSpanScope.(Int) -> TvGridItemSpan = { TvGridItemSpan(1) }
     }
 }
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class LazyGridInterval(
-    @Suppress("PrimitiveInLambda")
     override val key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     val span: TvLazyGridItemSpanScope.(Int) -> TvGridItemSpan,
-    @Suppress("PrimitiveInLambda")
     override val type: ((index: Int) -> Any?),
-    @Suppress("PrimitiveInLambda")
     val item: @Composable TvLazyGridItemScope.(Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
\ No newline at end of file
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
index 09aede3..037afba 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
@@ -208,7 +208,6 @@
     /**
      * Finds items on a line and their measurement constraints. Used for prefetching.
      */
-    @Suppress("PrimitiveInLambda")
     internal var prefetchInfoRetriever: (line: LineIndex) -> List<Pair<Int, Constraints>> by
     mutableStateOf({ emptyList() })
 
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
index 2300956..b46e090 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
@@ -63,11 +63,8 @@
 @Suppress("IllegalExperimentalApiUsage") // TODO (b/233188423): Address before moving to beta
 @ExperimentalFoundationApi
 internal class NearestRangeKeyIndexMapState(
-    @Suppress("PrimitiveInLambda")
     firstVisibleItemIndex: () -> Int,
-    @Suppress("PrimitiveInLambda")
     slidingWindowSize: () -> Int,
-    @Suppress("PrimitiveInLambda")
     extraItemCount: () -> Int,
     content: () -> LazyLayoutIntervalContent<*>
 ) : State<LazyLayoutKeyIndexMap> {
@@ -124,7 +121,6 @@
                         toIndex = last,
                     ) {
                         if (it.value.key != null) {
-                            @Suppress("PrimitiveInLambda", "ExceptionMessage")
                             val keyFactory = requireNotNull(it.value.key)
                             val start = maxOf(first, it.startIndex)
                             val end = minOf(last, it.startIndex + it.size - 1)
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt
index e499b8b..5058a26 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/layout/LazyLayoutSemantics.kt
@@ -53,7 +53,6 @@
             userScrollEnabled
         ) {
             val isVertical = orientation == Orientation.Vertical
-            @Suppress("PrimitiveInLambda")
             val indexForKeyMapping: (Any) -> Int = { needle ->
                 var result = -1
                 for (index in 0 until itemProvider.itemCount) {
@@ -86,7 +85,6 @@
                 reverseScrolling = reverseScrolling
             )
 
-            @Suppress("PrimitiveInLambda")
             val scrollByAction: ((x: Float, y: Float) -> Boolean)? = if (userScrollEnabled) {
                 { x, y ->
                     val delta = if (isVertical) {
@@ -104,7 +102,6 @@
                 null
             }
 
-            @Suppress("PrimitiveInLambda")
             val scrollToIndexAction: ((Int) -> Boolean)? = if (userScrollEnabled) {
                 { index ->
                     require(index >= 0 && index < itemProvider.itemCount) {
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt
index 5cea73e..e7949fe 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyDsl.kt
@@ -71,11 +71,8 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any? = { null },
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable TvLazyListItemScope.(index: Int) -> Unit
     )
 
@@ -147,7 +144,6 @@
  */
 inline fun <T> TvLazyListScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable TvLazyListItemScope.(index: Int, item: T) -> Unit
@@ -204,7 +200,6 @@
  */
 inline fun <T> TvLazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },
     crossinline itemContent: @Composable TvLazyListItemScope.(index: Int, item: T) -> Unit
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListMeasure.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListMeasure.kt
index fec6f61..07c4b07 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListMeasure.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListMeasure.kt
@@ -63,7 +63,6 @@
     beyondBoundsInfo: LazyListBeyondBoundsInfo,
     beyondBoundsItemCount: Int,
     pinnedItems: LazyLayoutPinnedItemList,
-    @Suppress("PrimitiveInLambda")
     layout: (Int, Int, Placeable.PlacementScope.() -> Unit) -> MeasureResult
 ): LazyListMeasureResult {
     require(beforeContentPadding >= 0) { "negative beforeContentPadding" }
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt
index 0e32290..01ef422 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/TvLazyListIntervalContent.kt
@@ -38,11 +38,8 @@
 
     override fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)?,
-        @Suppress("PrimitiveInLambda")
         contentType: (index: Int) -> Any?,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable TvLazyListItemScope.(index: Int) -> Unit
     ) {
         intervals.addInterval(
@@ -87,10 +84,7 @@
 
 @OptIn(ExperimentalFoundationApi::class)
 internal class TvLazyListInterval(
-    @Suppress("PrimitiveInLambda")
     override val key: ((index: Int) -> Any)?,
-    @Suppress("PrimitiveInLambda")
     override val type: ((index: Int) -> Any?),
-    @Suppress("PrimitiveInLambda")
     val item: @Composable TvLazyListItemScope.(index: Int) -> Unit
 ) : LazyLayoutIntervalContent.Interval
diff --git a/tv/tv-material/lint-baseline.xml b/tv/tv-material/lint-baseline.xml
new file mode 100644
index 0000000..8818459
--- /dev/null
+++ b/tv/tv-material/lint-baseline.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Carousel has parameter &apos;content&apos; with type Function2&lt;? super AnimatedContentScope, ? super Integer, Unit>."
+        errorLine1="    content: @Composable AnimatedContentScope.(index: Int) -> Unit"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/material3/Carousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;scrollByAction&apos; with type Function2&lt;? super Float, ? super Float, ? extends Boolean>."
+        errorLine1="            val scrollByAction: ((x: Float, y: Float) -> Boolean) ="
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/material3/Carousel.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ImmersiveList has parameter &apos;background&apos; with type Function3&lt;? super ImmersiveListBackgroundScope, ? super Integer, ? super Boolean, Unit>."
+        errorLine1="    @Composable ImmersiveListBackgroundScope.(index: Int, listHasFocus: Boolean) -> Unit,"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/material3/ImmersiveList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method AnimatedContent has parameter &apos;content&apos; with type Function2&lt;? super AnimatedVisibilityScope, ? super Integer, Unit>."
+        errorLine1="        content: @Composable AnimatedVisibilityScope.(targetState: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/material3/ImmersiveList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor ImmersiveListScope has parameter &apos;onFocused&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="public class ImmersiveListScope internal constructor(private val onFocused: (Int) -> Unit) {"
+        errorLine2="                                                                            ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/tv/material3/ImmersiveList.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;valueToOffset&apos; with type Function1&lt;? super Boolean, ? extends Float>."
+        errorLine1="    val valueToOffset = remember&lt;(Boolean) -> Float>(minBound, maxBound) {"
+        errorLine2="    ^">
+        <location
+            file="src/main/java/androidx/tv/material3/Switch.kt"/>
+    </issue>
+
+</issues>
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
index b9f537e..e811d70 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
@@ -121,7 +121,6 @@
                 .padding(16.dp),
         )
     },
-    @Suppress("PrimitiveInLambda")
     content: @Composable AnimatedContentScope.(index: Int) -> Unit
 ) {
     CarouselStateUpdater(carouselState, itemCount)
@@ -533,7 +532,6 @@
                 reverseScrolling = false
             )
 
-            @Suppress("PrimitiveInLambda")
             val scrollByAction: ((x: Float, y: Float) -> Boolean) =
                 { x, _ ->
                     when {
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt b/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
index bf22529..e10af5a 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
@@ -61,7 +61,6 @@
 @ExperimentalTvMaterial3Api
 @Composable
 fun ImmersiveList(
-    @Suppress("PrimitiveInLambda")
     background:
     @Composable ImmersiveListBackgroundScope.(index: Int, listHasFocus: Boolean) -> Unit,
     modifier: Modifier = Modifier,
@@ -167,7 +166,6 @@
             ImmersiveListDefaults.EnterTransition.togetherWith(ImmersiveListDefaults.ExitTransition)
         },
         contentAlignment: Alignment = Alignment.TopStart,
-        @Suppress("PrimitiveInLambda")
         content: @Composable AnimatedVisibilityScope.(targetState: Int) -> Unit
     ) {
         androidx.compose.animation.AnimatedContent(
@@ -182,10 +180,7 @@
 
 @Immutable
 @ExperimentalTvMaterial3Api
-public class ImmersiveListScope internal constructor(
-    @Suppress("PrimitiveInLambda")
-    private val onFocused: (Int) -> Unit
-) {
+public class ImmersiveListScope internal constructor(private val onFocused: (Int) -> Unit) {
     /**
      * Modifier to be added to each of the items of the list within ImmersiveList to inform the
      * ImmersiveList of the index of the item in focus
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
index 39e9a9d..61d51b2 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
@@ -103,7 +103,6 @@
     val thumbPaddingStart = (SwitchHeight - uncheckedThumbDiameter) / 2
     val minBound = with(LocalDensity.current) { thumbPaddingStart.toPx() }
     val maxBound = with(LocalDensity.current) { ThumbPathLength.toPx() }
-    @Suppress("PrimitiveInLambda")
     val valueToOffset = remember<(Boolean) -> Float>(minBound, maxBound) {
         { value -> if (value) maxBound else minBound }
     }
diff --git a/viewpager/viewpager/api/api_lint.ignore b/viewpager/viewpager/api/api_lint.ignore
index 1c07b48..908ecb2 100644
--- a/viewpager/viewpager/api/api_lint.ignore
+++ b/viewpager/viewpager/api/api_lint.ignore
@@ -9,18 +9,12 @@
     Symmetric method for `setDrawFullUnderline` must be named `isDrawFullUnderline`; was `getDrawFullUnderline`
 
 
-InvalidNullabilityOverride: androidx.viewpager.widget.PagerTabStrip#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.viewpager.widget.ViewPager#draw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `draw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-InvalidNullabilityOverride: androidx.viewpager.widget.ViewPager#onDraw(android.graphics.Canvas) parameter #0:
-    Invalid nullability on parameter `canvas` in method `onDraw`. Parameters of overrides cannot be NonNull if the super parameter is unannotated.
-
-
 ListenerInterface: androidx.viewpager.widget.ViewPager.SimpleOnPageChangeListener:
     Listeners should be an interface, or otherwise renamed Callback: SimpleOnPageChangeListener
 
 
+MissingNullability: androidx.viewpager.widget.PagerTabStrip#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.viewpager.widget.PagerTabStrip#onTouchEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `ev` in method `onTouchEvent`
 MissingNullability: androidx.viewpager.widget.PagerTabStrip#setBackgroundDrawable(android.graphics.drawable.Drawable) parameter #0:
@@ -39,6 +33,8 @@
     Missing nullability on parameter `event` in method `dispatchKeyEvent`
 MissingNullability: androidx.viewpager.widget.ViewPager#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent) parameter #0:
     Missing nullability on parameter `event` in method `dispatchPopulateAccessibilityEvent`
+MissingNullability: androidx.viewpager.widget.ViewPager#draw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `draw`
 MissingNullability: androidx.viewpager.widget.ViewPager#generateDefaultLayoutParams():
     Missing nullability on method `generateDefaultLayoutParams` return
 MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.util.AttributeSet):
@@ -49,6 +45,8 @@
     Missing nullability on method `generateLayoutParams` return
 MissingNullability: androidx.viewpager.widget.ViewPager#generateLayoutParams(android.view.ViewGroup.LayoutParams) parameter #0:
     Missing nullability on parameter `p` in method `generateLayoutParams`
+MissingNullability: androidx.viewpager.widget.ViewPager#onDraw(android.graphics.Canvas) parameter #0:
+    Missing nullability on parameter `canvas` in method `onDraw`
 MissingNullability: androidx.viewpager.widget.ViewPager#onInterceptTouchEvent(android.view.MotionEvent) parameter #0:
     Missing nullability on parameter `ev` in method `onInterceptTouchEvent`
 MissingNullability: androidx.viewpager.widget.ViewPager#onRequestFocusInDescendants(int, android.graphics.Rect) parameter #1:
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/TestActivity.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/TestActivity.kt
index 7d31f03..a4f665f 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/TestActivity.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/TestActivity.kt
@@ -32,6 +32,7 @@
         onCreateCallback(this)
 
         // disable enter animation.
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
@@ -39,6 +40,7 @@
         super.finish()
 
         // disable exit animation
+        @Suppress("Deprecation")
         overridePendingTransition(0, 0)
     }
 
diff --git a/wear/compose/compose-foundation/api/1.2.0-beta01.txt b/wear/compose/compose-foundation/api/1.2.0-beta01.txt
index 03d2707..91d6749 100644
--- a/wear/compose/compose-foundation/api/1.2.0-beta01.txt
+++ b/wear/compose/compose-foundation/api/1.2.0-beta01.txt
@@ -26,11 +26,6 @@
     method public static void basicCurvedText(androidx.wear.compose.foundation.CurvedScope, String text, androidx.wear.compose.foundation.CurvedTextStyle style, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedDirection.Angular? angularDirection, optional int overflow);
   }
 
-  public final class CompositionLocalsKt {
-    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> getLocalReduceMotion();
-    property @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> LocalReduceMotion;
-  }
-
   public interface CurvedAlignment {
   }
 
@@ -200,61 +195,6 @@
     property public final boolean expanded;
   }
 
-  @kotlin.RequiresOptIn(message="This Wear Foundation API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalWearFoundationApi {
-  }
-
-  public final class HierarchicalFocusCoordinatorKt {
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void HierarchicalFocusCoordinator(kotlin.jvm.functions.Function0<java.lang.Boolean> requiresFocus, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void OnFocusChange(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Boolean,kotlin.Unit> onFocusChanged);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void RequestFocusWhenActive(androidx.compose.ui.focus.FocusRequester focusRequester);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.ui.focus.FocusRequester rememberActiveFocusRequester();
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public fun interface ReduceMotion {
-    method @androidx.compose.runtime.Composable public boolean enabled();
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public interface RevealScope {
-    method public float getRevealOffset();
-    property public abstract float revealOffset;
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public final class RevealState {
-    method public suspend Object? animateTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public int getCurrentValue();
-    method public float getOffset();
-    method public java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> getSwipeAnchors();
-    method public int getTargetValue();
-    method public boolean isAnimationRunning();
-    method public suspend Object? snapTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final int currentValue;
-    property public final boolean isAnimationRunning;
-    property public final float offset;
-    property public final java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> swipeAnchors;
-    property public final int targetValue;
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi @kotlin.jvm.JvmInline public final value class RevealValue {
-    method public int getValue();
-    property public final int value;
-    field public static final androidx.wear.compose.foundation.RevealValue.Companion Companion;
-  }
-
-  public static final class RevealValue.Companion {
-    method public int getCovered();
-    method public int getRevealed();
-    method public int getRevealing();
-    property public final int Covered;
-    property public final int Revealed;
-    property public final int Revealing;
-  }
-
-  public final class SwipeToRevealKt {
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void SwipeToReveal(kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit> action, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> onFullSwipe, optional androidx.wear.compose.foundation.RevealState state, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? additionalAction, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? undoAction, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> createAnchors(optional float coveredAnchor, optional float revealingAnchor, optional float revealedAnchor);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.wear.compose.foundation.RevealState rememberRevealState(optional int initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold, optional java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> anchors);
-  }
-
 }
 
 package androidx.wear.compose.foundation.lazy {
diff --git a/wear/compose/compose-foundation/api/public_plus_experimental_1.2.0-beta01.txt b/wear/compose/compose-foundation/api/public_plus_experimental_1.2.0-beta01.txt
new file mode 100644
index 0000000..03d2707
--- /dev/null
+++ b/wear/compose/compose-foundation/api/public_plus_experimental_1.2.0-beta01.txt
@@ -0,0 +1,398 @@
+// Signature format: 4.0
+package androidx.wear.compose.foundation {
+
+  @kotlin.jvm.JvmInline public final value class AnchorType {
+    field public static final androidx.wear.compose.foundation.AnchorType.Companion Companion;
+  }
+
+  public static final class AnchorType.Companion {
+    method public float getCenter();
+    method public float getEnd();
+    method public float getStart();
+    property public final float Center;
+    property public final float End;
+    property public final float Start;
+  }
+
+  @androidx.compose.runtime.Stable public interface ArcPaddingValues {
+    method public float calculateAfterPadding(androidx.compose.ui.unit.LayoutDirection layoutDirection, int angularDirection);
+    method public float calculateBeforePadding(androidx.compose.ui.unit.LayoutDirection layoutDirection, int angularDirection);
+    method public float calculateInnerPadding(int radialDirection);
+    method public float calculateOuterPadding(int radialDirection);
+  }
+
+  public final class BasicCurvedTextKt {
+    method public static void basicCurvedText(androidx.wear.compose.foundation.CurvedScope, String text, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedDirection.Angular? angularDirection, optional int overflow, optional kotlin.jvm.functions.Function0<androidx.wear.compose.foundation.CurvedTextStyle> style);
+    method public static void basicCurvedText(androidx.wear.compose.foundation.CurvedScope, String text, androidx.wear.compose.foundation.CurvedTextStyle style, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedDirection.Angular? angularDirection, optional int overflow);
+  }
+
+  public final class CompositionLocalsKt {
+    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> getLocalReduceMotion();
+    property @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> LocalReduceMotion;
+  }
+
+  public interface CurvedAlignment {
+  }
+
+  @kotlin.jvm.JvmInline public static final value class CurvedAlignment.Angular {
+    field public static final androidx.wear.compose.foundation.CurvedAlignment.Angular.Companion Companion;
+  }
+
+  public static final class CurvedAlignment.Angular.Companion {
+    method public float Custom(float ratio);
+    method public float getCenter();
+    method public float getEnd();
+    method public float getStart();
+    property public final float Center;
+    property public final float End;
+    property public final float Start;
+  }
+
+  @kotlin.jvm.JvmInline public static final value class CurvedAlignment.Radial {
+    field public static final androidx.wear.compose.foundation.CurvedAlignment.Radial.Companion Companion;
+  }
+
+  public static final class CurvedAlignment.Radial.Companion {
+    method public float Custom(float ratio);
+    method public float getCenter();
+    method public float getInner();
+    method public float getOuter();
+    property public final float Center;
+    property public final float Inner;
+    property public final float Outer;
+  }
+
+  public final class CurvedBoxKt {
+    method public static void curvedBox(androidx.wear.compose.foundation.CurvedScope, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedAlignment.Radial? radialAlignment, optional androidx.wear.compose.foundation.CurvedAlignment.Angular? angularAlignment, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.CurvedScope,kotlin.Unit> contentBuilder);
+  }
+
+  public final class CurvedColumnKt {
+    method public static void curvedColumn(androidx.wear.compose.foundation.CurvedScope, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedDirection.Radial? radialDirection, optional androidx.wear.compose.foundation.CurvedAlignment.Angular? angularAlignment, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.CurvedScope,kotlin.Unit> contentBuilder);
+  }
+
+  public final class CurvedComposableKt {
+    method public static void curvedComposable(androidx.wear.compose.foundation.CurvedScope, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional float radialAlignment, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
+  public interface CurvedDirection {
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public static final value class CurvedDirection.Angular {
+    field public static final androidx.wear.compose.foundation.CurvedDirection.Angular.Companion Companion;
+  }
+
+  public static final class CurvedDirection.Angular.Companion {
+    method public int getClockwise();
+    method public int getCounterClockwise();
+    method public int getNormal();
+    method public int getReversed();
+    property public final int Clockwise;
+    property public final int CounterClockwise;
+    property public final int Normal;
+    property public final int Reversed;
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public static final value class CurvedDirection.Radial {
+    field public static final androidx.wear.compose.foundation.CurvedDirection.Radial.Companion Companion;
+  }
+
+  public static final class CurvedDirection.Radial.Companion {
+    method public int getInsideOut();
+    method public int getOutsideIn();
+    property public final int InsideOut;
+    property public final int OutsideIn;
+  }
+
+  public final class CurvedDrawKt {
+    method public static androidx.wear.compose.foundation.CurvedModifier angularGradientBackground(androidx.wear.compose.foundation.CurvedModifier, java.util.List<androidx.compose.ui.graphics.Color> colors, optional int cap);
+    method public static androidx.wear.compose.foundation.CurvedModifier angularGradientBackground(androidx.wear.compose.foundation.CurvedModifier, kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional int cap);
+    method public static androidx.wear.compose.foundation.CurvedModifier background(androidx.wear.compose.foundation.CurvedModifier, long color, optional int cap);
+    method public static androidx.wear.compose.foundation.CurvedModifier radialGradientBackground(androidx.wear.compose.foundation.CurvedModifier, java.util.List<androidx.compose.ui.graphics.Color> colors, optional int cap);
+    method public static androidx.wear.compose.foundation.CurvedModifier radialGradientBackground(androidx.wear.compose.foundation.CurvedModifier, kotlin.Pair<java.lang.Float,androidx.compose.ui.graphics.Color>![] colorStops, optional int cap);
+  }
+
+  public final class CurvedLayoutKt {
+    method @androidx.compose.runtime.Composable public static void CurvedLayout(optional androidx.compose.ui.Modifier modifier, optional float anchor, optional float anchorType, optional androidx.wear.compose.foundation.CurvedAlignment.Radial? radialAlignment, optional int angularDirection, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.CurvedScope,kotlin.Unit> contentBuilder);
+  }
+
+  @androidx.compose.runtime.Stable @kotlin.jvm.JvmDefaultWithCompatibility public sealed interface CurvedModifier {
+    method public default infix androidx.wear.compose.foundation.CurvedModifier then(androidx.wear.compose.foundation.CurvedModifier other);
+    field public static final androidx.wear.compose.foundation.CurvedModifier.Companion Companion;
+  }
+
+  public static final class CurvedModifier.Companion implements androidx.wear.compose.foundation.CurvedModifier {
+  }
+
+  public final class CurvedPaddingKt {
+    method public static androidx.wear.compose.foundation.ArcPaddingValues ArcPaddingValues(float all);
+    method public static androidx.wear.compose.foundation.ArcPaddingValues ArcPaddingValues(optional float radial, optional float angular);
+    method public static androidx.wear.compose.foundation.ArcPaddingValues ArcPaddingValues(optional float outer, optional float inner, optional float before, optional float after);
+    method public static androidx.wear.compose.foundation.CurvedModifier padding(androidx.wear.compose.foundation.CurvedModifier, androidx.wear.compose.foundation.ArcPaddingValues paddingValues);
+    method public static androidx.wear.compose.foundation.CurvedModifier padding(androidx.wear.compose.foundation.CurvedModifier, optional float all);
+    method public static androidx.wear.compose.foundation.CurvedModifier padding(androidx.wear.compose.foundation.CurvedModifier, optional float radial, optional float angular);
+    method public static androidx.wear.compose.foundation.CurvedModifier padding(androidx.wear.compose.foundation.CurvedModifier, float outer, float inner, float before, float after);
+  }
+
+  public final class CurvedParentDataKt {
+    method public static androidx.wear.compose.foundation.CurvedModifier parentDataModifier(androidx.wear.compose.foundation.CurvedModifier, kotlin.jvm.functions.Function1<java.lang.Object,?> modifyParentData);
+    method public static androidx.wear.compose.foundation.CurvedModifier weight(androidx.wear.compose.foundation.CurvedModifier, float weight);
+  }
+
+  public final class CurvedRowKt {
+    method public static void curvedRow(androidx.wear.compose.foundation.CurvedScope, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedAlignment.Radial? radialAlignment, optional androidx.wear.compose.foundation.CurvedDirection.Angular? angularDirection, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.CurvedScope,kotlin.Unit> contentBuilder);
+  }
+
+  @androidx.compose.foundation.layout.LayoutScopeMarker public final class CurvedScope {
+  }
+
+  public final class CurvedSizeKt {
+    method public static androidx.wear.compose.foundation.CurvedModifier angularSize(androidx.wear.compose.foundation.CurvedModifier, float sweepDegrees);
+    method public static androidx.wear.compose.foundation.CurvedModifier angularSizeDp(androidx.wear.compose.foundation.CurvedModifier, float angularWidth);
+    method public static androidx.wear.compose.foundation.CurvedModifier radialSize(androidx.wear.compose.foundation.CurvedModifier, float thickness);
+    method public static androidx.wear.compose.foundation.CurvedModifier size(androidx.wear.compose.foundation.CurvedModifier, float sweepDegrees, float thickness);
+    method public static androidx.wear.compose.foundation.CurvedModifier sizeIn(androidx.wear.compose.foundation.CurvedModifier, optional float minSweepDegrees, optional float maxSweepDegrees, optional float minThickness, optional float maxThickness);
+  }
+
+  public final class CurvedTextStyle {
+    ctor public CurvedTextStyle(androidx.compose.ui.text.TextStyle style);
+    ctor @Deprecated public CurvedTextStyle(optional long background, optional long color, optional long fontSize);
+    ctor public CurvedTextStyle(optional long background, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis);
+    method @Deprecated public androidx.wear.compose.foundation.CurvedTextStyle copy(optional long background, optional long color, optional long fontSize);
+    method public androidx.wear.compose.foundation.CurvedTextStyle copy(optional long background, optional long color, optional long fontSize, optional androidx.compose.ui.text.font.FontFamily? fontFamily, optional androidx.compose.ui.text.font.FontWeight? fontWeight, optional androidx.compose.ui.text.font.FontStyle? fontStyle, optional androidx.compose.ui.text.font.FontSynthesis? fontSynthesis);
+    method public long getBackground();
+    method public long getColor();
+    method public androidx.compose.ui.text.font.FontFamily? getFontFamily();
+    method public long getFontSize();
+    method public androidx.compose.ui.text.font.FontStyle? getFontStyle();
+    method public androidx.compose.ui.text.font.FontSynthesis? getFontSynthesis();
+    method public androidx.compose.ui.text.font.FontWeight? getFontWeight();
+    method public androidx.wear.compose.foundation.CurvedTextStyle merge(optional androidx.wear.compose.foundation.CurvedTextStyle? other);
+    method public operator androidx.wear.compose.foundation.CurvedTextStyle plus(androidx.wear.compose.foundation.CurvedTextStyle other);
+    property public final long background;
+    property public final long color;
+    property public final androidx.compose.ui.text.font.FontFamily? fontFamily;
+    property public final long fontSize;
+    property public final androidx.compose.ui.text.font.FontStyle? fontStyle;
+    property public final androidx.compose.ui.text.font.FontSynthesis? fontSynthesis;
+    property public final androidx.compose.ui.text.font.FontWeight? fontWeight;
+  }
+
+  public final class ExpandableItemsDefaults {
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float> getCollapseAnimationSpec();
+    method public androidx.compose.animation.core.AnimationSpec<java.lang.Float> getExpandAnimationSpec();
+    property public final androidx.compose.animation.core.AnimationSpec<java.lang.Float> collapseAnimationSpec;
+    property public final androidx.compose.animation.core.AnimationSpec<java.lang.Float> expandAnimationSpec;
+    field public static final androidx.wear.compose.foundation.ExpandableItemsDefaults INSTANCE;
+  }
+
+  public final class ExpandableKt {
+    method public static void expandableButton(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, androidx.wear.compose.foundation.ExpandableState state, optional Object? key, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method public static void expandableItem(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, androidx.wear.compose.foundation.ExpandableState state, optional Object? key, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> content);
+    method public static void expandableItems(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, androidx.wear.compose.foundation.ExpandableState state, int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.layout.BoxScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+    method @androidx.compose.runtime.Composable public static androidx.wear.compose.foundation.ExpandableState rememberExpandableState(optional boolean initiallyExpanded, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> expandAnimationSpec, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> collapseAnimationSpec);
+  }
+
+  public final class ExpandableState {
+    method public float getExpandProgress();
+    method public boolean isExpanded();
+    method public void setExpanded(boolean);
+    property public final float expandProgress;
+    property public final boolean expanded;
+  }
+
+  @kotlin.RequiresOptIn(message="This Wear Foundation API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalWearFoundationApi {
+  }
+
+  public final class HierarchicalFocusCoordinatorKt {
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void HierarchicalFocusCoordinator(kotlin.jvm.functions.Function0<java.lang.Boolean> requiresFocus, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void OnFocusChange(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Boolean,kotlin.Unit> onFocusChanged);
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void RequestFocusWhenActive(androidx.compose.ui.focus.FocusRequester focusRequester);
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.ui.focus.FocusRequester rememberActiveFocusRequester();
+  }
+
+  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public fun interface ReduceMotion {
+    method @androidx.compose.runtime.Composable public boolean enabled();
+  }
+
+  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public interface RevealScope {
+    method public float getRevealOffset();
+    property public abstract float revealOffset;
+  }
+
+  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public final class RevealState {
+    method public suspend Object? animateTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public int getCurrentValue();
+    method public float getOffset();
+    method public java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> getSwipeAnchors();
+    method public int getTargetValue();
+    method public boolean isAnimationRunning();
+    method public suspend Object? snapTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public final int currentValue;
+    property public final boolean isAnimationRunning;
+    property public final float offset;
+    property public final java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> swipeAnchors;
+    property public final int targetValue;
+  }
+
+  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi @kotlin.jvm.JvmInline public final value class RevealValue {
+    method public int getValue();
+    property public final int value;
+    field public static final androidx.wear.compose.foundation.RevealValue.Companion Companion;
+  }
+
+  public static final class RevealValue.Companion {
+    method public int getCovered();
+    method public int getRevealed();
+    method public int getRevealing();
+    property public final int Covered;
+    property public final int Revealed;
+    property public final int Revealing;
+  }
+
+  public final class SwipeToRevealKt {
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void SwipeToReveal(kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit> action, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> onFullSwipe, optional androidx.wear.compose.foundation.RevealState state, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? additionalAction, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? undoAction, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> createAnchors(optional float coveredAnchor, optional float revealingAnchor, optional float revealedAnchor);
+    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.wear.compose.foundation.RevealState rememberRevealState(optional int initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold, optional java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> anchors);
+  }
+
+}
+
+package androidx.wear.compose.foundation.lazy {
+
+  @androidx.compose.runtime.Immutable public final class AutoCenteringParams {
+    ctor public AutoCenteringParams(optional int itemIndex, optional int itemOffset);
+  }
+
+  public final class ScalingLazyColumnDefaults {
+    method public androidx.wear.compose.foundation.lazy.ScalingParams scalingParams(optional float edgeScale, optional float edgeAlpha, optional float minElementHeight, optional float maxElementHeight, optional float minTransitionArea, optional float maxTransitionArea, optional androidx.compose.animation.core.Easing scaleInterpolator, optional kotlin.jvm.functions.Function1<? super androidx.compose.ui.unit.Constraints,java.lang.Integer> viewportVerticalOffsetResolver);
+    method @androidx.compose.runtime.Composable public androidx.compose.foundation.gestures.FlingBehavior snapFlingBehavior(androidx.wear.compose.foundation.lazy.ScalingLazyListState state, optional float snapOffset, optional androidx.compose.animation.core.DecayAnimationSpec<java.lang.Float> decay);
+    field public static final androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults INSTANCE;
+  }
+
+  public final class ScalingLazyColumnKt {
+    method @androidx.compose.runtime.Composable public static void ScalingLazyColumn(optional androidx.compose.ui.Modifier modifier, optional androidx.wear.compose.foundation.lazy.ScalingLazyListState state, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional boolean reverseLayout, optional androidx.compose.foundation.layout.Arrangement.Vertical verticalArrangement, optional androidx.compose.ui.Alignment.Horizontal horizontalAlignment, optional androidx.compose.foundation.gestures.FlingBehavior flingBehavior, optional boolean userScrollEnabled, optional androidx.wear.compose.foundation.lazy.ScalingParams scalingParams, optional int anchorType, optional androidx.wear.compose.foundation.lazy.AutoCenteringParams? autoCentering, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.lazy.ScalingLazyListScope,kotlin.Unit> content);
+    method public static inline <T> void items(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function1<? super T,?>? key, kotlin.jvm.functions.Function2<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void items(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, T![] items, optional kotlin.jvm.functions.Function1<? super T,?>? key, kotlin.jvm.functions.Function2<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, java.util.List<? extends T> items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, kotlin.jvm.functions.Function3<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+    method public static inline <T> void itemsIndexed(androidx.wear.compose.foundation.lazy.ScalingLazyListScope, T![] items, optional kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,?>? key, kotlin.jvm.functions.Function3<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,? super java.lang.Integer,? super T,kotlin.Unit> itemContent);
+  }
+
+  @androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class ScalingLazyListAnchorType {
+    field public static final androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType.Companion Companion;
+  }
+
+  public static final class ScalingLazyListAnchorType.Companion {
+    method public int getItemCenter();
+    method public int getItemStart();
+    property public final int ItemCenter;
+    property public final int ItemStart;
+  }
+
+  public sealed interface ScalingLazyListItemInfo {
+    method public float getAlpha();
+    method public int getIndex();
+    method public Object getKey();
+    method public int getOffset();
+    method public float getScale();
+    method public int getSize();
+    method public int getUnadjustedOffset();
+    method public int getUnadjustedSize();
+    property public abstract float alpha;
+    property public abstract int index;
+    property public abstract Object key;
+    property public abstract int offset;
+    property public abstract float scale;
+    property public abstract int size;
+    property public abstract int unadjustedOffset;
+    property public abstract int unadjustedSize;
+  }
+
+  @androidx.compose.runtime.Stable @androidx.wear.compose.foundation.lazy.ScalingLazyScopeMarker public sealed interface ScalingLazyListItemScope {
+    method public androidx.compose.ui.Modifier fillParentMaxHeight(androidx.compose.ui.Modifier, optional float fraction);
+    method public androidx.compose.ui.Modifier fillParentMaxSize(androidx.compose.ui.Modifier, optional float fraction);
+    method public androidx.compose.ui.Modifier fillParentMaxWidth(androidx.compose.ui.Modifier, optional float fraction);
+  }
+
+  public sealed interface ScalingLazyListLayoutInfo {
+    method public int getAfterAutoCenteringPadding();
+    method public int getAfterContentPadding();
+    method public int getAnchorType();
+    method public int getBeforeAutoCenteringPadding();
+    method public int getBeforeContentPadding();
+    method public androidx.compose.foundation.gestures.Orientation getOrientation();
+    method public boolean getReverseLayout();
+    method public int getTotalItemsCount();
+    method public int getViewportEndOffset();
+    method public long getViewportSize();
+    method public int getViewportStartOffset();
+    method public java.util.List<androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo> getVisibleItemsInfo();
+    property public abstract int afterAutoCenteringPadding;
+    property public abstract int afterContentPadding;
+    property public abstract int anchorType;
+    property public abstract int beforeAutoCenteringPadding;
+    property public abstract int beforeContentPadding;
+    property public abstract androidx.compose.foundation.gestures.Orientation orientation;
+    property public abstract boolean reverseLayout;
+    property public abstract int totalItemsCount;
+    property public abstract int viewportEndOffset;
+    property public abstract long viewportSize;
+    property public abstract int viewportStartOffset;
+    property public abstract java.util.List<androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo> visibleItemsInfo;
+  }
+
+  @androidx.wear.compose.foundation.lazy.ScalingLazyScopeMarker public sealed interface ScalingLazyListScope {
+    method public void item(optional Object? key, kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,kotlin.Unit> content);
+    method public void items(int count, optional kotlin.jvm.functions.Function1<? super java.lang.Integer,?>? key, kotlin.jvm.functions.Function2<? super androidx.wear.compose.foundation.lazy.ScalingLazyListItemScope,? super java.lang.Integer,kotlin.Unit> itemContent);
+  }
+
+  @androidx.compose.runtime.Stable public final class ScalingLazyListState implements androidx.compose.foundation.gestures.ScrollableState {
+    ctor public ScalingLazyListState(optional int initialCenterItemIndex, optional int initialCenterItemScrollOffset);
+    method public suspend Object? animateScrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public float dispatchRawDelta(float delta);
+    method public int getCenterItemIndex();
+    method public int getCenterItemScrollOffset();
+    method public androidx.wear.compose.foundation.lazy.ScalingLazyListLayoutInfo getLayoutInfo();
+    method public boolean isScrollInProgress();
+    method public suspend Object? scroll(androidx.compose.foundation.MutatePriority scrollPriority, kotlin.jvm.functions.Function2<? super androidx.compose.foundation.gestures.ScrollScope,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block, kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    method public suspend Object? scrollToItem(int index, optional int scrollOffset, optional kotlin.coroutines.Continuation<? super kotlin.Unit>);
+    property public boolean canScrollBackward;
+    property public boolean canScrollForward;
+    property public final int centerItemIndex;
+    property public final int centerItemScrollOffset;
+    property public boolean isScrollInProgress;
+    property public final androidx.wear.compose.foundation.lazy.ScalingLazyListLayoutInfo layoutInfo;
+    field public static final androidx.wear.compose.foundation.lazy.ScalingLazyListState.Companion Companion;
+  }
+
+  public static final class ScalingLazyListState.Companion {
+    method public androidx.compose.runtime.saveable.Saver<androidx.wear.compose.foundation.lazy.ScalingLazyListState,java.lang.Object> getSaver();
+    property public final androidx.compose.runtime.saveable.Saver<androidx.wear.compose.foundation.lazy.ScalingLazyListState,java.lang.Object> Saver;
+  }
+
+  public final class ScalingLazyListStateKt {
+    method @androidx.compose.runtime.Composable public static androidx.wear.compose.foundation.lazy.ScalingLazyListState rememberScalingLazyListState(optional int initialCenterItemIndex, optional int initialCenterItemScrollOffset);
+  }
+
+  @kotlin.DslMarker public @interface ScalingLazyScopeMarker {
+  }
+
+  @androidx.compose.runtime.Stable public interface ScalingParams {
+    method public float getEdgeAlpha();
+    method public float getEdgeScale();
+    method public float getMaxElementHeight();
+    method public float getMaxTransitionArea();
+    method public float getMinElementHeight();
+    method public float getMinTransitionArea();
+    method public androidx.compose.animation.core.Easing getScaleInterpolator();
+    method public int resolveViewportVerticalOffset(long viewportConstraints);
+    property public abstract float edgeAlpha;
+    property public abstract float edgeScale;
+    property public abstract float maxElementHeight;
+    property public abstract float maxTransitionArea;
+    property public abstract float minElementHeight;
+    property public abstract float minTransitionArea;
+    property public abstract androidx.compose.animation.core.Easing scaleInterpolator;
+  }
+
+}
+
diff --git a/wear/compose/compose-foundation/api/restricted_1.2.0-beta01.txt b/wear/compose/compose-foundation/api/restricted_1.2.0-beta01.txt
index 03d2707..91d6749 100644
--- a/wear/compose/compose-foundation/api/restricted_1.2.0-beta01.txt
+++ b/wear/compose/compose-foundation/api/restricted_1.2.0-beta01.txt
@@ -26,11 +26,6 @@
     method public static void basicCurvedText(androidx.wear.compose.foundation.CurvedScope, String text, androidx.wear.compose.foundation.CurvedTextStyle style, optional androidx.wear.compose.foundation.CurvedModifier modifier, optional androidx.wear.compose.foundation.CurvedDirection.Angular? angularDirection, optional int overflow);
   }
 
-  public final class CompositionLocalsKt {
-    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> getLocalReduceMotion();
-    property @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.wear.compose.foundation.ReduceMotion> LocalReduceMotion;
-  }
-
   public interface CurvedAlignment {
   }
 
@@ -200,61 +195,6 @@
     property public final boolean expanded;
   }
 
-  @kotlin.RequiresOptIn(message="This Wear Foundation API is experimental and is likely to change or to be removed in" + " the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalWearFoundationApi {
-  }
-
-  public final class HierarchicalFocusCoordinatorKt {
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void HierarchicalFocusCoordinator(kotlin.jvm.functions.Function0<java.lang.Boolean> requiresFocus, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void OnFocusChange(kotlin.jvm.functions.Function2<? super kotlinx.coroutines.CoroutineScope,? super java.lang.Boolean,kotlin.Unit> onFocusChanged);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void RequestFocusWhenActive(androidx.compose.ui.focus.FocusRequester focusRequester);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.compose.ui.focus.FocusRequester rememberActiveFocusRequester();
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public fun interface ReduceMotion {
-    method @androidx.compose.runtime.Composable public boolean enabled();
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public interface RevealScope {
-    method public float getRevealOffset();
-    property public abstract float revealOffset;
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public final class RevealState {
-    method public suspend Object? animateTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    method public int getCurrentValue();
-    method public float getOffset();
-    method public java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> getSwipeAnchors();
-    method public int getTargetValue();
-    method public boolean isAnimationRunning();
-    method public suspend Object? snapTo(int targetValue, kotlin.coroutines.Continuation<? super kotlin.Unit>);
-    property public final int currentValue;
-    property public final boolean isAnimationRunning;
-    property public final float offset;
-    property public final java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> swipeAnchors;
-    property public final int targetValue;
-  }
-
-  @androidx.wear.compose.foundation.ExperimentalWearFoundationApi @kotlin.jvm.JvmInline public final value class RevealValue {
-    method public int getValue();
-    property public final int value;
-    field public static final androidx.wear.compose.foundation.RevealValue.Companion Companion;
-  }
-
-  public static final class RevealValue.Companion {
-    method public int getCovered();
-    method public int getRevealed();
-    method public int getRevealing();
-    property public final int Covered;
-    property public final int Revealed;
-    property public final int Revealing;
-  }
-
-  public final class SwipeToRevealKt {
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static void SwipeToReveal(kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit> action, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit> onFullSwipe, optional androidx.wear.compose.foundation.RevealState state, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? additionalAction, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealScope,kotlin.Unit>? undoAction, kotlin.jvm.functions.Function0<kotlin.Unit> content);
-    method @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> createAnchors(optional float coveredAnchor, optional float revealingAnchor, optional float revealedAnchor);
-    method @androidx.compose.runtime.Composable @androidx.wear.compose.foundation.ExperimentalWearFoundationApi public static androidx.wear.compose.foundation.RevealState rememberRevealState(optional int initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.wear.compose.foundation.RevealValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function2<? super androidx.compose.ui.unit.Density,? super java.lang.Float,java.lang.Float> positionalThreshold, optional java.util.Map<androidx.wear.compose.foundation.RevealValue,java.lang.Float> anchors);
-  }
-
 }
 
 package androidx.wear.compose.foundation.lazy {
diff --git a/wear/compose/compose-foundation/build.gradle b/wear/compose/compose-foundation/build.gradle
index c00ea3b..749bb3c 100644
--- a/wear/compose/compose-foundation/build.gradle
+++ b/wear/compose/compose-foundation/build.gradle
@@ -33,7 +33,7 @@
     implementation(libs.kotlinStdlib)
     implementation(project(":compose:foundation:foundation-layout"))
     implementation(project(":compose:ui:ui-util"))
-    implementation(project(":core:core"))
+    implementation("androidx.core:core:1.11.0-beta02")
     implementation("androidx.profileinstaller:profileinstaller:1.3.0")
 
     testImplementation(libs.testRules)
diff --git a/wear/compose/compose-foundation/lint-baseline.xml b/wear/compose/compose-foundation/lint-baseline.xml
new file mode 100644
index 0000000..0ce8821
--- /dev/null
+++ b/wear/compose/compose-foundation/lint-baseline.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method sumOf has parameter &apos;selector&apos; with type Function1&lt;? super T, Float>."
+        errorLine1="internal fun &lt;T> Iterable&lt;T>.sumOf(selector: (T) -> Float): Float = map(selector).sum()"
+        errorLine2="                                             ~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/CurvedLayout.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method expandableItems has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="    key: ((index: Int) -> Any)? = null,"
+        errorLine2="         ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/Expandable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method expandableItems has parameter &apos;itemContent&apos; with type Function2&lt;? super BoxScope, ? super Integer, Unit>."
+        errorLine1="    itemContent: @Composable BoxScope.(index: Int) -> Unit"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/Expandable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super ScalingLazyListItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable ScalingLazyListItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method scalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="        viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 20f).toInt() }"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method autoCenteringHeight has parameter &apos;getHeight&apos; with type Function0&lt;Integer>."
+        errorLine1="private fun Modifier.autoCenteringHeight(getHeight: () -> Int) ="
+        errorLine2="                                                    ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DefaultScalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="    val viewportVerticalOffsetResolver: (Constraints) -> Int,"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Constraints, Integer> of &apos;getViewportVerticalOffsetResolver&apos;."
+        errorLine1="    val viewportVerticalOffsetResolver: (Constraints) -> Int,"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor RevealState has parameter &apos;confirmValueChange&apos; with type Function1&lt;? super RevealValue, Boolean>."
+        errorLine1="    confirmValueChange: (RevealValue) -> Boolean,"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor RevealState has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    positionalThreshold: Density.(totalDistance: Float) -> Float,"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberRevealState has parameter &apos;confirmValueChange&apos; with type Function1&lt;? super RevealValue, Boolean>."
+        errorLine1="    confirmValueChange: (RevealValue) -> Boolean = { true },"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rememberRevealState has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;defaultThreshold$lint_module&apos;."
+        errorLine1="    internal fun defaultThreshold() = fractionalPositionalThreshold(threshold)"
+        errorLine2="                 ~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method swipeAnchors has parameter &apos;calculateAnchor&apos; with type Function2&lt;? super T, ? super IntSize, Float>."
+        errorLine1="    calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor SwipeableV2State has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="    internal val positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;getPositionalThreshold$lint_module&apos;."
+        errorLine1="    internal val positionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Saver has parameter &apos;positionalThreshold&apos; with type Function2&lt;? super Density, ? super Float, Float>."
+        errorLine1="            positionalThreshold: Density.(distance: Float) -> Float,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;fixedPositionalThreshold&apos;."
+        errorLine1="public fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;fractionalPositionalThreshold&apos;."
+        errorLine1="): Density.(distance: Float) -> Float = { distance -> distance * fraction }"
+        errorLine2="   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Density, Float, Float> of &apos;getPositionalThreshold&apos;."
+        errorLine1="    val PositionalThreshold: Density.(totalDistance: Float) -> Float ="
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method ReconcileAnimationOnAnchorChangeHandler$lint_module has parameter &apos;animate&apos; with type Function2&lt;? super T, ? super Float, Unit>."
+        errorLine1="        animate: (target: T, velocity: Float) -> Unit,"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt"/>
+    </issue>
+
+</issues>
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/CurvedLayout.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/CurvedLayout.kt
index bddca99..de25e17 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/CurvedLayout.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/CurvedLayout.kt
@@ -413,9 +413,6 @@
 
 internal fun Float.toRadians() = this * PI.toFloat() / 180f
 internal fun Float.toDegrees() = this * 180f / PI.toFloat()
-internal fun <T> Iterable<T>.sumOf(
-    @Suppress("PrimitiveInLambda")
-    selector: (T) -> Float
-): Float = map(selector).sum()
+internal fun <T> Iterable<T>.sumOf(selector: (T) -> Float): Float = map(selector).sum()
 internal fun offsetFromDistanceAndAngle(distance: Float, angle: Float) =
     Offset(distance * cos(angle), distance * sin(angle))
\ No newline at end of file
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/Expandable.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/Expandable.kt
index 3e75aa0..8e8f89a 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/Expandable.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/Expandable.kt
@@ -77,9 +77,7 @@
 public fun ScalingLazyListScope.expandableItems(
     state: ExpandableState,
     count: Int,
-    @Suppress("PrimitiveInLambda")
     key: ((index: Int) -> Any)? = null,
-    @Suppress("PrimitiveInLambda")
     itemContent: @Composable BoxScope.(index: Int) -> Unit
 ) {
     repeat(count) { itemIndex ->
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt
index 556b7f2..a386e82 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeToReveal.kt
@@ -115,9 +115,7 @@
 public class RevealState internal constructor(
     initialValue: RevealValue,
     animationSpec: AnimationSpec<Float>,
-    @Suppress("PrimitiveInLambda")
     confirmValueChange: (RevealValue) -> Boolean,
-    @Suppress("PrimitiveInLambda")
     positionalThreshold: Density.(totalDistance: Float) -> Float,
     internal val anchors: Map<RevealValue, Float>
 ) {
@@ -220,9 +218,7 @@
 public fun rememberRevealState(
     initialValue: RevealValue = RevealValue.Covered,
     animationSpec: AnimationSpec<Float> = SwipeToRevealDefaults.animationSpec,
-    @Suppress("PrimitiveInLambda")
     confirmValueChange: (RevealValue) -> Boolean = { true },
-    @Suppress("PrimitiveInLambda")
     positionalThreshold: Density.(totalDistance: Float) -> Float =
         SwipeToRevealDefaults.defaultThreshold(),
     anchors: Map<RevealValue, Float> = createAnchors()
@@ -419,7 +415,6 @@
 
     internal const val threshold = 0.5f
 
-    @Suppress("PrimitiveInLambda")
     internal fun defaultThreshold() = fractionalPositionalThreshold(threshold)
 }
 
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
index 73dc4a9..273c59b 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/SwipeableV2.kt
@@ -115,7 +115,6 @@
     state: SwipeableV2State<T>,
     possibleValues: Set<T>,
     anchorChangeHandler: AnchorChangeHandler<T>? = null,
-    @Suppress("PrimitiveInLambda")
     calculateAnchor: (value: T, layoutSize: IntSize) -> Float?,
 ) = this.then(SwipeAnchorsModifier(
     onDensityChanged = { state.density = it },
@@ -175,7 +174,6 @@
     initialValue: T,
     internal val animationSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
     internal val confirmValueChange: (newValue: T) -> Boolean = { true },
-    @Suppress("PrimitiveInLambda")
     internal val positionalThreshold: Density.(totalDistance: Float) -> Float =
         SwipeableV2Defaults.PositionalThreshold,
     internal val velocityThreshold: Dp = SwipeableV2Defaults.VelocityThreshold,
@@ -498,7 +496,6 @@
         fun <T : Any> Saver(
             animationSpec: AnimationSpec<Float>,
             confirmValueChange: (T) -> Boolean,
-            @Suppress("PrimitiveInLambda")
             positionalThreshold: Density.(distance: Float) -> Float,
             velocityThreshold: Dp
         ) = Saver<SwipeableV2State<T>, T>(
@@ -557,7 +554,6 @@
  */
 @ExperimentalWearFoundationApi
 @RestrictTo(LIBRARY_GROUP)
-@Suppress("PrimitiveInLambda")
 public fun fixedPositionalThreshold(threshold: Dp): Density.(distance: Float) -> Float = {
     threshold.toPx()
 }
@@ -571,7 +567,6 @@
  */
 @ExperimentalWearFoundationApi
 @RestrictTo(LIBRARY_GROUP)
-@Suppress("PrimitiveInLambda")
 public fun fractionalPositionalThreshold(
     fraction: Float
 ): Density.(distance: Float) -> Float = { distance -> distance * fraction }
@@ -596,7 +591,6 @@
     /**
      * The default positional threshold (56 dp) used by [rememberSwipeableV2State]
      */
-    @Suppress("PrimitiveInLambda")
     val PositionalThreshold: Density.(totalDistance: Float) -> Float =
         fixedPositionalThreshold(56.dp)
 
@@ -617,7 +611,6 @@
     @ExperimentalWearFoundationApi
     internal fun <T> ReconcileAnimationOnAnchorChangeHandler(
         state: SwipeableV2State<T>,
-        @Suppress("PrimitiveInLambda")
         animate: (target: T, velocity: Float) -> Unit,
         snap: (target: T) -> Unit
     ) = AnchorChangeHandler { previousTarget, previousAnchors, newAnchors ->
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt
index ea184bf..7a6eba0 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumn.kt
@@ -91,9 +91,7 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable ScalingLazyListItemScope.(index: Int) -> Unit
     )
 }
@@ -132,7 +130,6 @@
  */
 inline fun <T> ScalingLazyListScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable ScalingLazyListItemScope.(index: Int, item: T) -> Unit
 ) = items(items.size, if (key != null) { index: Int -> key(index, items[index]) } else null) {
@@ -173,7 +170,6 @@
  */
 public inline fun <T> ScalingLazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable ScalingLazyListItemScope.(index: Int, item: T) -> Unit
 ) = items(items.size, if (key != null) { index: Int -> key(index, items[index]) } else null) {
@@ -572,7 +568,6 @@
         minTransitionArea: Float = 0.35f,
         maxTransitionArea: Float = 0.55f,
         scaleInterpolator: Easing = CubicBezierEasing(0.3f, 0f, 0.7f, 1f),
-        @Suppress("PrimitiveInLambda")
         viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 20f).toInt() }
     ): ScalingParams = DefaultScalingParams(
         edgeScale = edgeScale,
@@ -751,10 +746,7 @@
     }
 }
 
-private fun Modifier.autoCenteringHeight(
-    @Suppress("PrimitiveInLambda")
-    getHeight: () -> Int
-) =
+private fun Modifier.autoCenteringHeight(getHeight: () -> Int) =
     layout { measurable, constraints ->
         val height = getHeight()
         val placeable = measurable.measure(
diff --git a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt
index 73506a3..00d1260 100644
--- a/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt
+++ b/wear/compose/compose-foundation/src/main/java/androidx/wear/compose/foundation/lazy/ScalingLazyColumnMeasure.kt
@@ -211,7 +211,6 @@
     override val minTransitionArea: Float,
     override val maxTransitionArea: Float,
     override val scaleInterpolator: Easing,
-    @Suppress("PrimitiveInLambda")
     val viewportVerticalOffsetResolver: (Constraints) -> Int,
 ) : ScalingParams {
 
diff --git a/wear/compose/compose-material-core/lint-baseline.xml b/wear/compose/compose-material-core/lint-baseline.xml
new file mode 100644
index 0000000..813fc06
--- /dev/null
+++ b/wear/compose/compose-material-core/lint-baseline.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method drawProgressBar has parameter &apos;drawSelectedProgressBar&apos; with type Function4&lt;? super Color, ? super Float, ? super LayoutDirection, ? super DrawScope, Unit>."
+        errorLine1="        (color: Color, valueRatio: Float, direction: LayoutDirection, drawScope: DrawScope) -> Unit,"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/materialcore/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method drawProgressBar has parameter &apos;drawUnselectedProgressBar&apos; with type Function4&lt;? super Color, ? super Float, ? super LayoutDirection, ? super DrawScope, Unit>."
+        errorLine1="        (color: Color, valueRatio: Float, direction: LayoutDirection, drawScope: DrawScope) -> Unit,"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/materialcore/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method drawProgressBar has parameter &apos;drawProgressBarSeparator&apos; with type Function3&lt;? super Color, ? super Float, ? super DrawScope, Unit>."
+        errorLine1="    drawProgressBarSeparator: (color: Color, position: Float, drawScope: DrawScope) -> Unit,"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/materialcore/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/materialcore/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;updateValue&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    val updateValue: (Int) -> Unit = { stepDiff ->"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/materialcore/Stepper.kt"/>
+    </issue>
+
+</issues>
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Slider.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Slider.kt
index b724910..5042b3b 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Slider.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Slider.kt
@@ -62,7 +62,6 @@
 }
 
 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-@Suppress("PrimitiveInLambda")
 public fun Modifier.drawProgressBar(
     selectedBarColor: State<Color>,
     unselectedBarColor: State<Color>,
diff --git a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
index 2071aab..a82c450 100644
--- a/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
+++ b/wear/compose/compose-material-core/src/main/java/androidx/wear/compose/materialcore/Stepper.kt
@@ -79,7 +79,6 @@
 @Composable
 public fun Stepper(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     steps: Int,
     decreaseIcon: @Composable () -> Unit,
@@ -98,7 +97,6 @@
         )
     }
 
-    @Suppress("PrimitiveInLambda")
     val updateValue: (Int) -> Unit = { stepDiff ->
         val newValue =
             RangeDefaults.calculateCurrentStepValue(currentStep + stepDiff, steps, valueRange)
diff --git a/wear/compose/compose-material/lint-baseline.xml b/wear/compose/compose-material/lint-baseline.xml
new file mode 100644
index 0000000..77e29cb
--- /dev/null
+++ b/wear/compose/compose-material/lint-baseline.xml
@@ -0,0 +1,328 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;indicatorFactory&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    val indicatorFactory: @Composable (Int) -> Unit = { page ->"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method LinearPageIndicator has parameter &apos;indicatorFactory&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    indicatorFactory: @Composable (Int) -> Unit,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method CurvedPageIndicator has parameter &apos;indicatorFactory&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    indicatorFactory: @Composable (Int) -> Unit,"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Picker has parameter &apos;option&apos; with type Function2&lt;? super PickerScope, ? super Integer, Unit>."
+        errorLine1="    option: @Composable PickerScope.(optionIndex: Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Picker has parameter &apos;option&apos; with type Function2&lt;? super PickerScope, ? super Integer, ? extends Unit>."
+        errorLine1="    option: @Composable PickerScope.(optionIndex: Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Picker has parameter &apos;option&apos; with type Function2&lt;? super PickerScope, ? super Integer, ? extends Unit>."
+        errorLine1="    option: @Composable PickerScope.(optionIndex: Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Picker has parameter &apos;option&apos; with type Function2&lt;? super PickerScope, ? super Integer, Unit>."
+        errorLine1="    option: @Composable PickerScope.(optionIndex: Int) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method scalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="        viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 5f).toInt() }"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method defaultScalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="        viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 5f).toInt() }"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Picker.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method PickerGroup has parameter &apos;onSelected&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onSelected: (selectedIndex: Int) -> Unit = {},"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PickerGroup.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method PickerGroup has parameter &apos;separator&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    separator: (@Composable (Int) -> Unit)? = null"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PickerGroup.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor PickerGroupItem has parameter &apos;option&apos; with type Function3&lt;? super PickerScope, ? super Integer, ? super Boolean, Unit>."
+        errorLine1="    val option: @Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PickerGroup.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;PickerScope, Integer, Boolean, Unit> of &apos;getOption&apos;."
+        errorLine1="    val option: @Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PickerGroup.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method PositionIndicator has parameter &apos;value&apos; with type Function0&lt;Float>."
+        errorLine1="    value: () -> Float,"
+        errorLine2="           ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PositionIndicator.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor FractionPositionIndicatorState has parameter &apos;fraction&apos; with type Function0&lt;Float>."
+        errorLine1="    private val fraction: () -> Float"
+        errorLine2="                          ~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/PositionIndicator.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rangeSemantics has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/RangeDefaults.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;key&apos; with type Function1&lt;? super Integer, ? extends Object>."
+        errorLine1="        key: ((index: Int) -> Any)? = null,"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method items has parameter &apos;itemContent&apos; with type Function2&lt;? super ScalingLazyListItemScope, ? super Integer, Unit>."
+        errorLine1="        itemContent: @Composable ScalingLazyListItemScope.(index: Int) -> Unit"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method itemsIndexed has parameter &apos;key&apos; with type Function2&lt;? super Integer, ? super T, ? extends Object>."
+        errorLine1="    noinline key: ((index: Int, item: T) -> Any)? = null,"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method scalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="        viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 20f).toInt() }"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method autoCenteringHeight has parameter &apos;getHeight&apos; with type Function0&lt;Integer>."
+        errorLine1="private fun Modifier.autoCenteringHeight(getHeight: () -> Int) ="
+        errorLine2="                                                    ~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in constructor DefaultScalingParams has parameter &apos;viewportVerticalOffsetResolver&apos; with type Function1&lt;? super Constraints, Integer>."
+        errorLine1="    val viewportVerticalOffsetResolver: (Constraints) -> Int,"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function1&lt;Constraints, Integer> of &apos;getViewportVerticalOffsetResolver&apos;."
+        errorLine1="    val viewportVerticalOffsetResolver: (Constraints) -> Int,"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method InlineSlider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;updateValue&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="        val updateValue: (Int) -> Unit = { stepDiff ->"
+        errorLine2="                         ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method InlineSlider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onValueChange: (Int) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Slider.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onValueChange: (Int) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, ? extends Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, ? extends Unit>."
+        errorLine1="    onValueChange: (Int) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method setThresholds$lint_module has parameter &apos;&lt;set-?>&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function2&lt;Float, Float, Float> of &apos;getThresholds$lint_module&apos;."
+        errorLine1="    internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method computeTarget has parameter &apos;thresholds&apos; with type Function2&lt;? super Float, ? super Float, Float>."
+        errorLine1="    thresholds: (Float, Float) -> Float,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/Swipeable.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method currentTime has parameter &apos;time&apos; with type Function0&lt;Long>."
+        errorLine1="    time: () -> Long,"
+        errorLine2="          ~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/TimeText.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;updatedTimeLambda&apos; with type Function0&lt;? extends Long>."
+        errorLine1="    val updatedTimeLambda by rememberUpdatedState(time)"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material/TimeText.kt"/>
+    </issue>
+
+</issues>
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt
index fd65c91..08dd5cc 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/HorizontalPageIndicator.kt
@@ -117,7 +117,6 @@
     }
     pagesState.recalculateState(normalizedSelectedPage, normalizedOffset)
 
-    @Suppress("PrimitiveInLambda")
     val indicatorFactory: @Composable (Int) -> Unit = { page ->
         // An external box with a fixed indicatorSize - let us remain the same size for
         // an indicator even if it's shrinked for smooth animations
@@ -242,7 +241,6 @@
 private fun LinearPageIndicator(
     modifier: Modifier,
     pagesOnScreen: Int,
-    @Suppress("PrimitiveInLambda")
     indicatorFactory: @Composable (Int) -> Unit,
     spacerLeft: @Composable () -> Unit,
     spacerRight: @Composable () -> Unit
@@ -266,7 +264,6 @@
 private fun CurvedPageIndicator(
     modifier: Modifier,
     pagesOnScreen: Int,
-    @Suppress("PrimitiveInLambda")
     indicatorFactory: @Composable (Int) -> Unit,
     spacerLeft: @Composable () -> Unit,
     spacerRight: @Composable () -> Unit
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Picker.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Picker.kt
index 3e4cd26..2aaa04b 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Picker.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Picker.kt
@@ -125,7 +125,6 @@
     gradientColor: Color = MaterialTheme.colors.background,
     flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state),
     userScrollEnabled: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     option: @Composable PickerScope.(optionIndex: Int) -> Unit
 ) {
     require(gradientRatio in 0f..0.5f) { "gradientRatio should be between 0.0 and 0.5" }
@@ -251,7 +250,6 @@
     gradientColor: Color = MaterialTheme.colors.background,
     flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state),
     userScrollEnabled: Boolean = true,
-    @Suppress("PrimitiveInLambda")
     option: @Composable PickerScope.(optionIndex: Int) -> Unit
 ) = Picker(
     state = state,
@@ -328,7 +326,6 @@
     gradientRatio: Float = PickerDefaults.DefaultGradientRatio,
     gradientColor: Color = MaterialTheme.colors.background,
     flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state),
-    @Suppress("PrimitiveInLambda")
     option: @Composable PickerScope.(optionIndex: Int) -> Unit
 ) = Picker(
     state = state,
@@ -396,7 +393,6 @@
     gradientRatio: Float = PickerDefaults.DefaultGradientRatio,
     gradientColor: Color = MaterialTheme.colors.background,
     flingBehavior: FlingBehavior = PickerDefaults.flingBehavior(state),
-    @Suppress("PrimitiveInLambda")
     option: @Composable PickerScope.(optionIndex: Int) -> Unit
 ) = Picker(
     state = state,
@@ -661,7 +657,6 @@
         minTransitionArea: Float = 0.45f,
         maxTransitionArea: Float = 0.45f,
         scaleInterpolator: Easing = CubicBezierEasing(0.25f, 0.00f, 0.75f, 1.00f),
-        @Suppress("PrimitiveInLambda")
         viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 5f).toInt() }
     ): androidx.wear.compose.material.ScalingParams =
         androidx.wear.compose.material.ScalingLazyColumnDefaults.scalingParams(
@@ -687,7 +682,6 @@
         minTransitionArea: Float = 0.45f,
         maxTransitionArea: Float = 0.45f,
         scaleInterpolator: Easing = CubicBezierEasing(0.25f, 0.00f, 0.75f, 1.00f),
-        @Suppress("PrimitiveInLambda")
         viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 5f).toInt() }
     ): ScalingParams =
         ScalingLazyColumnDefaults.scalingParams(
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PickerGroup.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PickerGroup.kt
index 8a7d6d4..8588ee8 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PickerGroup.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PickerGroup.kt
@@ -87,13 +87,11 @@
     vararg pickers: PickerGroupItem,
     modifier: Modifier = Modifier,
     pickerGroupState: PickerGroupState = rememberPickerGroupState(),
-    @Suppress("PrimitiveInLambda")
     onSelected: (selectedIndex: Int) -> Unit = {},
     autoCenter: Boolean = true,
     propagateMinConstraints: Boolean = false,
     touchExplorationStateProvider: TouchExplorationStateProvider =
         DefaultTouchExplorationStateProvider(),
-    @Suppress("PrimitiveInLambda")
     separator: (@Composable (Int) -> Unit)? = null
 ) {
     val touchExplorationServicesEnabled by touchExplorationStateProvider.touchExplorationState()
@@ -245,7 +243,6 @@
     val focusRequester: FocusRequester? = null,
     val onSelected: () -> Unit = {},
     val readOnlyLabel: @Composable (BoxScope.() -> Unit)? = null,
-    @Suppress("PrimitiveInLambda")
     val option: @Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit
 )
 
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
index e5abd9f8..74be61a 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
@@ -339,7 +339,6 @@
  */
 @Composable
 public fun PositionIndicator(
-    @Suppress("PrimitiveInLambda")
     value: () -> Float,
     modifier: Modifier = Modifier,
     range: ClosedFloatingPointRange<Float> = 0f..1f,
@@ -647,7 +646,6 @@
  * @VisibleForTesting
  */
 internal class FractionPositionIndicatorState(
-    @Suppress("PrimitiveInLambda")
     private val fraction: () -> Float
 ) : PositionIndicatorState {
     override val positionFraction = 1f // Position indicator always starts at the bottom|end
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/RangeDefaults.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/RangeDefaults.kt
index af28aa7..a4943d6 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/RangeDefaults.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/RangeDefaults.kt
@@ -26,7 +26,6 @@
 internal fun Modifier.rangeSemantics(
     value: Float,
     enabled: Boolean,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     valueRange: ClosedFloatingPointRange<Float>,
     steps: Int
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt
index 4c31a63..3c93e35 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumn.kt
@@ -92,9 +92,7 @@
      */
     fun items(
         count: Int,
-        @Suppress("PrimitiveInLambda")
         key: ((index: Int) -> Any)? = null,
-        @Suppress("PrimitiveInLambda")
         itemContent: @Composable ScalingLazyListItemScope.(index: Int) -> Unit
     )
 }
@@ -137,7 +135,6 @@
     "Please use it instead")
 inline fun <T> ScalingLazyListScope.itemsIndexed(
     items: List<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable ScalingLazyListItemScope.(index: Int, item: T) -> Unit
 ) = items(items.size, if (key != null) { index: Int -> key(index, items[index]) } else null) {
@@ -182,7 +179,6 @@
     "Please use it instead")
 public inline fun <T> ScalingLazyListScope.itemsIndexed(
     items: Array<T>,
-    @Suppress("PrimitiveInLambda")
     noinline key: ((index: Int, item: T) -> Any)? = null,
     crossinline itemContent: @Composable ScalingLazyListItemScope.(index: Int, item: T) -> Unit
 ) = items(items.size, if (key != null) { index: Int -> key(index, items[index]) } else null) {
@@ -587,7 +583,6 @@
         minTransitionArea: Float = 0.35f,
         maxTransitionArea: Float = 0.55f,
         scaleInterpolator: Easing = CubicBezierEasing(0.3f, 0f, 0.7f, 1f),
-        @Suppress("PrimitiveInLambda")
         viewportVerticalOffsetResolver: (Constraints) -> Int = { (it.maxHeight / 20f).toInt() }
     ): ScalingParams = DefaultScalingParams(
         edgeScale = edgeScale,
@@ -704,10 +699,7 @@
     }
 }
 
-private fun Modifier.autoCenteringHeight(
-    @Suppress("PrimitiveInLambda")
-    getHeight: () -> Int
-) =
+private fun Modifier.autoCenteringHeight(getHeight: () -> Int) =
     layout { measurable, constraints ->
         val height = getHeight()
         val placeable = measurable.measure(
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt
index 628ed2d..382be50 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/ScalingLazyColumnMeasure.kt
@@ -215,7 +215,6 @@
     override val minTransitionArea: Float,
     override val maxTransitionArea: Float,
     override val scaleInterpolator: Easing,
-    @Suppress("PrimitiveInLambda")
     val viewportVerticalOffsetResolver: (Constraints) -> Int,
 ) : ScalingParams {
 
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Slider.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Slider.kt
index 9a474a9..ec0a2a2 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Slider.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Slider.kt
@@ -94,7 +94,6 @@
 @Composable
 public fun InlineSlider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     steps: Int,
     decreaseIcon: @Composable () -> Unit,
@@ -130,7 +129,6 @@
 
         val visibleSegments = if (segmented) steps + 1 else 1
 
-        @Suppress("PrimitiveInLambda")
         val updateValue: (Int) -> Unit = { stepDiff ->
             val newValue =
                 RangeDefaults.calculateCurrentStepValue(currentStep + stepDiff, steps, valueRange)
@@ -257,7 +255,6 @@
 @Composable
 public fun InlineSlider(
     value: Int,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Int) -> Unit,
     valueProgression: IntProgression,
     decreaseIcon: @Composable () -> Unit,
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
index 2606954..0b28d50 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Stepper.kt
@@ -66,7 +66,6 @@
 @Composable
 fun Stepper(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     steps: Int,
     decreaseIcon: @Composable () -> Unit,
@@ -155,7 +154,6 @@
 @Composable
 fun Stepper(
     value: Int,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Int) -> Unit,
     valueProgression: IntProgression,
     decreaseIcon: @Composable () -> Unit,
@@ -219,7 +217,6 @@
 @Composable
 public fun Stepper(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     steps: Int,
     decreaseIcon: @Composable () -> Unit,
@@ -286,7 +283,6 @@
 @Composable
 fun Stepper(
     value: Int,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Int) -> Unit,
     valueProgression: IntProgression,
     decreaseIcon: @Composable () -> Unit,
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Swipeable.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Swipeable.kt
index 6c84d68..9a6fda0 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Swipeable.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/Swipeable.kt
@@ -201,7 +201,6 @@
         }
     }
 
-    @Suppress("PrimitiveInLambda")
     internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
 
     internal var velocityThreshold by mutableFloatStateOf(0f)
@@ -767,7 +766,6 @@
     offset: Float,
     lastValue: Float,
     anchors: Set<Float>,
-    @Suppress("PrimitiveInLambda")
     thresholds: (Float, Float) -> Float,
     velocity: Float,
     velocityThreshold: Float
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/TimeText.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/TimeText.kt
index 9eed5c1..5dea0bbb 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/TimeText.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/TimeText.kt
@@ -312,7 +312,6 @@
 @Composable
 @VisibleForTesting
 internal fun currentTime(
-    @Suppress("PrimitiveInLambda")
     time: () -> Long,
     timeFormat: String
 ): State<String> {
@@ -325,7 +324,6 @@
     }
 
     val context = LocalContext.current
-    @Suppress("PrimitiveInLambda")
     val updatedTimeLambda by rememberUpdatedState(time)
 
     DisposableEffect(context, updatedTimeLambda) {
diff --git a/wear/compose/compose-material3/api/current.txt b/wear/compose/compose-material3/api/current.txt
index 2142a1b..f9659e1 100644
--- a/wear/compose/compose-material3/api/current.txt
+++ b/wear/compose/compose-material3/api/current.txt
@@ -210,6 +210,10 @@
     method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.wear.compose.material3.ColorScheme colorScheme, optional androidx.wear.compose.material3.Typography typography, optional androidx.wear.compose.material3.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
+  public final class RangeSemanticsKt {
+    method public static androidx.compose.ui.Modifier rangeSemantics(androidx.compose.ui.Modifier, float value, boolean enabled, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, int steps);
+  }
+
   public final class ShapeDefaults {
     method public androidx.compose.foundation.shape.RoundedCornerShape getExtraLarge();
     method public androidx.compose.foundation.shape.RoundedCornerShape getExtraSmall();
@@ -247,6 +251,19 @@
     property public final androidx.compose.ui.graphics.Shape small;
   }
 
+  public final class StepperDefaults {
+    method public androidx.compose.ui.graphics.vector.ImageVector getDecrease();
+    method public androidx.compose.ui.graphics.vector.ImageVector getIncrease();
+    property public final androidx.compose.ui.graphics.vector.ImageVector Decrease;
+    property public final androidx.compose.ui.graphics.vector.ImageVector Increase;
+    field public static final androidx.wear.compose.material3.StepperDefaults INSTANCE;
+  }
+
+  public final class StepperKt {
+    method @androidx.compose.runtime.Composable public static void Stepper(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, int steps, kotlin.jvm.functions.Function0<kotlin.Unit> decreaseIcon, kotlin.jvm.functions.Function0<kotlin.Unit> increaseIcon, optional androidx.compose.ui.Modifier modifier, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional long backgroundColor, optional long contentColor, optional long iconColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Stepper(int value, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onValueChange, kotlin.ranges.IntProgression valueProgression, kotlin.jvm.functions.Function0<kotlin.Unit> decreaseIcon, kotlin.jvm.functions.Function0<kotlin.Unit> increaseIcon, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional long iconColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
   @androidx.compose.runtime.Immutable public final class TextButtonColors {
     ctor public TextButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
   }
diff --git a/wear/compose/compose-material3/api/restricted_current.txt b/wear/compose/compose-material3/api/restricted_current.txt
index 2142a1b..f9659e1 100644
--- a/wear/compose/compose-material3/api/restricted_current.txt
+++ b/wear/compose/compose-material3/api/restricted_current.txt
@@ -210,6 +210,10 @@
     method @androidx.compose.runtime.Composable public static void MaterialTheme(optional androidx.wear.compose.material3.ColorScheme colorScheme, optional androidx.wear.compose.material3.Typography typography, optional androidx.wear.compose.material3.Shapes shapes, kotlin.jvm.functions.Function0<kotlin.Unit> content);
   }
 
+  public final class RangeSemanticsKt {
+    method public static androidx.compose.ui.Modifier rangeSemantics(androidx.compose.ui.Modifier, float value, boolean enabled, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, int steps);
+  }
+
   public final class ShapeDefaults {
     method public androidx.compose.foundation.shape.RoundedCornerShape getExtraLarge();
     method public androidx.compose.foundation.shape.RoundedCornerShape getExtraSmall();
@@ -247,6 +251,19 @@
     property public final androidx.compose.ui.graphics.Shape small;
   }
 
+  public final class StepperDefaults {
+    method public androidx.compose.ui.graphics.vector.ImageVector getDecrease();
+    method public androidx.compose.ui.graphics.vector.ImageVector getIncrease();
+    property public final androidx.compose.ui.graphics.vector.ImageVector Decrease;
+    property public final androidx.compose.ui.graphics.vector.ImageVector Increase;
+    field public static final androidx.wear.compose.material3.StepperDefaults INSTANCE;
+  }
+
+  public final class StepperKt {
+    method @androidx.compose.runtime.Composable public static void Stepper(float value, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onValueChange, int steps, kotlin.jvm.functions.Function0<kotlin.Unit> decreaseIcon, kotlin.jvm.functions.Function0<kotlin.Unit> increaseIcon, optional androidx.compose.ui.Modifier modifier, optional kotlin.ranges.ClosedFloatingPointRange<java.lang.Float> valueRange, optional long backgroundColor, optional long contentColor, optional long iconColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+    method @androidx.compose.runtime.Composable public static void Stepper(int value, kotlin.jvm.functions.Function1<? super java.lang.Integer,kotlin.Unit> onValueChange, kotlin.ranges.IntProgression valueProgression, kotlin.jvm.functions.Function0<kotlin.Unit> decreaseIcon, kotlin.jvm.functions.Function0<kotlin.Unit> increaseIcon, optional androidx.compose.ui.Modifier modifier, optional long backgroundColor, optional long contentColor, optional long iconColor, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+  }
+
   @androidx.compose.runtime.Immutable public final class TextButtonColors {
     ctor public TextButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
   }
diff --git a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
index c24447b..4e3d505 100644
--- a/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
+++ b/wear/compose/compose-material3/integration-tests/src/main/java/androidx/wear/compose/material3/demos/WearMaterial3Demos.kt
@@ -16,16 +16,30 @@
 
 package androidx.wear.compose.material3.demos
 
+import androidx.compose.ui.Alignment
+import androidx.wear.compose.foundation.lazy.AutoCenteringParams
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
 import androidx.wear.compose.integration.demos.common.Centralize
 import androidx.wear.compose.integration.demos.common.ComposableDemo
 import androidx.wear.compose.integration.demos.common.DemoCategory
+import androidx.wear.compose.material3.samples.AppCardSample
+import androidx.wear.compose.material3.samples.AppCardWithIconSample
+import androidx.wear.compose.material3.samples.CardSample
 import androidx.wear.compose.material3.samples.FixedFontSize
+import androidx.wear.compose.material3.samples.OutlinedAppCardSample
+import androidx.wear.compose.material3.samples.OutlinedCardSample
+import androidx.wear.compose.material3.samples.OutlinedTitleCardSample
+import androidx.wear.compose.material3.samples.StepperSample
+import androidx.wear.compose.material3.samples.StepperWithIntegerSample
+import androidx.wear.compose.material3.samples.StepperWithRangeSemanticsSample
+import androidx.wear.compose.material3.samples.TitleCardSample
+import androidx.wear.compose.material3.samples.TitleCardWithImageSample
 
 val WearMaterial3Demos = DemoCategory(
     "Material 3",
     listOf(
         DemoCategory(
-            "Buttons",
+            "Button",
             listOf(
                 ComposableDemo("Button") {
                     ButtonDemo()
@@ -41,12 +55,51 @@
                 }
             )
         ),
+        DemoCategory(
+            "Card",
+            listOf(
+                ComposableDemo("Samples") {
+                    ScalingLazyColumn(
+                        horizontalAlignment = Alignment.CenterHorizontally,
+                        autoCentering = AutoCenteringParams(itemIndex = 0)
+                    ) {
+                        item { CardSample() }
+                        item { AppCardSample() }
+                        item { AppCardWithIconSample() }
+                        item { TitleCardSample() }
+                        item { TitleCardWithImageSample() }
+                        item { OutlinedCardSample() }
+                        item { OutlinedAppCardSample() }
+                        item { OutlinedTitleCardSample() }
+                    }
+                }
+            )
+        ),
         ComposableDemo("Text Button") {
             TextButtonDemo()
         },
         ComposableDemo("Icon Button") {
             IconButtonDemo()
         },
+        DemoCategory(
+            "Stepper",
+            listOf(
+                DemoCategory(
+                    "Samples",
+                    listOf(
+                        ComposableDemo("Stepper") {
+                            Centralize { StepperSample() }
+                        },
+                        ComposableDemo("Integer Stepper") {
+                            Centralize { StepperWithIntegerSample() }
+                        },
+                        ComposableDemo("Stepper with rangeSemantics") {
+                            Centralize { StepperWithRangeSemanticsSample() }
+                        }
+                    )
+                )
+            )
+        ),
         ComposableDemo(
             title = "Fixed Font Size"
         ) {
diff --git a/wear/compose/compose-material3/lint-baseline.xml b/wear/compose/compose-material3/lint-baseline.xml
new file mode 100644
index 0000000..63fcac6
--- /dev/null
+++ b/wear/compose/compose-material3/lint-baseline.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method rangeSemantics has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material3/RangeSemantics.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material3/Stepper.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method Stepper has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onValueChange: (Int) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/material3/Stepper.kt"/>
+    </issue>
+
+</issues>
diff --git a/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/CardSample.kt b/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/CardSample.kt
new file mode 100644
index 0000000..4e5af0f
--- /dev/null
+++ b/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/CardSample.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.wear.compose.material3.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.wear.compose.material3.AppCard
+import androidx.wear.compose.material3.Card
+import androidx.wear.compose.material3.CardDefaults
+import androidx.wear.compose.material3.Icon
+import androidx.wear.compose.material3.MaterialTheme
+import androidx.wear.compose.material3.OutlinedCard
+import androidx.wear.compose.material3.Text
+import androidx.wear.compose.material3.TitleCard
+
+@Sampled
+@Composable
+fun CardSample() {
+    Card(
+        onClick = { /* Do something */ },
+    ) {
+        Text("Card")
+    }
+}
+
+@Sampled
+@Composable
+fun AppCardSample() {
+    AppCard(
+        onClick = { /* Do something */ },
+        appName = { Text("AppName") },
+        title = { Text("AppCard") },
+        time = { Text("now") },
+    ) {
+        Text("Card content")
+    }
+}
+
+@Sampled
+@Composable
+fun AppCardWithIconSample() {
+    AppCard(
+        onClick = { /* Do something */ },
+        appName = { Text("AppName") },
+        appImage = {
+            Icon(
+                painter = painterResource(id = android.R.drawable.star_big_off),
+                contentDescription = "favourites",
+                modifier = Modifier
+                    .size(CardDefaults.AppImageSize)
+                    .wrapContentSize(align = Alignment.Center),
+            )
+        },
+        title = { Text("AppCard with icon") },
+        time = { Text("now") },
+    ) {
+        Text("Card content")
+    }
+}
+
+@Sampled
+@Composable
+fun TitleCardSample() {
+    TitleCard(
+        onClick = { /* Do something */ },
+        title = { Text("TitleCard") },
+        time = { Text("now") },
+    ) {
+        Text("Card content")
+    }
+}
+
+@Sampled
+@Composable
+fun TitleCardWithImageSample() {
+    TitleCard(
+        onClick = { /* Do something */ },
+        title = { Text("TitleCard With an ImageBackground") },
+        colors = CardDefaults.imageCardColors(
+            containerPainter = CardDefaults.imageWithScrimBackgroundPainter(
+                backgroundImagePainter = painterResource(id = R.drawable.backgroundimage)
+            ),
+            contentColor = MaterialTheme.colorScheme.onSurface,
+            titleColor = MaterialTheme.colorScheme.onSurface
+        )
+    ) {
+        Text("Card content")
+    }
+}
+
+@Sampled
+@Composable
+fun OutlinedCardSample() {
+    OutlinedCard(
+        onClick = { /* Do something */ },
+    ) {
+        Text("OutlinedCard")
+    }
+}
+
+@Sampled
+@Composable
+fun OutlinedAppCardSample() {
+    AppCard(
+        onClick = { /* Do something */ },
+        appName = { Text("AppName") },
+        title = { Text("Outlined AppCard") },
+        colors = CardDefaults.outlinedCardColors(),
+        border = CardDefaults.outlinedCardBorder(),
+    ) {
+        Text("Card content")
+    }
+}
+
+@Sampled
+@Composable
+fun OutlinedTitleCardSample() {
+    TitleCard(
+        onClick = { /* Do something */ },
+        title = { Text("Outlined TitleCard") },
+        colors = CardDefaults.outlinedCardColors(),
+        border = CardDefaults.outlinedCardBorder(),
+    ) {
+        Text("Card content")
+    }
+}
diff --git a/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/StepperSample.kt b/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/StepperSample.kt
new file mode 100644
index 0000000..0ca665d
--- /dev/null
+++ b/wear/compose/compose-material3/samples/src/main/java/androidx/wear/compose/material3/samples/StepperSample.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.wear.compose.material3.samples
+
+import androidx.annotation.Sampled
+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.wear.compose.material3.Icon
+import androidx.wear.compose.material3.Stepper
+import androidx.wear.compose.material3.StepperDefaults
+import androidx.wear.compose.material3.Text
+import androidx.wear.compose.material3.rangeSemantics
+
+@Sampled
+@Composable
+fun StepperSample() {
+    var value by remember { mutableStateOf(2f) }
+    Stepper(
+        value = value,
+        onValueChange = { value = it },
+        valueRange = 1f..4f,
+        increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+        decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+        steps = 7
+    ) { Text("Value: $value") }
+}
+
+@Sampled
+@Composable
+fun StepperWithIntegerSample() {
+    var value by remember { mutableStateOf(2) }
+    Stepper(
+        value = value,
+        onValueChange = { value = it },
+        increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+        decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+        valueProgression = 1..10
+    ) { Text("Value: $value") }
+}
+
+@Sampled
+@Composable
+fun StepperWithRangeSemanticsSample() {
+    var value by remember { mutableStateOf(2f) }
+    val valueRange = 1f..4f
+    val onValueChange = { i: Float -> value = i }
+    val steps = 7
+
+    Stepper(
+        value = value,
+        onValueChange = onValueChange,
+        valueRange = valueRange,
+        modifier = Modifier.rangeSemantics(value, true, onValueChange, valueRange, steps),
+        increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+        decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+        steps = steps,
+    ) { Text("Value: $value") }
+}
diff --git a/wear/compose/compose-material3/samples/src/main/res/drawable/backgroundimage.png b/wear/compose/compose-material3/samples/src/main/res/drawable/backgroundimage.png
new file mode 100644
index 0000000..ea5a397
--- /dev/null
+++ b/wear/compose/compose-material3/samples/src/main/res/drawable/backgroundimage.png
Binary files differ
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperScreenshotTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperScreenshotTest.kt
new file mode 100644
index 0000000..0a66e9b
--- /dev/null
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperScreenshotTest.kt
@@ -0,0 +1,197 @@
+/*
+ * 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.wear.compose.material3.test
+
+import android.os.Build
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Star
+import androidx.compose.material.icons.filled.ThumbUp
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+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.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import androidx.wear.compose.material3.FilledTonalButton
+import androidx.wear.compose.material3.Icon
+import androidx.wear.compose.material3.MaterialTheme
+import androidx.wear.compose.material3.SCREENSHOT_GOLDEN_PATH
+import androidx.wear.compose.material3.Stepper
+import androidx.wear.compose.material3.StepperDefaults
+import androidx.wear.compose.material3.TEST_TAG
+import androidx.wear.compose.material3.Text
+import androidx.wear.compose.material3.setContentWithTheme
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+public class StepperScreenshotTest {
+    @get:Rule
+    public val rule = createComposeRule()
+
+    @get:Rule
+    public val screenshotRule = AndroidXScreenshotTestRule(SCREENSHOT_GOLDEN_PATH)
+
+    @get:Rule
+    public val testName = TestName()
+
+    @Test
+    public fun stepper_no_content() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                steps = 3,
+                onValueChange = {}
+            ) {}
+        }
+    }
+
+    @Test
+    public fun stepper_custom_icons() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                steps = 3,
+                onValueChange = {},
+                decreaseIcon = {
+                    Icon(
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                },
+                increaseIcon = {
+                    Icon(
+                        imageVector = Icons.Filled.ThumbUp,
+                        contentDescription = ""
+                    )
+                },
+            ) {}
+        }
+    }
+
+    @Test
+    public fun stepper_with_content() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                steps = 3,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                onValueChange = {}
+            ) {
+                FilledTonalButton(
+                    onClick = {},
+                    modifier = Modifier.width(146.dp),
+                    label = {
+                        Text(
+                            text = "Demo",
+                            modifier = Modifier.fillMaxWidth()
+                        )
+                    }
+                )
+            }
+        }
+    }
+
+    @Test
+    public fun stepper_with_custom_colors() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                steps = 3,
+                onValueChange = {},
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                backgroundColor = Color.Green,
+                contentColor = Color.Yellow,
+                iconColor = Color.Magenta,
+            ) {
+                Text("Demo")
+            }
+        }
+    }
+
+    @Test
+    public fun stepper_with_increase_button_disabled() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                valueRange = 0f..4f,
+                value = 4f,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                steps = 3,
+                onValueChange = {}
+            ) {}
+        }
+    }
+
+    @Test
+    public fun stepper_with_decrease_button_disabled() {
+        verifyScreenshot {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                valueRange = 0f..4f,
+                value = 0f,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                steps = 3,
+                onValueChange = {}
+            ) {}
+        }
+    }
+
+    private fun verifyScreenshot(
+        content: @Composable () -> Unit
+    ) {
+        rule.setContentWithTheme {
+            Box(
+                modifier = Modifier
+                    .fillMaxSize()
+                    .background(MaterialTheme.colorScheme.background)
+            ) {
+                content()
+            }
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+}
diff --git a/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperTest.kt b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperTest.kt
new file mode 100644
index 0000000..c683c09
--- /dev/null
+++ b/wear/compose/compose-material3/src/androidTest/kotlin/androidx/wear/compose/material3/StepperTest.kt
@@ -0,0 +1,676 @@
+/*
+ * 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.wear.compose.material3
+
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Star
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.ProgressBarRangeInfo
+import androidx.compose.ui.test.assertContentDescriptionContains
+import androidx.compose.ui.test.assertHasNoClickAction
+import androidx.compose.ui.test.assertRangeInfoEquals
+import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
+import androidx.compose.ui.test.click
+import androidx.compose.ui.test.getUnclippedBoundsInRoot
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onChild
+import androidx.compose.ui.test.onChildAt
+import androidx.compose.ui.test.onNodeWithContentDescription
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onParent
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.height
+import com.google.common.truth.Truth
+import kotlin.math.roundToInt
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+
+public class StepperTest {
+    @get:Rule
+    public val rule = createComposeRule()
+
+    @Test
+    public fun supports_testtag() {
+        rule.setContentWithTheme {
+            Stepper(
+                value = 1f,
+                onValueChange = {},
+                steps = 5,
+                increaseIcon = {},
+                decreaseIcon = {},
+                modifier = Modifier.testTag(TEST_TAG)
+            ) {}
+        }
+
+        rule.onNodeWithTag(TEST_TAG).assertExists()
+    }
+
+    @Test
+    public fun coerces_value_top_limit() = rule.setNewValueAndCheck(
+        range = 0f..10f,
+        steps = 4,
+        initialValue = 4f,
+        newValue = 20f,
+        expectedFinalValue = 10f
+    )
+
+    @Test
+    public fun coerces_value_lower_limit() = rule.setNewValueAndCheck(
+        range = 0f..10f,
+        steps = 4,
+        initialValue = 4f,
+        newValue = -20f,
+        expectedFinalValue = 0f
+    )
+
+    @Test(expected = IllegalArgumentException::class)
+    public fun throws_when_steps_negative() {
+        rule.setContent {
+            Stepper(
+                value = 0f,
+                onValueChange = {},
+                increaseIcon = {},
+                decreaseIcon = {},
+                steps = -1
+            ) {}
+        }
+    }
+
+    @Test
+    public fun coerce_value_exactly() = rule.setNewValueAndCheck(
+        range = 0f..1f,
+        steps = 4,
+        initialValue = 0f,
+        // Allowed values are only 0, 0.2, 0.4, 0.6, 0.8, 1
+        newValue = 0.6f,
+        expectedFinalValue = 0.6f
+    )
+
+    @Test
+    public fun coerce_value_to_previous() = rule.setNewValueAndCheck(
+        range = 0f..1f,
+        steps = 4,
+        initialValue = 0f,
+        // Allowed values are only 0, 0.2, 0.4, 0.6, 0.8, 1
+        newValue = 0.65f,
+        expectedFinalValue = 0.6f
+    )
+
+    @Test
+    public fun coerce_value_to_next() = rule.setNewValueAndCheck(
+        range = 0f..1f,
+        steps = 4,
+        initialValue = 0f,
+        // Allowed values are only 0, 0.2, 0.4, 0.6, 0.8, 1
+        newValue = 0.55f,
+        expectedFinalValue = 0.6f
+    )
+
+    @Test
+    public fun decreases_value_by_clicking_bottom() {
+        val state = mutableStateOf(2f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        // The clickable area for a decrease button takes bottom 35% of the screen
+        rule.onNodeWithTag(TEST_TAG).performTouchInput {
+            click(Offset(width / 2f, height - 15f))
+        }
+
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(1f)
+        }
+    }
+
+    @Test
+    public fun increases_value_by_clicking_top() {
+        val state = mutableStateOf(2f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        // The clickable area for an increase button takes top 35% of the screen
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width / 2f, 15f)) }
+
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(3f)
+        }
+    }
+
+    @Test
+    public fun reaches_min_clicking_bottom() {
+        // Start one step above the minimum.
+        val state = mutableStateOf(2f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        // The clickable area for a decrease button takes bottom 35% of the screen
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width / 2f, height - 15f)) }
+
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(1f)
+        }
+    }
+
+    @Test
+    public fun reaches_max_clicking_top() {
+        // Start one step below the maximum.
+        val state = mutableStateOf(3f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        // The clickable area for an increase button takes top 35% of the screen
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width / 2f, 15f)) }
+
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(4f)
+        }
+    }
+
+    @Test
+    public fun disables_decrease_when_minimum_value_reached() {
+        val state = mutableStateOf(1f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        rule.onNodeWithContentDescription(DECREASE).onParent().assertHasNoClickAction()
+    }
+
+    @Test
+    public fun disables_increase_when_maximum_value_reached() {
+        val state = mutableStateOf(4f)
+        val range = 1f..4f
+
+        rule.initDefaultStepper(state, range, 2)
+
+        rule.onNodeWithContentDescription(INCREASE).onParent().assertHasNoClickAction()
+    }
+
+    @Test
+    public fun colors_decrease_icon_with_disabled_alpha() =
+        verifyDisabledColors(increase = false, value = 1f)
+
+    @Test
+    public fun colors_increase_icon_with_disabled_alpha() =
+        verifyDisabledColors(increase = true, value = 4f)
+
+    @Test
+    public fun sets_custom_decrease_icon() {
+        val iconTag = "iconTag_test"
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                onValueChange = { },
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = {
+                    Icon(
+                        modifier = Modifier.testTag(iconTag),
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                },
+            ) {}
+        }
+        val unclippedBoundsInRoot = rule.onRoot().getUnclippedBoundsInRoot()
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(iconTag, true)
+            .assertExists()
+            .assertTopPositionInRootIsEqualTo(
+                unclippedBoundsInRoot.height -
+                    BorderVerticalMargin - DefaultIconHeight
+            )
+    }
+
+    @Test
+    public fun sets_custom_increase_icon() {
+        val iconTag = "iconTag_test"
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                onValueChange = { },
+                increaseIcon = {
+                    Icon(
+                        modifier = Modifier.testTag(iconTag),
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+            ) {}
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag(iconTag, true)
+            .assertExists()
+            .assertTopPositionInRootIsEqualTo(BorderVerticalMargin)
+    }
+
+    @Test
+    public fun sets_content() {
+        val contentTag = "contentTag_test"
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                onValueChange = { },
+            ) {
+                Text("Testing", modifier = Modifier
+                    .testTag(contentTag)
+                    .fillMaxHeight())
+            }
+        }
+
+        val rootHeight = rule.onRoot().getUnclippedBoundsInRoot().height
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(contentTag, true)
+            .assertExists()
+            .assertTopPositionInRootIsEqualTo(
+                // Position of the content is a weight(35%) of (top button minus 2 spacers 8dp each)
+                // plus 1 spacer
+                (rootHeight - VerticalMargin * 2) * ButtonWeight + VerticalMargin
+            )
+    }
+
+    @Test
+    public fun sets_custom_description_for_increase_icon() {
+        val testContentDescription = "testContentDescription"
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                increaseIcon = { Icon(StepperDefaults.Increase, testContentDescription) },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                onValueChange = { },
+            ) {}
+        }
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(TEST_TAG, true)
+            // 0 is the index of increase button, 1 - decrease button, content is empty
+            .onChildAt(0)
+            .onChild()
+            .assertContentDescriptionContains(testContentDescription)
+    }
+
+    @Test
+    public fun sets_custom_description_for_decrease_icon() {
+        val testContentDescription = "testContentDescription"
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, testContentDescription) },
+                onValueChange = { },
+            ) {}
+        }
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(TEST_TAG, true)
+            // 0 is the index of increase button, 1 - decrease button, content is empty
+            .onChildAt(1)
+            .onChild()
+            .assertContentDescriptionContains(testContentDescription)
+    }
+
+    @Test(expected = java.lang.AssertionError::class)
+    fun does_not_support_stepper_range_semantics_by_default() {
+        val value = 1f
+        val steps = 5
+        val valueRange = 0f..(steps + 1).toFloat()
+
+        val modifier = Modifier.testTag(TEST_TAG)
+
+        rule.setContentWithTheme {
+            Stepper(
+                modifier = modifier,
+                value = value,
+                steps = steps,
+                valueRange = valueRange,
+                onValueChange = { },
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+            ) {}
+        }
+        rule.waitForIdle()
+        // Should throw assertion error for assertRangeInfoEquals
+        rule.onNodeWithTag(TEST_TAG, true)
+            .assertExists()
+            .assertRangeInfoEquals(ProgressBarRangeInfo(value, valueRange, steps))
+    }
+
+    @Test
+    fun enable_stepper_semantics_using_modifier() {
+        val value = 1f
+        val steps = 5
+        val valueRange = 0f..(steps + 1).toFloat()
+
+        rule.setContentWithTheme {
+            Stepper(
+                value = value,
+                steps = steps,
+                valueRange = valueRange,
+                onValueChange = { },
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                modifier = Modifier
+                    .testTag(TEST_TAG)
+                    .rangeSemantics(value, true, {}, valueRange, steps)
+            ) {}
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag(TEST_TAG, true)
+            .assertExists()
+            .assertRangeInfoEquals(ProgressBarRangeInfo(value, valueRange, steps))
+    }
+
+    private fun verifyDisabledColors(increase: Boolean, value: Float) {
+        val state = mutableStateOf(value)
+        var expectedIconColor = Color.Transparent
+        var actualIconColor = Color.Transparent
+        var expectedAlpha = 0f
+        var actualAlpha = 0f
+
+        rule.setContentWithTheme {
+            expectedIconColor = MaterialTheme.colorScheme.primary.copy(
+                alpha = ContentAlpha.disabled
+            )
+            expectedAlpha = expectedIconColor.alpha
+            Stepper(
+                value = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2,
+                iconColor = MaterialTheme.colorScheme.primary,
+                increaseIcon = {
+                    if (increase) {
+                        actualIconColor = LocalContentColor.current
+                        actualAlpha = LocalContentAlpha.current
+                    }
+                },
+                decreaseIcon = {
+                    if (!increase) {
+                        actualIconColor = LocalContentColor.current
+                        actualAlpha = LocalContentAlpha.current
+                    }
+                },
+                modifier = Modifier.testTag(TEST_TAG)
+            ) {}
+        }
+
+        assertEquals(expectedIconColor, actualIconColor)
+        assertEquals(expectedAlpha, actualAlpha)
+    }
+
+    private val BorderVerticalMargin = 22.dp
+    private val VerticalMargin = 8.dp
+    private val ButtonWeight = .35f
+    private val DefaultIconHeight = 24.dp
+}
+
+public class IntegerStepperTest {
+    @get:Rule
+    public val rule = createComposeRule()
+
+    @Test
+    public fun supports_testtag() {
+        rule.setContentWithTheme {
+            Stepper(
+                value = 1,
+                onValueChange = {},
+                valueProgression = 0..5,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                modifier = Modifier.testTag(TEST_TAG)
+            ) {}
+        }
+
+        rule.onNodeWithTag(TEST_TAG).assertExists()
+    }
+
+    @Test
+    public fun coerces_value_top_limit() = rule.setNewValueAndCheck(
+        progression = 0..10,
+        initialValue = 4,
+        newValue = 20,
+        expectedFinalValue = 10
+    )
+
+    @Test
+    public fun coerces_value_lower_limit() = rule.setNewValueAndCheck(
+        progression = 0..10,
+        initialValue = 4,
+        newValue = -20,
+        expectedFinalValue = 0
+    )
+
+    @Test
+    public fun coerce_value_exactly() = rule.setNewValueAndCheck(
+        progression = IntProgression.fromClosedRange(0, 12, 3),
+        initialValue = 0,
+        newValue = 3,
+        expectedFinalValue = 3
+    )
+
+    @Test
+    public fun coerce_value_to_previous() = rule.setNewValueAndCheck(
+        progression = IntProgression.fromClosedRange(0, 12, 3),
+        initialValue = 0,
+        newValue = 4,
+        expectedFinalValue = 3
+    )
+
+    @Test
+    public fun coerce_value_to_next() = rule.setNewValueAndCheck(
+        progression = IntProgression.fromClosedRange(0, 12, 3),
+        initialValue = 0,
+        newValue = 5,
+        expectedFinalValue = 6
+    )
+
+    @Test(expected = java.lang.AssertionError::class)
+    fun does_not_support_stepper_range_semantics_by_default() {
+        val value = 1
+        val valueProgression = 0..10
+
+        rule.setContentWithTheme {
+            Stepper(
+                value = value,
+                onValueChange = {},
+                valueProgression = valueProgression,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                modifier = Modifier.testTag(TEST_TAG)
+            ) {}
+        }
+        rule.waitForIdle()
+        // Should throw assertion error for assertRangeInfoEquals
+        rule.onNodeWithTag(TEST_TAG, true)
+            .assertExists()
+            .assertRangeInfoEquals(
+                ProgressBarRangeInfo(
+                    value.toFloat(),
+                    valueProgression.first.toFloat()..valueProgression.last.toFloat(),
+                    valueProgression.stepsNumber()
+                )
+            )
+    }
+
+    @Test()
+    fun enable_stepper_semantics_using_modifier() {
+        val value = 1
+        val valueProgression = 0..10
+
+        rule.setContentWithTheme {
+            Stepper(
+                value = value,
+                onValueChange = {},
+                valueProgression = valueProgression,
+                increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+                decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+                modifier = Modifier
+                    .testTag(TEST_TAG)
+                    .rangeSemantics(
+                        value.toFloat(),
+                        true, {},
+                        valueProgression.first.toFloat()..valueProgression.last.toFloat(),
+                        valueProgression.stepsNumber()
+                    )
+            ) {}
+        }
+        rule.waitForIdle()
+
+        rule.onNodeWithTag(TEST_TAG, true)
+            .assertExists()
+            .assertRangeInfoEquals(
+                ProgressBarRangeInfo(
+                    value.toFloat(),
+                    valueProgression.first.toFloat()..valueProgression.last.toFloat(),
+                    valueProgression.stepsNumber()
+                )
+            )
+    }
+}
+
+private fun ComposeContentTestRule.setNewValueAndCheck(
+    range: ClosedFloatingPointRange<Float>,
+    steps: Int,
+    initialValue: Float,
+    newValue: Float,
+    expectedFinalValue: Float
+) {
+    val state = mutableStateOf(initialValue)
+
+    initDefaultStepper(state, range, steps)
+
+    runOnIdle { state.value = newValue }
+    onNodeWithTag(TEST_TAG, true)
+        .assertRangeInfoEquals(ProgressBarRangeInfo(expectedFinalValue, range, steps))
+
+    // State value is not coerced to expectedValue - thus we expect it to be equal to
+    // the last set value, which is newValue
+    waitForIdle()
+    assertEquals(newValue, state.value)
+}
+
+private fun ComposeContentTestRule.initDefaultStepper(
+    state: MutableState<Float>,
+    valueRange: ClosedFloatingPointRange<Float>,
+    steps: Int
+) {
+    val onValueChange: (Float) -> Unit = { state.value = it }
+
+    setContentWithTheme {
+        Stepper(
+            value = state.value,
+            onValueChange = onValueChange,
+            valueRange = valueRange,
+            steps = steps,
+            increaseIcon = { Icon(StepperDefaults.Increase, INCREASE) },
+            decreaseIcon = { Icon(StepperDefaults.Decrease, DECREASE) },
+            modifier = Modifier
+                .testTag(TEST_TAG)
+                .rangeSemantics(state.value, true, onValueChange, valueRange, steps)
+        ) {}
+    }
+}
+
+private fun ComposeContentTestRule.setNewValueAndCheck(
+    progression: IntProgression,
+    initialValue: Int,
+    newValue: Int,
+    expectedFinalValue: Int
+) {
+    val state = mutableStateOf(initialValue)
+
+    initDefaultStepper(state, progression)
+
+    runOnIdle { state.value = newValue }
+    onNodeWithTag(TEST_TAG)
+        .assertRangeInfoEquals(
+            ProgressBarRangeInfo(
+                expectedFinalValue.toFloat(),
+                progression.first.toFloat()..progression.last.toFloat(),
+                progression.stepsNumber()
+            )
+        )
+
+    // State value is not coerced to expectedValue - thus we expect it to be equal to
+    // the last set value, which is newValue
+    waitForIdle()
+    assertEquals(newValue, state.value)
+}
+
+private fun ComposeContentTestRule.initDefaultStepper(
+    state: MutableState<Int>,
+    valueProgression: IntProgression,
+) {
+    val onValueChange: (Int) -> Unit = { state.value = it }
+    val steps = valueProgression.stepsNumber()
+    val valueRange = valueProgression.first.toFloat()..valueProgression.last.toFloat()
+
+    setContentWithTheme {
+        Stepper(
+            value = state.value,
+            onValueChange = onValueChange,
+            valueProgression = valueProgression,
+            increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
+            decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
+            modifier = Modifier
+                .testTag(TEST_TAG)
+                .rangeSemantics(
+                    state.value.toFloat(),
+                    true,
+                    { onValueChange(it.roundToInt()) },
+                    valueRange,
+                    steps
+                )
+        ) {}
+    }
+}
+
+private val INCREASE = "increase"
+private val DECREASE = "decrease"
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
index 5454a04..8ae62c8 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Card.kt
@@ -50,6 +50,9 @@
  *
  * Cards can be enabled or disabled. A disabled card will not respond to click events.
  *
+ * Example of a [Card]:
+ * @sample androidx.wear.compose.material3.samples.CardSample
+ *
  * For more information, see the
  * [Cards](https://developer.android.com/training/wearables/components/cards)
  * Wear OS Material design guide.
@@ -127,6 +130,15 @@
  * If more than one composable is provided in the content slot it is the responsibility of the
  * caller to determine how to layout the contents, e.g. provide either a row or a column.
  *
+ * Example of an [AppCard]:
+ * @sample androidx.wear.compose.material3.samples.AppCardSample
+ *
+ * Example of an [AppCard] with icon:
+ * @sample androidx.wear.compose.material3.samples.AppCardWithIconSample
+ *
+ * Example of an outlined [AppCard]:
+ * @sample androidx.wear.compose.material3.samples.OutlinedAppCardSample
+ *
  * For more information, see the
  * [Cards](https://developer.android.com/training/wearables/components/cards)
  * guide.
@@ -242,6 +254,15 @@
  * If more than one composable is provided in the content slot it is the responsibility of the
  * caller to determine how to layout the contents, e.g. provide either a row or a column.
  *
+ * Example of a [TitleCard]:
+ * @sample androidx.wear.compose.material3.samples.TitleCardSample
+ *
+ * Example of a [TitleCard] with image:
+ * @sample androidx.wear.compose.material3.samples.TitleCardWithImageSample
+ *
+ * Example of an outlined [TitleCard]:
+ * @sample androidx.wear.compose.material3.samples.OutlinedTitleCardSample
+ *
  * For more information, see the
  * [Cards](https://developer.android.com/training/wearables/components/cards)
  * guide.
@@ -333,6 +354,9 @@
  *
  * Cards can be enabled or disabled. A disabled card will not respond to click events.
  *
+ * Example of an [OutlinedCard]:
+ * @sample androidx.wear.compose.material3.samples.OutlinedCardSample
+ *
  * For more information, see the
  * [Cards](https://developer.android.com/training/wearables/components/cards)
  * Wear OS Material design guide.
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/RangeSemantics.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/RangeSemantics.kt
new file mode 100644
index 0000000..c6e3aa8
--- /dev/null
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/RangeSemantics.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.wear.compose.material3
+
+import androidx.compose.foundation.progressSemantics
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.disabled
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.setProgress
+import androidx.wear.compose.materialcore.RangeDefaults
+
+/**
+ * Modifier to add semantics signifying progress of the Stepper/Slider.
+ *
+ * @param value Current value of the ProgressIndicator/Slider. If outside of [valueRange] provided,
+ * value will be coerced to this range. Must not be NaN.
+ * @param enabled If false then semantics will not be added.
+ * @param onValueChange Lambda which updates [value].
+ * @param valueRange Range of values that value can take. Passed [value] will be coerced to this
+ * range.
+ * @param steps If greater than 0, specifies the amounts of discrete values, evenly distributed
+ * between across the whole value range. If 0, any value from the range specified is allowed.
+ * Must not be negative.
+ */
+public fun Modifier.rangeSemantics(
+    value: Float,
+    enabled: Boolean,
+    onValueChange: (Float) -> Unit,
+    valueRange: ClosedFloatingPointRange<Float>,
+    steps: Int
+): Modifier {
+    val step = RangeDefaults.snapValueToStep(value, valueRange, steps)
+    return semantics(mergeDescendants = true) {
+        if (!enabled) disabled()
+        setProgress(
+            action = { targetValue ->
+                val newStepIndex = RangeDefaults.snapValueToStep(targetValue, valueRange, steps)
+                if (step == newStepIndex) {
+                    false
+                } else {
+                    onValueChange(targetValue)
+                    true
+                }
+            }
+        )
+    }.progressSemantics(
+        RangeDefaults.calculateCurrentStepValue(step, steps, valueRange), valueRange, steps
+    )
+}
+
+internal fun IntProgression.stepsNumber(): Int = (last - first) / step - 1
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt
new file mode 100644
index 0000000..a233927
--- /dev/null
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Stepper.kt
@@ -0,0 +1,187 @@
+/*
+ * 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.wear.compose.material3
+
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Add
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import kotlin.math.roundToInt
+
+/**
+ * [Stepper] allows users to make a selection from a range of values.
+ * It's a full-screen control with increase button on the top, decrease button on the bottom and
+ * a slot (expected to have either [Text] or [Button]) in the middle.
+ * Value can be increased and decreased by clicking on the increase and decrease buttons.
+ * Buttons can have custom icons - [decreaseIcon] and [increaseIcon].
+ * Step value is calculated as the difference between min and max values divided by [steps]+1.
+ * Stepper itself doesn't show the current value but can be displayed via the content slot or
+ * [PositionIndicator] if required.
+ * If [value] is not equal to any step value, then it will be coerced to the closest step value.
+ * However, the [value] itself will not be changed and [onValueChange] in this case will
+ * not be triggered.
+ * To add range semantics on Stepper, use [Modifier.rangeSemantics].
+ *
+ * Example of a simple [Stepper]:
+ * @sample androidx.wear.compose.material3.samples.StepperSample
+ *
+ * Example of a [Stepper] with range semantics:
+ * @sample androidx.wear.compose.material3.samples.StepperWithRangeSemanticsSample
+ *
+ * @param value Current value of the Stepper. If outside of [valueRange] provided, value will be
+ * coerced to this range.
+ * @param onValueChange Lambda in which value should be updated
+ * @param steps Specifies the number of discrete values, excluding min and max values, evenly
+ * distributed across the whole value range. Must not be negative. If 0, stepper will have only
+ * min and max values and no steps in between
+ * @param decreaseIcon A slot for an icon which is placed on the decrease (bottom) button
+ * @param increaseIcon A slot for an icon which is placed on the increase (top) button
+ * @param modifier Modifiers for the Stepper layout
+ * @param valueRange Range of values that Stepper value can take. Passed [value] will be coerced to
+ * this range
+ * @param backgroundColor [Color] representing the background color for the stepper.
+ * @param contentColor [Color] representing the color for [content] in the middle.
+ * @param iconColor Icon tint [Color] which used by [increaseIcon] and [decreaseIcon]
+ * that defaults to [contentColor], unless specifically overridden.
+ * @param content Content body for the Stepper.
+ */
+@Composable
+fun Stepper(
+    value: Float,
+    onValueChange: (Float) -> Unit,
+    steps: Int,
+    decreaseIcon: @Composable () -> Unit,
+    increaseIcon: @Composable () -> Unit,
+    modifier: Modifier = Modifier,
+    valueRange: ClosedFloatingPointRange<Float> = 0f..(steps + 1).toFloat(),
+    backgroundColor: Color = MaterialTheme.colorScheme.background,
+    contentColor: Color = MaterialTheme.colorScheme.onSurface,
+    iconColor: Color = contentColor,
+    content: @Composable BoxScope.() -> Unit
+) {
+    androidx.wear.compose.materialcore.Stepper(
+        value = value,
+        onValueChange = onValueChange,
+        steps = steps,
+        decreaseIcon = decreaseIcon,
+        increaseIcon = increaseIcon,
+        valueRange = valueRange,
+        modifier = modifier,
+        backgroundColor = backgroundColor,
+        enabledButtonProviderValues = arrayOf(
+            LocalContentColor provides iconColor,
+            LocalContentAlpha provides iconColor.alpha
+        ),
+        disabledButtonProviderValues = arrayOf(
+            LocalContentColor provides iconColor.copy(alpha = ContentAlpha.disabled),
+            LocalContentAlpha provides iconColor.copy(alpha = ContentAlpha.disabled).alpha
+        )
+    ) {
+        CompositionLocalProvider(
+            LocalContentColor provides contentColor
+        ) {
+            content()
+        }
+    }
+}
+
+/**
+ * [Stepper] allows users to make a selection from a range of values.
+ * It's a full-screen control with increase button on the top, decrease button on the bottom and
+ * a slot (expected to have either [Text] or [Button]) in the middle.
+ * Value can be increased and decreased by clicking on the increase and decrease buttons.
+ * Buttons can have custom icons - [decreaseIcon] and [increaseIcon].
+ * Stepper itself doesn't show the current value but can be displayed via the content slot or
+ * [PositionIndicator] if required.
+ * To add range semantics on Stepper, use [Modifier.rangeSemantics].
+ *
+ * Example of a [Stepper] with integer values:
+ * @sample androidx.wear.compose.material3.samples.StepperWithIntegerSample
+ *
+ * A number of steps is calculated as the difference between max and min values of
+ * [valueProgression] divided by [valueProgression].step - 1.
+ * For example, with a range of 100..120 and a step 5,
+ * number of steps will be (120-100)/ 5 - 1 = 3. Steps are 100(first), 105, 110, 115, 120(last)
+ *
+ * If [valueProgression] range is not equally divisible by [valueProgression].step,
+ * then [valueProgression].last will be adjusted to the closest divisible value in the range.
+ * For example, 1..13 range and a step = 5, steps will be 1(first) , 6 , 11(last)
+ *
+ * If [value] is not equal to any step value, then it will be coerced to the closest step value.
+ * However, the [value] itself will not be changed and [onValueChange] in this case will
+ * not be triggered.
+ *
+ * @param value Current value of the Stepper. If outside of [valueProgression] provided, value will be
+ * coerced to this range.
+ * @param onValueChange Lambda in which value should be updated
+ * @param valueProgression Progression of values that Stepper value can take. Consists of
+ * rangeStart, rangeEnd and step. Range will be equally divided by step size
+ * @param decreaseIcon A slot for an icon which is placed on the decrease (bottom) button
+ * @param increaseIcon A slot for an icon which is placed on the increase (top) button
+ * @param modifier Modifiers for the Stepper layout
+ * @param backgroundColor [Color] representing the background color for the stepper.
+ * @param contentColor [Color] representing the color for [content] in the middle.
+ * @param iconColor Icon tint [Color] which used by [increaseIcon] and [decreaseIcon]
+ * that defaults to [contentColor], unless specifically overridden.
+ * @param content Content body for the Stepper.
+ */
+@Composable
+fun Stepper(
+    value: Int,
+    onValueChange: (Int) -> Unit,
+    valueProgression: IntProgression,
+    decreaseIcon: @Composable () -> Unit,
+    increaseIcon: @Composable () -> Unit,
+    modifier: Modifier = Modifier,
+    backgroundColor: Color = MaterialTheme.colorScheme.background,
+    contentColor: Color = MaterialTheme.colorScheme.onSurface,
+    iconColor: Color = contentColor,
+    content: @Composable BoxScope.() -> Unit
+) {
+    Stepper(
+        value = value.toFloat(),
+        onValueChange = { onValueChange(it.roundToInt()) },
+        steps = valueProgression.stepsNumber(),
+        modifier = modifier,
+        valueRange = valueProgression.first.toFloat()..valueProgression.last.toFloat(),
+        decreaseIcon = decreaseIcon,
+        increaseIcon = increaseIcon,
+        backgroundColor = backgroundColor,
+        contentColor = contentColor,
+        iconColor = iconColor,
+        content = content
+    )
+}
+
+/**
+ * Defaults used by stepper.
+ */
+public object StepperDefaults {
+    /**
+     * Decrease [ImageVector].
+     */
+    public val Decrease = androidx.wear.compose.materialcore.RangeIcons.Minus
+
+    /**
+     * Increase [ImageVector].
+     */
+    public val Increase = Icons.Filled.Add
+}
diff --git a/wear/compose/integration-tests/demos/build.gradle b/wear/compose/integration-tests/demos/build.gradle
index 66e0a8b..fa0c223 100644
--- a/wear/compose/integration-tests/demos/build.gradle
+++ b/wear/compose/integration-tests/demos/build.gradle
@@ -26,8 +26,8 @@
         applicationId "androidx.wear.compose.integration.demos"
         minSdk 25
         targetSdk 30
-        versionCode 14
-        versionName "1.14"
+        versionCode 15
+        versionName "1.15"
         // Change the APK name to match the *testapp regex we use to pick up APKs for testing as
         // part of CI.
         archivesBaseName = "wear-compose-demos-testapp"
diff --git a/wear/compose/integration-tests/demos/lint-baseline.xml b/wear/compose/integration-tests/demos/lint-baseline.xml
new file mode 100644
index 0000000..505db87
--- /dev/null
+++ b/wear/compose/integration-tests/demos/lint-baseline.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta02" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta02)" variant="all" version="8.1.0-beta02">
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in variable &apos;pickerOption&apos; with type Function3&lt;? super PickerScope, ? super Integer, ? super Boolean, ? extends Unit>."
+        errorLine1="        val pickerOption = pickerTextOption(textStyle) { &quot;%02d&quot;.format(it) }"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method pickerGroupItemWithRSB has parameter &apos;option&apos; with type Function3&lt;? super PickerScope, ? super Integer, ? super Boolean, Unit>."
+        errorLine1="    option: @Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method pickerTextOption has parameter &apos;indexToText&apos; with type Function1&lt;? super Integer, String>."
+        errorLine1="private fun pickerTextOption(textStyle: TextStyle, indexToText: (Int) -> String):"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in return type Function3&lt;PickerScope, Integer, Boolean, Unit> of &apos;pickerTextOption&apos;."
+        errorLine1="    (@Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit) = {"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DefaultInlineSlider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Float, Unit>."
+        errorLine1="    onValueChange: (Float) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt"/>
+    </issue>
+
+    <issue
+        id="PrimitiveInLambda"
+        message="Use a functional interface instead of lambda syntax for lambdas with primitive values in method DefaultInlineSlider has parameter &apos;onValueChange&apos; with type Function1&lt;? super Integer, Unit>."
+        errorLine1="    onValueChange: (Int) -> Unit,"
+        errorLine2="                   ~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt"/>
+    </issue>
+
+</issues>
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
index e043c6c..74f1a4c 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PickerDemo.kt
@@ -137,7 +137,6 @@
         }
         val textStyle = MaterialTheme.typography.display3
         val optionColor = MaterialTheme.colors.secondary
-        @Suppress("PrimitiveInLambda")
         val pickerOption = pickerTextOption(textStyle) { "%02d".format(it) }
         val focusRequesterConfirmButton = remember { FocusRequester() }
 
@@ -809,7 +808,6 @@
     contentDescription: String?,
     onSelected: () -> Unit,
     readOnlyLabel: @Composable (BoxScope.() -> Unit)? = null,
-    @Suppress("PrimitiveInLambda")
     option: @Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit
 ) = PickerGroupItem(
     pickerState = pickerState,
@@ -846,12 +844,8 @@
     }
 }
 
-@Suppress("PrimitiveInLambda")
-private fun pickerTextOption(
-    textStyle: TextStyle,
-    @Suppress("PrimitiveInLambda")
-    indexToText: (Int) -> String
-): (@Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit) = {
+private fun pickerTextOption(textStyle: TextStyle, indexToText: (Int) -> String):
+    (@Composable PickerScope.(optionIndex: Int, pickerSelected: Boolean) -> Unit) = {
         value: Int, pickerSelected: Boolean ->
     Box(modifier = Modifier.fillMaxSize()) {
         Text(
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
index 05a25e4..8e038f0 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
@@ -203,7 +203,6 @@
 @Composable
 fun DefaultInlineSlider(
     value: Float,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Float) -> Unit,
     steps: Int,
     modifier: Modifier = Modifier,
@@ -231,7 +230,6 @@
 @Composable
 fun DefaultInlineSlider(
     value: Int,
-    @Suppress("PrimitiveInLambda")
     onValueChange: (Int) -> Unit,
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/1.0.0-beta01.txt b/wear/protolayout/protolayout-expression-pipeline/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..59d2661b
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/api/1.0.0-beta01.txt
@@ -0,0 +1,80 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.expression.pipeline {
+
+  public interface BoundDynamicType extends java.lang.AutoCloseable {
+    method @UiThread public void close();
+    method @UiThread public void startEvaluation();
+  }
+
+  public abstract class DynamicTypeBindingRequest {
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicBool(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Boolean!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicColor(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicDuration(androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Duration!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicFloat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Float!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicInstant(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Instant!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicInt32(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicString(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString, android.icu.util.ULocale, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.String!>);
+  }
+
+  public class DynamicTypeEvaluator {
+    ctor public DynamicTypeEvaluator(androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest) throws androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.EvaluationException;
+  }
+
+  public static final class DynamicTypeEvaluator.Config {
+    method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
+    method @VisibleForTesting public java.util.function.Supplier<java.time.Instant!>? getClock();
+    method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
+    method public androidx.wear.protolayout.expression.pipeline.PlatformTimeUpdateNotifier? getPlatformTimeUpdateNotifier();
+    method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
+  }
+
+  public static final class DynamicTypeEvaluator.Config.Builder {
+    ctor public DynamicTypeEvaluator.Config.Builder();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
+    method @VisibleForTesting public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setClock(java.util.function.Supplier<java.time.Instant!>);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setPlatformTimeUpdateNotifier(androidx.wear.protolayout.expression.pipeline.PlatformTimeUpdateNotifier);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
+  }
+
+  public static class DynamicTypeEvaluator.EvaluationException extends java.lang.Exception {
+    ctor public DynamicTypeEvaluator.EvaluationException(String);
+  }
+
+  public interface DynamicTypeValueReceiver<T> {
+    method public void onData(T);
+    method public void onInvalidated();
+  }
+
+  public interface PlatformDataProvider {
+    method public void clearReceiver();
+    method public void setReceiver(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+  }
+
+  public interface PlatformDataReceiver {
+    method public void onData(androidx.wear.protolayout.expression.PlatformDataValues);
+    method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+  }
+
+  public interface PlatformTimeUpdateNotifier {
+    method public void clearReceiver();
+    method public void setReceiver(java.util.concurrent.Executor, Runnable);
+  }
+
+  public interface QuotaManager {
+    method public void releaseQuota(int);
+    method public boolean tryAcquireQuota(int);
+  }
+
+  public final class StateStore {
+    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+    method public static int getMaxStateEntryCount();
+    method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/protolayout/protolayout-expression-pipeline/api/res-1.0.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/protolayout/protolayout-expression-pipeline/api/res-1.0.0-beta01.txt
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/restricted_1.0.0-beta01.txt b/wear/protolayout/protolayout-expression-pipeline/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..6fb0986
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,82 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.expression.pipeline {
+
+  public interface BoundDynamicType extends java.lang.AutoCloseable {
+    method @UiThread public void close();
+    method @UiThread public void startEvaluation();
+  }
+
+  public abstract class DynamicTypeBindingRequest {
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicBool(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Boolean!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicColor(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicDuration(androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Duration!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicFloat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Float!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicInstant(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.time.Instant!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicInt32(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.Integer!>);
+    method public static androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest forDynamicString(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString, android.icu.util.ULocale, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver<java.lang.String!>);
+  }
+
+  public class DynamicTypeEvaluator {
+    ctor public DynamicTypeEvaluator(androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config);
+    method public androidx.wear.protolayout.expression.pipeline.BoundDynamicType bind(androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest) throws androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.EvaluationException;
+  }
+
+  public static final class DynamicTypeEvaluator.Config {
+    method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
+    method @VisibleForTesting public java.util.function.Supplier<java.time.Instant!>? getClock();
+    method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
+    method public androidx.wear.protolayout.expression.pipeline.PlatformTimeUpdateNotifier? getPlatformTimeUpdateNotifier();
+    method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
+  }
+
+  public static final class DynamicTypeEvaluator.Config.Builder {
+    ctor public DynamicTypeEvaluator.Config.Builder();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
+    method @VisibleForTesting public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setClock(java.util.function.Supplier<java.time.Instant!>);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setPlatformTimeUpdateNotifier(androidx.wear.protolayout.expression.pipeline.PlatformTimeUpdateNotifier);
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
+  }
+
+  public static class DynamicTypeEvaluator.EvaluationException extends java.lang.Exception {
+    ctor public DynamicTypeEvaluator.EvaluationException(String);
+  }
+
+  public interface DynamicTypeValueReceiver<T> {
+    method public void onData(T);
+    method public void onInvalidated();
+  }
+
+  public interface PlatformDataProvider {
+    method public void clearReceiver();
+    method public void setReceiver(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+  }
+
+  public interface PlatformDataReceiver {
+    method public void onData(androidx.wear.protolayout.expression.PlatformDataValues);
+    method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+  }
+
+  public interface PlatformTimeUpdateNotifier {
+    method public void clearReceiver();
+    method public void setReceiver(java.util.concurrent.Executor, Runnable);
+  }
+
+  public interface QuotaManager {
+    method public void releaseQuota(int);
+    method public boolean tryAcquireQuota(int);
+  }
+
+  public final class StateStore {
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public StateStore(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
+    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+    method public static int getMaxStateEntryCount();
+    method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @UiThread public void setAppStateEntryValuesProto(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
+  }
+
+}
+
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformTimeUpdateNotifierImpl.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformTimeUpdateNotifierImpl.java
index 94dac24..991a300 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformTimeUpdateNotifierImpl.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformTimeUpdateNotifierImpl.java
@@ -40,7 +40,7 @@
     @Nullable private Runnable mRegisteredReceiver;
     private final Runnable mNotifyAndSchedule = this::notifyAndScheduleNextSecond;
     private long mLastScheduleTimeMillis = 0;
-    private boolean mUpdatesEnabled = false;
+    private boolean mUpdatesEnabled = true;
     @Nullable private Executor mRegisteredExecutor;
 
     @Override
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/InstantNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/InstantNodesTest.java
index 6933726..70cc286 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/InstantNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/InstantNodesTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
@@ -26,27 +27,16 @@
 import androidx.wear.protolayout.expression.pipeline.InstantNodes.PlatformTimeSourceNode;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInstant;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
 
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.Executor;
 
 @RunWith(AndroidJUnit4.class)
 public class InstantNodesTest {
-
-    @Rule public final MockitoRule mockito = MockitoJUnit.rule();
-
-    @Captor ArgumentCaptor<Runnable> mReceiverCaptor;
-    @Captor ArgumentCaptor<Executor> mExecutor;
-
     @Test
     public void testFixedInstant() {
         List<Instant> results = new ArrayList<>();
@@ -73,8 +63,9 @@
         node.init();
         assertThat(timeSource.getRegisterConsumersCount()).isEqualTo(1);
 
-        verify(notifier).setReceiver(mExecutor.capture(), mReceiverCaptor.capture());
-        mReceiverCaptor.getValue().run(); // Ticking.
+        ArgumentCaptor<Runnable> receiverCaptor = ArgumentCaptor.forClass(Runnable.class);
+        verify(notifier).setReceiver(any(), receiverCaptor.capture());
+        receiverCaptor.getValue().run(); // Ticking.
         assertThat(results).containsExactly(Instant.ofEpochSecond(1234567L));
 
         node.destroy();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/resources/robolectric.properties b/wear/protolayout/protolayout-expression-pipeline/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/protolayout/protolayout-expression/api/1.0.0-beta01.txt b/wear/protolayout/protolayout-expression/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..1203940
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/api/1.0.0-beta01.txt
@@ -0,0 +1,375 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.expression {
+
+  public final class AnimationParameterBuilders {
+    field public static final int REPEAT_MODE_RESTART = 1; // 0x1
+    field public static final int REPEAT_MODE_REVERSE = 2; // 0x2
+    field public static final int REPEAT_MODE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class AnimationParameterBuilders.AnimationParameters {
+    method @IntRange(from=0) public long getDelayMillis();
+    method @IntRange(from=0) public long getDurationMillis();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
+  }
+
+  public static final class AnimationParameterBuilders.AnimationParameters.Builder {
+    ctor public AnimationParameterBuilders.AnimationParameters.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setDelayMillis(@IntRange(from=0) long);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setDurationMillis(@IntRange(from=0) long);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setEasing(androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing);
+  }
+
+  public static final class AnimationParameterBuilders.AnimationSpec {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
+  }
+
+  public static final class AnimationParameterBuilders.AnimationSpec.Builder {
+    ctor public AnimationParameterBuilders.AnimationSpec.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setAnimationParameters(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
+  }
+
+  public static interface AnimationParameterBuilders.Easing {
+    method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing cubicBezier(float, float, float, float);
+    method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing fromByteArray(byte[]);
+    method public default byte[] toEasingByteArray();
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
+  }
+
+  public static final class AnimationParameterBuilders.Repeatable {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
+    method public int getIterations();
+    method public int getRepeatMode();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
+    method public boolean hasInfiniteIteration();
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
+  }
+
+  public static final class AnimationParameterBuilders.Repeatable.Builder {
+    ctor public AnimationParameterBuilders.Repeatable.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setForwardRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setIterations(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setRepeatMode(int);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+  }
+
+  public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public AppDataKey(String);
+  }
+
+  public class ConditionScopes {
+  }
+
+  public static class ConditionScopes.ConditionScope<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType, RawT> {
+    method public androidx.wear.protolayout.expression.ConditionScopes.IfTrueScope<T!,RawT!> use(RawT!);
+    method public androidx.wear.protolayout.expression.ConditionScopes.IfTrueScope<T!,RawT!> use(T!);
+  }
+
+  public static class ConditionScopes.IfTrueScope<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType, RawT> {
+    method public T! elseUse(RawT!);
+    method public T! elseUse(T!);
+  }
+
+  public final class DynamicBuilders {
+  }
+
+  public static interface DynamicBuilders.DynamicBool extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicBoolByteArray();
+    method public default int toDynamicBoolByteArray(byte[]);
+    method public default int toDynamicBoolByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicColorByteArray();
+    method public default int toDynamicColorByteArray(byte[]);
+    method public default int toDynamicColorByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicDurationByteArray();
+    method public default int toDynamicDurationByteArray(byte[]);
+    method public default int toDynamicDurationByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
+  }
+
+  public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method public default byte[] toDynamicFloatByteArray();
+    method public default int toDynamicFloatByteArray(byte[]);
+    method public default int toDynamicFloatByteArray(byte[], int, int);
+  }
+
+  public static class DynamicBuilders.DynamicFloat.FloatFormatter {
+    method @IntRange(from=0) public int getMaxFractionDigits();
+    method @IntRange(from=0) public int getMinFractionDigits();
+    method @IntRange(from=0) public int getMinIntegerDigits();
+    method public boolean isGroupingUsed();
+  }
+
+  public static final class DynamicBuilders.DynamicFloat.FloatFormatter.Builder {
+    ctor public DynamicBuilders.DynamicFloat.FloatFormatter.Builder();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter build();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+  }
+
+  public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method public default byte[] toDynamicInstantByteArray();
+    method public default int toDynamicInstantByteArray(byte[]);
+    method public default int toDynamicInstantByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+  }
+
+  public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
+    method public default byte[] toDynamicInt32ByteArray();
+    method public default int toDynamicInt32ByteArray(byte[]);
+    method public default int toDynamicInt32ByteArray(byte[], int, int);
+  }
+
+  public static class DynamicBuilders.DynamicInt32.IntFormatter {
+    method @IntRange(from=0) public int getMinIntegerDigits();
+    method public boolean isGroupingUsed();
+  }
+
+  public static final class DynamicBuilders.DynamicInt32.IntFormatter.Builder {
+    ctor public DynamicBuilders.DynamicInt32.IntFormatter.Builder();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter build();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+  }
+
+  public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicStringByteArray();
+    method public default int toDynamicStringByteArray(byte[]);
+    method public default int toDynamicStringByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicType {
+  }
+
+  public final class DynamicDataBuilders {
+  }
+
+  public static interface DynamicDataBuilders.DynamicDataValue<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
+    method public default byte[] toDynamicDataValueByteArray();
+    method public default int toDynamicDataValueByteArray(byte[]);
+    method public default int toDynamicDataValueByteArray(byte[], int, int);
+  }
+
+  public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public String getKey();
+    method public String getNamespace();
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ExperimentalProtoLayoutExtensionApi {
+  }
+
+  public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public PlatformDataKey(String, String);
+  }
+
+  public final class PlatformDataValues {
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getAll();
+    method public static <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.expression.PlatformDataValues of(androidx.wear.protolayout.expression.PlatformDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+  }
+
+  public static final class PlatformDataValues.Builder {
+    ctor public PlatformDataValues.Builder();
+    method public androidx.wear.protolayout.expression.PlatformDataValues build();
+    method public <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.expression.PlatformDataValues.Builder put(androidx.wear.protolayout.expression.PlatformDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+  }
+
+  public class PlatformHealthSources {
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    field public static final int HEART_RATE_ACCURACY_HIGH = 5; // 0x5
+    field public static final int HEART_RATE_ACCURACY_LOW = 3; // 0x3
+    field public static final int HEART_RATE_ACCURACY_MEDIUM = 4; // 0x4
+    field public static final int HEART_RATE_ACCURACY_NO_CONTACT = 1; // 0x1
+    field public static final int HEART_RATE_ACCURACY_UNKNOWN = 0; // 0x0
+    field public static final int HEART_RATE_ACCURACY_UNRELIABLE = 2; // 0x2
+  }
+
+  public static final class PlatformHealthSources.DynamicHeartRateAccuracy implements androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 {
+    method public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
+  }
+
+  public static class PlatformHealthSources.Keys {
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_CALORIES;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_DISTANCE_METERS;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_FLOORS;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> HEART_RATE_ACCURACY;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ProtoLayoutExperimental {
+  }
+
+  public final class VersionBuilders {
+  }
+
+  public static final class VersionBuilders.VersionInfo {
+    method public int getMajor();
+    method public int getMinor();
+  }
+
+  public static final class VersionBuilders.VersionInfo.Builder {
+    ctor public VersionBuilders.VersionInfo.Builder();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo build();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo.Builder setMajor(int);
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo.Builder setMinor(int);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/protolayout/protolayout-expression/api/res-1.0.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/protolayout/protolayout-expression/api/res-1.0.0-beta01.txt
diff --git a/wear/protolayout/protolayout-expression/api/restricted_1.0.0-beta01.txt b/wear/protolayout/protolayout-expression/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..1203940
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,375 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.expression {
+
+  public final class AnimationParameterBuilders {
+    field public static final int REPEAT_MODE_RESTART = 1; // 0x1
+    field public static final int REPEAT_MODE_REVERSE = 2; // 0x2
+    field public static final int REPEAT_MODE_UNKNOWN = 0; // 0x0
+  }
+
+  public static final class AnimationParameterBuilders.AnimationParameters {
+    method @IntRange(from=0) public long getDelayMillis();
+    method @IntRange(from=0) public long getDurationMillis();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing? getEasing();
+  }
+
+  public static final class AnimationParameterBuilders.AnimationParameters.Builder {
+    ctor public AnimationParameterBuilders.AnimationParameters.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setDelayMillis(@IntRange(from=0) long);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setDurationMillis(@IntRange(from=0) long);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters.Builder setEasing(androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing);
+  }
+
+  public static final class AnimationParameterBuilders.AnimationSpec {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getAnimationParameters();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable? getRepeatable();
+  }
+
+  public static final class AnimationParameterBuilders.AnimationSpec.Builder {
+    ctor public AnimationParameterBuilders.AnimationSpec.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setAnimationParameters(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec.Builder setRepeatable(androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable);
+  }
+
+  public static interface AnimationParameterBuilders.Easing {
+    method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing cubicBezier(float, float, float, float);
+    method public static androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing fromByteArray(byte[]);
+    method public default byte[] toEasingByteArray();
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_LINEAR_IN_EASING;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing FAST_OUT_SLOW_IN_EASING;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Easing LINEAR_OUT_SLOW_IN_EASING;
+  }
+
+  public static final class AnimationParameterBuilders.Repeatable {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getForwardRepeatOverride();
+    method public int getIterations();
+    method public int getRepeatMode();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters? getReverseRepeatOverride();
+    method public boolean hasInfiniteIteration();
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_RESTART;
+    field public static final androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable INFINITE_REPEATABLE_WITH_REVERSE;
+  }
+
+  public static final class AnimationParameterBuilders.Repeatable.Builder {
+    ctor public AnimationParameterBuilders.Repeatable.Builder();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable build();
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setForwardRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setIterations(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setRepeatMode(int);
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
+  }
+
+  public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public AppDataKey(String);
+  }
+
+  public class ConditionScopes {
+  }
+
+  public static class ConditionScopes.ConditionScope<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType, RawT> {
+    method public androidx.wear.protolayout.expression.ConditionScopes.IfTrueScope<T!,RawT!> use(RawT!);
+    method public androidx.wear.protolayout.expression.ConditionScopes.IfTrueScope<T!,RawT!> use(T!);
+  }
+
+  public static class ConditionScopes.IfTrueScope<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType, RawT> {
+    method public T! elseUse(RawT!);
+    method public T! elseUse(T!);
+  }
+
+  public final class DynamicBuilders {
+  }
+
+  public static interface DynamicBuilders.DynamicBool extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicBoolByteArray();
+    method public default int toDynamicBoolByteArray(byte[]);
+    method public default int toDynamicBoolByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicColorByteArray();
+    method public default int toDynamicColorByteArray(byte[]);
+    method public default int toDynamicColorByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicDuration extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getHoursPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getIntDaysPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getMinutesPart();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 getSecondsPart();
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration!,java.time.Duration!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicDurationByteArray();
+    method public default int toDynamicDurationByteArray(byte[]);
+    method public default int toDynamicDurationByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntDays();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntHours();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntMinutes();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 toIntSeconds();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration withSecondsPrecision(java.time.Duration);
+  }
+
+  public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat constant(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(float);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!,java.lang.Float!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method public default byte[] toDynamicFloatByteArray();
+    method public default int toDynamicFloatByteArray(byte[]);
+    method public default int toDynamicFloatByteArray(byte[], int, int);
+  }
+
+  public static class DynamicBuilders.DynamicFloat.FloatFormatter {
+    method @IntRange(from=0) public int getMaxFractionDigits();
+    method @IntRange(from=0) public int getMinFractionDigits();
+    method @IntRange(from=0) public int getMinIntegerDigits();
+    method public boolean isGroupingUsed();
+  }
+
+  public static final class DynamicBuilders.DynamicFloat.FloatFormatter.Builder {
+    ctor public DynamicBuilders.DynamicFloat.FloatFormatter.Builder();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter build();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setGroupingUsed(boolean);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMaxFractionDigits(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinFractionDigits(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+  }
+
+  public static interface DynamicBuilders.DynamicInstant extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicDuration durationUntil(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant!,java.time.Instant!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant platformTimeWithSecondsPrecision();
+    method public default byte[] toDynamicInstantByteArray();
+    method public default int toDynamicInstantByteArray(byte[]);
+    method public default int toDynamicInstantByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant withSecondsPrecision(java.time.Instant);
+  }
+
+  public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 constant(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat div(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 div(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[], int, int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lt(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool lte(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat minus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 minus(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat plus(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 plus(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat rem(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 rem(int);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat times(float);
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 times(int);
+    method public default byte[] toDynamicInt32ByteArray();
+    method public default int toDynamicInt32ByteArray(byte[]);
+    method public default int toDynamicInt32ByteArray(byte[], int, int);
+  }
+
+  public static class DynamicBuilders.DynamicInt32.IntFormatter {
+    method @IntRange(from=0) public int getMinIntegerDigits();
+    method public boolean isGroupingUsed();
+  }
+
+  public static final class DynamicBuilders.DynamicInt32.IntFormatter.Builder {
+    ctor public DynamicBuilders.DynamicInt32.IntFormatter.Builder();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter build();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setGroupingUsed(boolean);
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter.Builder setMinIntegerDigits(@IntRange(from=0) int);
+  }
+
+  public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
+    method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public default byte[] toDynamicStringByteArray();
+    method public default int toDynamicStringByteArray(byte[]);
+    method public default int toDynamicStringByteArray(byte[], int, int);
+  }
+
+  public static interface DynamicBuilders.DynamicType {
+  }
+
+  public final class DynamicDataBuilders {
+  }
+
+  public static interface DynamicDataBuilders.DynamicDataValue<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!> fromBool(boolean);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?> fromByteArray(byte[], int, int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!> fromColor(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> fromFloat(float);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> fromInt(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!> fromString(String);
+    method public default byte[] toDynamicDataValueByteArray();
+    method public default int toDynamicDataValueByteArray(byte[]);
+    method public default int toDynamicDataValueByteArray(byte[], int, int);
+  }
+
+  public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public String getKey();
+    method public String getNamespace();
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ExperimentalProtoLayoutExtensionApi {
+  }
+
+  public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public PlatformDataKey(String, String);
+  }
+
+  public final class PlatformDataValues {
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getAll();
+    method public static <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.expression.PlatformDataValues of(androidx.wear.protolayout.expression.PlatformDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+  }
+
+  public static final class PlatformDataValues.Builder {
+    ctor public PlatformDataValues.Builder();
+    method public androidx.wear.protolayout.expression.PlatformDataValues build();
+    method public <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.expression.PlatformDataValues.Builder put(androidx.wear.protolayout.expression.PlatformDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+  }
+
+  public class PlatformHealthSources {
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyCalories();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyDistanceMeters();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat dailyFloors();
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy heartRateAccuracy();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    field public static final int HEART_RATE_ACCURACY_HIGH = 5; // 0x5
+    field public static final int HEART_RATE_ACCURACY_LOW = 3; // 0x3
+    field public static final int HEART_RATE_ACCURACY_MEDIUM = 4; // 0x4
+    field public static final int HEART_RATE_ACCURACY_NO_CONTACT = 1; // 0x1
+    field public static final int HEART_RATE_ACCURACY_UNKNOWN = 0; // 0x0
+    field public static final int HEART_RATE_ACCURACY_UNRELIABLE = 2; // 0x2
+  }
+
+  public static final class PlatformHealthSources.DynamicHeartRateAccuracy implements androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 {
+    method public static androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy constant(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> dynamicDataValueOf(int);
+  }
+
+  public static class PlatformHealthSources.Keys {
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_CALORIES;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_DISTANCE_METERS;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> DAILY_FLOORS;
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.PlatformHealthSources.DynamicHeartRateAccuracy!> HEART_RATE_ACCURACY;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ProtoLayoutExperimental {
+  }
+
+  public final class VersionBuilders {
+  }
+
+  public static final class VersionBuilders.VersionInfo {
+    method public int getMajor();
+    method public int getMinor();
+  }
+
+  public static final class VersionBuilders.VersionInfo.Builder {
+    ctor public VersionBuilders.VersionInfo.Builder();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo build();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo.Builder setMajor(int);
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo.Builder setMinor(int);
+  }
+
+}
+
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
index ff1bc0f..a8030ad 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
@@ -127,7 +127,7 @@
                                 .toString())
                 .isEqualTo(
                         "Int32FormatOp{input=FixedInt32{value=1}, minIntegerDigits=2,"
-                            + " groupingUsed=true}");
+                                + " groupingUsed=true}");
     }
 
     @Test
diff --git a/wear/protolayout/protolayout-expression/src/test/resources/robolectric.properties b/wear/protolayout/protolayout-expression/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/protolayout/protolayout-material/api/1.0.0-beta01.txt b/wear/protolayout/protolayout-material/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..4f36b35
--- /dev/null
+++ b/wear/protolayout/protolayout-material/api/1.0.0-beta01.txt
@@ -0,0 +1,320 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.material {
+
+  public class Button implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Button? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ButtonColors getButtonColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method public String? getIconContent();
+    method public String? getImageContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getSize();
+    method public String? getTextContent();
+  }
+
+  public static final class Button.Builder {
+    ctor public Button.Builder(android.content.Context, androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method public androidx.wear.protolayout.material.Button build();
+    method public androidx.wear.protolayout.material.Button.Builder setButtonColors(androidx.wear.protolayout.material.ButtonColors);
+    method public androidx.wear.protolayout.material.Button.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.Button.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.Button.Builder setCustomContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.Button.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setIconContent(String, androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.Button.Builder setImageContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.Button.Builder setSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.material.Button.Builder setTextContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setTextContent(String, int);
+  }
+
+  public class ButtonColors {
+    ctor public ButtonColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ButtonColors(@ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getBackgroundColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getContentColor();
+    method public static androidx.wear.protolayout.material.ButtonColors primaryButtonColors(androidx.wear.protolayout.material.Colors);
+    method public static androidx.wear.protolayout.material.ButtonColors secondaryButtonColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ButtonDefaults {
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp recommendedIconSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp recommendedIconSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_SIZE;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp EXTRA_LARGE_SIZE;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp LARGE_SIZE;
+    field public static final androidx.wear.protolayout.material.ButtonColors PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ButtonColors SECONDARY_COLORS;
+  }
+
+  public class Chip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Chip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getHeight();
+    method public int getHorizontalAlignment();
+    method public String? getIconContent();
+    method public String? getPrimaryLabelContent();
+    method public String? getSecondaryLabelContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  public static final class Chip.Builder {
+    ctor public Chip.Builder(android.content.Context, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.Chip build();
+    method public androidx.wear.protolayout.material.Chip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method public androidx.wear.protolayout.material.Chip.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.Chip.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.Chip.Builder setCustomContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.Chip.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.material.Chip.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setPrimaryLabelContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setSecondaryLabelContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.material.Chip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class ChipColors {
+    ctor public ChipColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ChipColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ChipColors(@ColorInt int, @ColorInt int);
+    ctor public ChipColors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getBackgroundColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getContentColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getIconColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getSecondaryContentColor();
+    method public static androidx.wear.protolayout.material.ChipColors primaryChipColors(androidx.wear.protolayout.material.Colors);
+    method public static androidx.wear.protolayout.material.ChipColors secondaryChipColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ChipDefaults {
+    field public static final androidx.wear.protolayout.material.ChipColors COMPACT_PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors COMPACT_SECONDARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors SECONDARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors TITLE_PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors TITLE_SECONDARY_COLORS;
+  }
+
+  public class CircularProgressIndicator implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.CircularProgressIndicator? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ProgressIndicatorColors getCircularProgressIndicatorColors();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getProgress();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getStrokeWidth();
+  }
+
+  public static final class CircularProgressIndicator.Builder {
+    ctor public CircularProgressIndicator.Builder();
+    method public androidx.wear.protolayout.material.CircularProgressIndicator build();
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setCircularProgressIndicatorColors(androidx.wear.protolayout.material.ProgressIndicatorColors);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setEndAngle(float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setProgress(androidx.wear.protolayout.TypeBuilders.FloatProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setProgress(@FloatRange(from=0, to=1) float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStartAngle(float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStrokeWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStrokeWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class Colors {
+    ctor public Colors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @ColorInt public int getOnPrimary();
+    method @ColorInt public int getOnSurface();
+    method @ColorInt public int getPrimary();
+    method @ColorInt public int getSurface();
+    field public static final androidx.wear.protolayout.material.Colors DEFAULT;
+  }
+
+  public class CompactChip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.CompactChip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public String? getIconContent();
+    method public String getText();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+  }
+
+  public static final class CompactChip.Builder {
+    ctor public CompactChip.Builder(android.content.Context, String, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.CompactChip build();
+    method public androidx.wear.protolayout.material.CompactChip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.CompactChip.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.CompactChip.Builder setIconContent(String);
+  }
+
+  public class ProgressIndicatorColors {
+    ctor public ProgressIndicatorColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ProgressIndicatorColors(@ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getIndicatorColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getTrackColor();
+    method public static androidx.wear.protolayout.material.ProgressIndicatorColors progressIndicatorColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ProgressIndicatorDefaults {
+    field public static final androidx.wear.protolayout.material.ProgressIndicatorColors DEFAULT_COLORS;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_STROKE_WIDTH;
+    field public static final float GAP_END_ANGLE = 156.1f;
+    field public static final float GAP_START_ANGLE = -156.1f;
+  }
+
+  public class Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Text? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle getFontStyle();
+    method public float getLineHeight();
+    method public int getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers getModifiers();
+    method public int getMultilineAlignment();
+    method public int getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp getText();
+    method public int getWeight();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+    method public boolean isItalic();
+    method public boolean isUnderline();
+  }
+
+  public static final class Text.Builder {
+    ctor public Text.Builder(android.content.Context, androidx.wear.protolayout.TypeBuilders.StringProp, androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint);
+    ctor public Text.Builder(android.content.Context, String);
+    method public androidx.wear.protolayout.material.Text build();
+    method public androidx.wear.protolayout.material.Text.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.Text.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setItalic(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.material.Text.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.material.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.material.Text.Builder setOverflow(int);
+    method public androidx.wear.protolayout.material.Text.Builder setTypography(int);
+    method public androidx.wear.protolayout.material.Text.Builder setUnderline(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setWeight(int);
+  }
+
+  public class TitleChip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.TitleChip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public int getHorizontalAlignment();
+    method public String? getIconContent();
+    method public String getText();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getWidth();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+  }
+
+  public static final class TitleChip.Builder {
+    ctor public TitleChip.Builder(android.content.Context, String, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.TitleChip build();
+    method public androidx.wear.protolayout.material.TitleChip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.TitleChip.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class Typography {
+    field public static final int TYPOGRAPHY_BODY1 = 7; // 0x7
+    field public static final int TYPOGRAPHY_BODY2 = 8; // 0x8
+    field public static final int TYPOGRAPHY_BUTTON = 9; // 0x9
+    field public static final int TYPOGRAPHY_CAPTION1 = 10; // 0xa
+    field public static final int TYPOGRAPHY_CAPTION2 = 11; // 0xb
+    field public static final int TYPOGRAPHY_CAPTION3 = 12; // 0xc
+    field public static final int TYPOGRAPHY_DISPLAY1 = 1; // 0x1
+    field public static final int TYPOGRAPHY_DISPLAY2 = 2; // 0x2
+    field public static final int TYPOGRAPHY_DISPLAY3 = 3; // 0x3
+    field public static final int TYPOGRAPHY_TITLE1 = 4; // 0x4
+    field public static final int TYPOGRAPHY_TITLE2 = 5; // 0x5
+    field public static final int TYPOGRAPHY_TITLE3 = 6; // 0x6
+  }
+
+}
+
+package androidx.wear.protolayout.material.layouts {
+
+  public class EdgeContentLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.EdgeContentLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getEdgeContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+  }
+
+  public static final class EdgeContentLayout.Builder {
+    ctor public EdgeContentLayout.Builder(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout build();
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setEdgeContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setPrimaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setSecondaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+  }
+
+  public class LayoutDefaults {
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_VERTICAL_SPACER_HEIGHT;
+    field public static final float EDGE_CONTENT_LAYOUT_PADDING_ABOVE_MAIN_CONTENT_DP = 6.0f;
+    field public static final float EDGE_CONTENT_LAYOUT_PADDING_BELOW_MAIN_CONTENT_DP = 8.0f;
+    field @Deprecated public static final int MULTI_BUTTON_MAX_NUMBER = 7; // 0x7
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp MULTI_SLOT_LAYOUT_HORIZONTAL_SPACER_WIDTH;
+  }
+
+  public static final class LayoutDefaults.MultiButtonLayoutDefaults {
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_1_BUTTON;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_2_BUTTONS;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_3_PLUS_BUTTONS;
+    field public static final int MAX_BUTTONS = 7; // 0x7
+  }
+
+  public class MultiButtonLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.MultiButtonLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getButtonContents();
+    method public int getFiveButtonDistribution();
+    field public static final int FIVE_BUTTON_DISTRIBUTION_BOTTOM_HEAVY = 2; // 0x2
+    field public static final int FIVE_BUTTON_DISTRIBUTION_TOP_HEAVY = 1; // 0x1
+  }
+
+  public static final class MultiButtonLayout.Builder {
+    ctor public MultiButtonLayout.Builder();
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout.Builder addButtonContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout build();
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout.Builder setFiveButtonDistribution(int);
+  }
+
+  public class MultiSlotLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.MultiSlotLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getHorizontalSpacerWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getSlotContents();
+  }
+
+  public static final class MultiSlotLayout.Builder {
+    ctor public MultiSlotLayout.Builder();
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout.Builder addSlotContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout build();
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout.Builder setHorizontalSpacerWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class PrimaryLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.PrimaryLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryChipContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getVerticalSpacerHeight();
+  }
+
+  public static final class PrimaryLayout.Builder {
+    ctor public PrimaryLayout.Builder(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout build();
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setPrimaryChipContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setPrimaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setSecondaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setVerticalSpacerHeight(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/protolayout/protolayout-material/api/res-1.0.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/protolayout/protolayout-material/api/res-1.0.0-beta01.txt
diff --git a/wear/protolayout/protolayout-material/api/restricted_1.0.0-beta01.txt b/wear/protolayout/protolayout-material/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..4f36b35
--- /dev/null
+++ b/wear/protolayout/protolayout-material/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,320 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.material {
+
+  public class Button implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Button? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ButtonColors getButtonColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method public String? getIconContent();
+    method public String? getImageContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getSize();
+    method public String? getTextContent();
+  }
+
+  public static final class Button.Builder {
+    ctor public Button.Builder(android.content.Context, androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method public androidx.wear.protolayout.material.Button build();
+    method public androidx.wear.protolayout.material.Button.Builder setButtonColors(androidx.wear.protolayout.material.ButtonColors);
+    method public androidx.wear.protolayout.material.Button.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.Button.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.Button.Builder setCustomContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.Button.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setIconContent(String, androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.Button.Builder setImageContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.Button.Builder setSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.material.Button.Builder setTextContent(String);
+    method public androidx.wear.protolayout.material.Button.Builder setTextContent(String, int);
+  }
+
+  public class ButtonColors {
+    ctor public ButtonColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ButtonColors(@ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getBackgroundColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getContentColor();
+    method public static androidx.wear.protolayout.material.ButtonColors primaryButtonColors(androidx.wear.protolayout.material.Colors);
+    method public static androidx.wear.protolayout.material.ButtonColors secondaryButtonColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ButtonDefaults {
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp recommendedIconSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp recommendedIconSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_SIZE;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp EXTRA_LARGE_SIZE;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp LARGE_SIZE;
+    field public static final androidx.wear.protolayout.material.ButtonColors PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ButtonColors SECONDARY_COLORS;
+  }
+
+  public class Chip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Chip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getHeight();
+    method public int getHorizontalAlignment();
+    method public String? getIconContent();
+    method public String? getPrimaryLabelContent();
+    method public String? getSecondaryLabelContent();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  public static final class Chip.Builder {
+    ctor public Chip.Builder(android.content.Context, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.Chip build();
+    method public androidx.wear.protolayout.material.Chip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method public androidx.wear.protolayout.material.Chip.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.Chip.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.Chip.Builder setCustomContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.Chip.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.material.Chip.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setPrimaryLabelContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setSecondaryLabelContent(String);
+    method public androidx.wear.protolayout.material.Chip.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.material.Chip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class ChipColors {
+    ctor public ChipColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ChipColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ChipColors(@ColorInt int, @ColorInt int);
+    ctor public ChipColors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getBackgroundColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getContentColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getIconColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getSecondaryContentColor();
+    method public static androidx.wear.protolayout.material.ChipColors primaryChipColors(androidx.wear.protolayout.material.Colors);
+    method public static androidx.wear.protolayout.material.ChipColors secondaryChipColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ChipDefaults {
+    field public static final androidx.wear.protolayout.material.ChipColors COMPACT_PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors COMPACT_SECONDARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors SECONDARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors TITLE_PRIMARY_COLORS;
+    field public static final androidx.wear.protolayout.material.ChipColors TITLE_SECONDARY_COLORS;
+  }
+
+  public class CircularProgressIndicator implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.CircularProgressIndicator? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ProgressIndicatorColors getCircularProgressIndicatorColors();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getEndAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getProgress();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp getStartAngle();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp getStrokeWidth();
+  }
+
+  public static final class CircularProgressIndicator.Builder {
+    ctor public CircularProgressIndicator.Builder();
+    method public androidx.wear.protolayout.material.CircularProgressIndicator build();
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setCircularProgressIndicatorColors(androidx.wear.protolayout.material.ProgressIndicatorColors);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setContentDescription(CharSequence);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setEndAngle(float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setProgress(androidx.wear.protolayout.TypeBuilders.FloatProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setProgress(@FloatRange(from=0, to=1) float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStartAngle(float);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStrokeWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.material.CircularProgressIndicator.Builder setStrokeWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class Colors {
+    ctor public Colors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @ColorInt public int getOnPrimary();
+    method @ColorInt public int getOnSurface();
+    method @ColorInt public int getPrimary();
+    method @ColorInt public int getSurface();
+    field public static final androidx.wear.protolayout.material.Colors DEFAULT;
+  }
+
+  public class CompactChip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.CompactChip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public String? getIconContent();
+    method public String getText();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+  }
+
+  public static final class CompactChip.Builder {
+    ctor public CompactChip.Builder(android.content.Context, String, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.CompactChip build();
+    method public androidx.wear.protolayout.material.CompactChip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.CompactChip.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.CompactChip.Builder setIconContent(String);
+  }
+
+  public class ProgressIndicatorColors {
+    ctor public ProgressIndicatorColors(androidx.wear.protolayout.ColorBuilders.ColorProp, androidx.wear.protolayout.ColorBuilders.ColorProp);
+    ctor public ProgressIndicatorColors(@ColorInt int, @ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getIndicatorColor();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getTrackColor();
+    method public static androidx.wear.protolayout.material.ProgressIndicatorColors progressIndicatorColors(androidx.wear.protolayout.material.Colors);
+  }
+
+  public class ProgressIndicatorDefaults {
+    field public static final androidx.wear.protolayout.material.ProgressIndicatorColors DEFAULT_COLORS;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_STROKE_WIDTH;
+    field public static final float GAP_END_ANGLE = 156.1f;
+    field public static final float GAP_START_ANGLE = -156.1f;
+  }
+
+  public class Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.Text? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp getColor();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle getFontStyle();
+    method public float getLineHeight();
+    method public int getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers getModifiers();
+    method public int getMultilineAlignment();
+    method public int getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp getText();
+    method public int getWeight();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+    method public boolean isItalic();
+    method public boolean isUnderline();
+  }
+
+  public static final class Text.Builder {
+    ctor public Text.Builder(android.content.Context, androidx.wear.protolayout.TypeBuilders.StringProp, androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint);
+    ctor public Text.Builder(android.content.Context, String);
+    method public androidx.wear.protolayout.material.Text build();
+    method public androidx.wear.protolayout.material.Text.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.Text.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setItalic(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.material.Text.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.material.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.material.Text.Builder setOverflow(int);
+    method public androidx.wear.protolayout.material.Text.Builder setTypography(int);
+    method public androidx.wear.protolayout.material.Text.Builder setUnderline(boolean);
+    method public androidx.wear.protolayout.material.Text.Builder setWeight(int);
+  }
+
+  public class TitleChip implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.TitleChip? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.ChipColors getChipColors();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable getClickable();
+    method public int getHorizontalAlignment();
+    method public String? getIconContent();
+    method public String getText();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension getWidth();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public boolean hasExcludeFontPadding();
+  }
+
+  public static final class TitleChip.Builder {
+    ctor public TitleChip.Builder(android.content.Context, String, androidx.wear.protolayout.ModifiersBuilders.Clickable, androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.TitleChip build();
+    method public androidx.wear.protolayout.material.TitleChip.Builder setChipColors(androidx.wear.protolayout.material.ChipColors);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.material.TitleChip.Builder setExcludeFontPadding(boolean);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setIconContent(String);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.material.TitleChip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class Typography {
+    field public static final int TYPOGRAPHY_BODY1 = 7; // 0x7
+    field public static final int TYPOGRAPHY_BODY2 = 8; // 0x8
+    field public static final int TYPOGRAPHY_BUTTON = 9; // 0x9
+    field public static final int TYPOGRAPHY_CAPTION1 = 10; // 0xa
+    field public static final int TYPOGRAPHY_CAPTION2 = 11; // 0xb
+    field public static final int TYPOGRAPHY_CAPTION3 = 12; // 0xc
+    field public static final int TYPOGRAPHY_DISPLAY1 = 1; // 0x1
+    field public static final int TYPOGRAPHY_DISPLAY2 = 2; // 0x2
+    field public static final int TYPOGRAPHY_DISPLAY3 = 3; // 0x3
+    field public static final int TYPOGRAPHY_TITLE1 = 4; // 0x4
+    field public static final int TYPOGRAPHY_TITLE2 = 5; // 0x5
+    field public static final int TYPOGRAPHY_TITLE3 = 6; // 0x6
+  }
+
+}
+
+package androidx.wear.protolayout.material.layouts {
+
+  public class EdgeContentLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.EdgeContentLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getEdgeContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+  }
+
+  public static final class EdgeContentLayout.Builder {
+    ctor public EdgeContentLayout.Builder(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout build();
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setEdgeContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setPrimaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.EdgeContentLayout.Builder setSecondaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+  }
+
+  public class LayoutDefaults {
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp DEFAULT_VERTICAL_SPACER_HEIGHT;
+    field public static final float EDGE_CONTENT_LAYOUT_PADDING_ABOVE_MAIN_CONTENT_DP = 6.0f;
+    field public static final float EDGE_CONTENT_LAYOUT_PADDING_BELOW_MAIN_CONTENT_DP = 8.0f;
+    field @Deprecated public static final int MULTI_BUTTON_MAX_NUMBER = 7; // 0x7
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp MULTI_SLOT_LAYOUT_HORIZONTAL_SPACER_WIDTH;
+  }
+
+  public static final class LayoutDefaults.MultiButtonLayoutDefaults {
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_1_BUTTON;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_2_BUTTONS;
+    field public static final androidx.wear.protolayout.DimensionBuilders.DpProp BUTTON_SIZE_FOR_3_PLUS_BUTTONS;
+    field public static final int MAX_BUTTONS = 7; // 0x7
+  }
+
+  public class MultiButtonLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.MultiButtonLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getButtonContents();
+    method public int getFiveButtonDistribution();
+    field public static final int FIVE_BUTTON_DISTRIBUTION_BOTTOM_HEAVY = 2; // 0x2
+    field public static final int FIVE_BUTTON_DISTRIBUTION_TOP_HEAVY = 1; // 0x1
+  }
+
+  public static final class MultiButtonLayout.Builder {
+    ctor public MultiButtonLayout.Builder();
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout.Builder addButtonContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout build();
+    method public androidx.wear.protolayout.material.layouts.MultiButtonLayout.Builder setFiveButtonDistribution(int);
+  }
+
+  public class MultiSlotLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.MultiSlotLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getHorizontalSpacerWidth();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getSlotContents();
+  }
+
+  public static final class MultiSlotLayout.Builder {
+    ctor public MultiSlotLayout.Builder();
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout.Builder addSlotContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout build();
+    method public androidx.wear.protolayout.material.layouts.MultiSlotLayout.Builder setHorizontalSpacerWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public class PrimaryLayout implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public static androidx.wear.protolayout.material.layouts.PrimaryLayout? fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryChipContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getVerticalSpacerHeight();
+  }
+
+  public static final class PrimaryLayout.Builder {
+    ctor public PrimaryLayout.Builder(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout build();
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setPrimaryChipContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setPrimaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setSecondaryLabelTextContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.material.layouts.PrimaryLayout.Builder setVerticalSpacerHeight(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+}
+
diff --git a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
index 76834d3..8b4c198 100644
--- a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
+++ b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/MaterialGoldenXLTest.java
@@ -73,6 +73,7 @@
         return (int) ((px - 0.5f) / scale);
     }
 
+    @SuppressWarnings("deprecation")
     @Parameterized.Parameters(name = "{0}")
     public static Collection<Object[]> data() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
index 59f0cb6..3994f03 100644
--- a/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
+++ b/wear/protolayout/protolayout-material/src/androidTest/java/androidx/wear/protolayout/material/layouts/LayoutsGoldenXLTest.java
@@ -73,6 +73,7 @@
         return (int) ((px - 0.5f) / scale);
     }
 
+    @SuppressWarnings("deprecation")
     @Parameterized.Parameters(name = "{0}")
     public static Collection<Object[]> data() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
diff --git a/wear/protolayout/protolayout-material/src/test/resources/robolectric.properties b/wear/protolayout/protolayout-material/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/protolayout/protolayout-material/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/protolayout/protolayout-renderer/api/1.0.0-beta01.txt b/wear/protolayout/protolayout-renderer/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/wear/protolayout/protolayout-renderer/api/1.0.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/protolayout/protolayout-renderer/api/res-1.0.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/protolayout/protolayout-renderer/api/res-1.0.0-beta01.txt
diff --git a/wear/protolayout/protolayout-renderer/api/restricted_1.0.0-beta01.txt b/wear/protolayout/protolayout-renderer/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..e393e1d
--- /dev/null
+++ b/wear/protolayout/protolayout-renderer/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,34 @@
+// Signature format: 4.0
+package androidx.wear.protolayout.renderer.impl {
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class ProtoLayoutViewInstance implements java.lang.AutoCloseable {
+    ctor public ProtoLayoutViewInstance(androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.Config);
+    method public void close() throws java.lang.Exception;
+    method @UiThread public void detach(android.view.ViewGroup);
+    method @UiThread public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> renderAndAttach(androidx.wear.protolayout.proto.LayoutElementProto.Layout, androidx.wear.protolayout.proto.ResourceProto.Resources, android.view.ViewGroup);
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final class ProtoLayoutViewInstance.Config {
+    method public com.google.common.util.concurrent.ListeningExecutorService getBgExecutorService();
+    method public String getClickableIdExtra();
+    method public androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.LoadActionListener getLoadActionListener();
+    method public java.util.Map<androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!,java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>!> getPlatformDataProviders();
+    method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
+    method public android.content.Context getUiContext();
+    method public com.google.common.util.concurrent.ListeningExecutorService getUiExecutorService();
+  }
+
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public static final class ProtoLayoutViewInstance.Config.Builder {
+    ctor public ProtoLayoutViewInstance.Config.Builder(android.content.Context, com.google.common.util.concurrent.ListeningExecutorService, com.google.common.util.concurrent.ListeningExecutorService, String);
+    method public androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, androidx.wear.protolayout.expression.PlatformDataKey<?>!...);
+    method public androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.Config build();
+    method public androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.Config.Builder setLoadActionListener(androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.LoadActionListener);
+    method public androidx.wear.protolayout.renderer.impl.ProtoLayoutViewInstance.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
+  }
+
+  public static interface ProtoLayoutViewInstance.LoadActionListener {
+    method public void onClick(androidx.wear.protolayout.proto.StateProto.State);
+  }
+
+}
+
diff --git a/wear/protolayout/protolayout-renderer/src/test/resources/robolectric.properties b/wear/protolayout/protolayout-renderer/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/protolayout/protolayout-renderer/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/protolayout/protolayout/api/1.0.0-beta01.txt b/wear/protolayout/protolayout/api/1.0.0-beta01.txt
new file mode 100644
index 0000000..4089bc7
--- /dev/null
+++ b/wear/protolayout/protolayout/api/1.0.0-beta01.txt
@@ -0,0 +1,1295 @@
+// Signature format: 4.0
+package androidx.wear.protolayout {
+
+  public final class ActionBuilders {
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidIntExtra intExtra(int);
+    method public static androidx.wear.protolayout.ActionBuilders.LaunchAction launchAction(android.content.ComponentName);
+    method public static androidx.wear.protolayout.ActionBuilders.LaunchAction launchAction(android.content.ComponentName, java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!>);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidLongExtra longExtra(long);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  public static interface ActionBuilders.Action {
+  }
+
+  public static final class ActionBuilders.AndroidActivity {
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
+  }
+
+  public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor public ActionBuilders.AndroidActivity.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.protolayout.ActionBuilders.AndroidExtra);
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public boolean getValue();
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra.Builder {
+    ctor public ActionBuilders.AndroidBooleanExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public double getValue();
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra.Builder {
+    ctor public ActionBuilders.AndroidDoubleExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  public static interface ActionBuilders.AndroidExtra {
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public int getValue();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra.Builder {
+    ctor public ActionBuilders.AndroidIntExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidIntExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public long getValue();
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra.Builder {
+    ctor public ActionBuilders.AndroidLongExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidLongExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public String getValue();
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra.Builder {
+    ctor public ActionBuilders.AndroidStringExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidStringExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  public static final class ActionBuilders.LaunchAction implements androidx.wear.protolayout.ActionBuilders.Action {
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  public static final class ActionBuilders.LaunchAction.Builder {
+    ctor public ActionBuilders.LaunchAction.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.LaunchAction build();
+    method public androidx.wear.protolayout.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.protolayout.ActionBuilders.AndroidActivity);
+  }
+
+  public static final class ActionBuilders.LoadAction implements androidx.wear.protolayout.ActionBuilders.Action {
+    method public androidx.wear.protolayout.StateBuilders.State? getRequestState();
+  }
+
+  public static final class ActionBuilders.LoadAction.Builder {
+    ctor public ActionBuilders.LoadAction.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.LoadAction build();
+    method public androidx.wear.protolayout.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.protolayout.StateBuilders.State);
+  }
+
+  public final class ColorBuilders {
+    method public static androidx.wear.protolayout.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  public static final class ColorBuilders.ColorProp {
+    method @ColorInt public int getArgb();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
+  }
+
+  public static final class ColorBuilders.ColorProp.Builder {
+    ctor @Deprecated public ColorBuilders.ColorProp.Builder();
+    ctor public ColorBuilders.ColorProp.Builder(@ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp build();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor);
+  }
+
+  public final class DeviceParametersBuilders {
+    field public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class DeviceParametersBuilders.Capabilities {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public long getMinimumFreshnessLimitMillis();
+  }
+
+  public static final class DeviceParametersBuilders.Capabilities.Builder {
+    ctor public DeviceParametersBuilders.Capabilities.Builder();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities.Builder setMinimumFreshnessLimitMillis(long);
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getFontScale();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor public DeviceParametersBuilders.DeviceParameters.Builder();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setCapabilities(androidx.wear.protolayout.DeviceParametersBuilders.Capabilities);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setFontScale(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setRendererSchemaVersion(androidx.wear.protolayout.expression.VersionBuilders.VersionInfo);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  public final class DimensionBuilders {
+    method public static androidx.wear.protolayout.DimensionBuilders.DegreesProp degrees(float);
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(float);
+    method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(int);
+    method public static androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp expand();
+    method public static androidx.wear.protolayout.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method public static androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  public static final class DimensionBuilders.AngularLayoutConstraint {
+    method public int getAngularAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.AngularLayoutConstraint.Builder {
+    ctor public DimensionBuilders.AngularLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint.Builder setAngularAlignment(int);
+  }
+
+  public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  public static final class DimensionBuilders.DegreesProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DegreesProp.Builder();
+    ctor public DimensionBuilders.DegreesProp.Builder(float);
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.DpProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ExtensionDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.DpProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DpProp.Builder();
+    ctor public DimensionBuilders.DpProp.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public static final class DimensionBuilders.EmProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.EmProp.Builder {
+    ctor public DimensionBuilders.EmProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension {
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp.Builder {
+    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp.Builder setLayoutWeight(androidx.wear.protolayout.TypeBuilders.FloatProp);
+  }
+
+  @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi public static interface DimensionBuilders.ExtensionDimension {
+  }
+
+  public static final class DimensionBuilders.HorizontalLayoutConstraint {
+    method public int getHorizontalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.HorizontalLayoutConstraint.Builder {
+    ctor public DimensionBuilders.HorizontalLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint.Builder setHorizontalAlignment(int);
+  }
+
+  public static interface DimensionBuilders.ImageDimension {
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ImageDimension {
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp.Builder {
+    ctor public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  public static final class DimensionBuilders.SpProp {
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.SpProp.Builder {
+    ctor public DimensionBuilders.SpProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  public static final class DimensionBuilders.VerticalLayoutConstraint {
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+    method public int getVerticalAlignment();
+  }
+
+  public static final class DimensionBuilders.VerticalLayoutConstraint.Builder {
+    ctor public DimensionBuilders.VerticalLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint.Builder setVerticalAlignment(int);
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp.Builder {
+    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp.Builder setMinimumSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public final class LayoutElementBuilders {
+    field public static final int ANGULAR_ALIGNMENT_CENTER = 2; // 0x2
+    field public static final int ANGULAR_ALIGNMENT_END = 3; // 0x3
+    field public static final int ANGULAR_ALIGNMENT_START = 1; // 0x1
+    field public static final int ANGULAR_ALIGNMENT_UNDEFINED = 0; // 0x0
+    field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field public static final int ARC_ANCHOR_END = 3; // 0x3
+    field public static final int ARC_ANCHOR_START = 1; // 0x1
+    field public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int STROKE_CAP_BUTT = 1; // 0x1
+    field public static final int STROKE_CAP_ROUND = 2; // 0x2
+    field public static final int STROKE_CAP_SQUARE = 3; // 0x3
+    field public static final int STROKE_CAP_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field public static final int TEXT_ALIGN_END = 3; // 0x3
+    field public static final int TEXT_ALIGN_START = 1; // 0x1
+    field public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int TEXT_OVERFLOW_MARQUEE = 3; // 0x3
+    field public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class LayoutElementBuilders.AndroidTextStyle {
+    method public boolean getExcludeFontPadding();
+  }
+
+  public static final class LayoutElementBuilders.AndroidTextStyle.Builder {
+    ctor public LayoutElementBuilders.AndroidTextStyle.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle.Builder setExcludeFontPadding(boolean);
+  }
+
+  public static final class LayoutElementBuilders.Arc implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicAnchorAngle();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  public static final class LayoutElementBuilders.Arc.Builder {
+    ctor public LayoutElementBuilders.Arc.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setLayoutConstraintsForDynamicAnchorAngle(androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter.Builder {
+    ctor public LayoutElementBuilders.ArcAdapter.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  public static final class LayoutElementBuilders.ArcLine implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine.Builder {
+    ctor public LayoutElementBuilders.ArcLine.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setLayoutConstraintsForDynamicLength(androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setStrokeCap(androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setStrokeCap(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer.Builder {
+    ctor public LayoutElementBuilders.ArcSpacer.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcText implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.ArcText.Builder {
+    ctor public LayoutElementBuilders.ArcText.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.Box implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Box.Builder {
+    ctor public LayoutElementBuilders.Box.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor public LayoutElementBuilders.ColorFilter.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.protolayout.ColorBuilders.ColorProp);
+  }
+
+  public static final class LayoutElementBuilders.Column implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Column.Builder {
+    ctor public LayoutElementBuilders.Column.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi public static final class LayoutElementBuilders.ExtensionLayoutElement implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public String getExtensionId();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
+    method public byte[] getPayload();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.ExtensionLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ExtensionLayoutElement.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setExtensionId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ExtensionDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setPayload(byte[]);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ExtensionDimension);
+  }
+
+  public static final class LayoutElementBuilders.FontStyle {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor public LayoutElementBuilders.FontStyle.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.protolayout.DimensionBuilders.EmProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyles {
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class LayoutElementBuilders.FontVariantProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontVariantProp.Builder {
+    ctor public LayoutElementBuilders.FontVariantProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor public LayoutElementBuilders.FontWeightProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Image implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Image.Builder {
+    ctor public LayoutElementBuilders.Image.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setColorFilter(androidx.wear.protolayout.LayoutElementBuilders.ColorFilter);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ImageDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ImageDimension);
+  }
+
+  public static final class LayoutElementBuilders.Layout {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.LayoutElementBuilders.Layout? fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public byte[] toByteArray();
+  }
+
+  public static final class LayoutElementBuilders.Layout.Builder {
+    ctor public LayoutElementBuilders.Layout.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  public static final class LayoutElementBuilders.Row implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Row.Builder {
+    ctor public LayoutElementBuilders.Row.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.Spacer implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Spacer.Builder {
+    ctor public LayoutElementBuilders.Spacer.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.SpacerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setLayoutConstraintsForDynamicHeight(androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setLayoutConstraintsForDynamicWidth(androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.SpacerDimension);
+  }
+
+  public static interface LayoutElementBuilders.Span {
+  }
+
+  public static final class LayoutElementBuilders.SpanImage implements androidx.wear.protolayout.LayoutElementBuilders.Span {
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage.Builder {
+    ctor public LayoutElementBuilders.SpanImage.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.SpanText implements androidx.wear.protolayout.LayoutElementBuilders.Span {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.SpanText.Builder {
+    ctor public LayoutElementBuilders.SpanText.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setAndroidTextStyle(androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Spannable implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  public static final class LayoutElementBuilders.Spannable.Builder {
+    ctor public LayoutElementBuilders.Spannable.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.protolayout.LayoutElementBuilders.Span);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMarqueeIterations(@IntRange(from=0xffffffff) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.protolayout.TypeBuilders.Int32Prop);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  public static final class LayoutElementBuilders.StrokeCapProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.StrokeCapProp.Builder {
+    ctor public LayoutElementBuilders.StrokeCapProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.Text.Builder {
+    ctor public LayoutElementBuilders.Text.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setAndroidTextStyle(androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setLayoutConstraintsForDynamicText(androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMarqueeIterations(@IntRange(from=0xffffffff) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.protolayout.TypeBuilders.Int32Prop);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor public LayoutElementBuilders.TextOverflowProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public final class ModifiersBuilders {
+    field public static final int SEMANTICS_ROLE_BUTTON = 2; // 0x2
+    field public static final int SEMANTICS_ROLE_CHECKBOX = 3; // 0x3
+    field public static final int SEMANTICS_ROLE_IMAGE = 1; // 0x1
+    field public static final int SEMANTICS_ROLE_NONE = 0; // 0x0
+    field public static final int SEMANTICS_ROLE_RADIOBUTTON = 5; // 0x5
+    field public static final int SEMANTICS_ROLE_SWITCH = 4; // 0x4
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_BOTTOM_TO_TOP = 4; // 0x4
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_LEFT_TO_RIGHT = 1; // 0x1
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_RIGHT_TO_LEFT = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_TOP_TO_BOTTOM = 3; // 0x3
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_UNDEFINED = 0; // 0x0
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_TO_INSIDE = 1; // 0x1
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_TO_OUTSIDE = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.AnimatedVisibility {
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
+  }
+
+  public static final class ModifiersBuilders.AnimatedVisibility.Builder {
+    ctor public ModifiersBuilders.AnimatedVisibility.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility build();
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility.Builder setEnterTransition(androidx.wear.protolayout.ModifiersBuilders.EnterTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility.Builder setExitTransition(androidx.wear.protolayout.ModifiersBuilders.ExitTransition);
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor public ModifiersBuilders.ArcModifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Background {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
+  }
+
+  public static final class ModifiersBuilders.Background.Builder {
+    ctor public ModifiersBuilders.Background.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Background.Builder setCorner(androidx.wear.protolayout.ModifiersBuilders.Corner);
+  }
+
+  public static final class ModifiersBuilders.Border {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class ModifiersBuilders.Border.Builder {
+    ctor public ModifiersBuilders.Border.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Border.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Clickable {
+    method public String getId();
+    method public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
+  }
+
+  public static final class ModifiersBuilders.Clickable.Builder {
+    ctor public ModifiersBuilders.Clickable.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable.Builder setId(String);
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.protolayout.ActionBuilders.Action);
+  }
+
+  public static final class ModifiersBuilders.Corner {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
+  }
+
+  public static final class ModifiersBuilders.Corner.Builder {
+    ctor public ModifiersBuilders.Corner.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.DefaultContentTransitions {
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(int);
+  }
+
+  public static final class ModifiersBuilders.ElementMetadata {
+    method public byte[] getTagData();
+  }
+
+  public static final class ModifiersBuilders.ElementMetadata.Builder {
+    ctor public ModifiersBuilders.ElementMetadata.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata.Builder setTagData(byte[]);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.EnterTransition {
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
+  }
+
+  public static final class ModifiersBuilders.EnterTransition.Builder {
+    ctor public ModifiersBuilders.EnterTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition.Builder setFadeIn(androidx.wear.protolayout.ModifiersBuilders.FadeInTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition.Builder setSlideIn(androidx.wear.protolayout.ModifiersBuilders.SlideInTransition);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.ExitTransition {
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
+  }
+
+  public static final class ModifiersBuilders.ExitTransition.Builder {
+    ctor public ModifiersBuilders.ExitTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition.Builder setFadeOut(androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition.Builder setSlideOut(androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.FadeInTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getInitialAlpha();
+  }
+
+  public static final class ModifiersBuilders.FadeInTransition.Builder {
+    ctor public ModifiersBuilders.FadeInTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition.Builder setInitialAlpha(@FloatRange(from=0.0, to=1.0) float);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.FadeOutTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getTargetAlpha();
+  }
+
+  public static final class ModifiersBuilders.FadeOutTransition.Builder {
+    ctor public ModifiersBuilders.FadeOutTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
+  }
+
+  public static final class ModifiersBuilders.Modifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor public ModifiersBuilders.Modifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.protolayout.ModifiersBuilders.Background);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.protolayout.ModifiersBuilders.Border);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setContentUpdateAnimation(androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.protolayout.ModifiersBuilders.ElementMetadata);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.protolayout.ModifiersBuilders.Padding);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Padding {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
+  }
+
+  public static final class ModifiersBuilders.Padding.Builder {
+    ctor public ModifiersBuilders.Padding.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setAll(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setStart(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setTop(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Semantics {
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public int getRole();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
+  }
+
+  public static final class ModifiersBuilders.Semantics.Builder {
+    ctor public ModifiersBuilders.Semantics.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setRole(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setStateDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static interface ModifiersBuilders.SlideBound {
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideInTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
+  }
+
+  public static final class ModifiersBuilders.SlideInTransition.Builder {
+    ctor public ModifiersBuilders.SlideInTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setDirection(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setInitialSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideOutTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
+  }
+
+  public static final class ModifiersBuilders.SlideOutTransition.Builder {
+    ctor public ModifiersBuilders.SlideOutTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setDirection(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideParentBound implements androidx.wear.protolayout.ModifiersBuilders.SlideBound {
+    method public int getSnapTo();
+  }
+
+  public static final class ModifiersBuilders.SlideParentBound.Builder {
+    ctor public ModifiersBuilders.SlideParentBound.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideParentBound build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideParentBound.Builder setSnapTo(int);
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor public ModifiersBuilders.SpanModifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+  }
+
+  public final class ResourceBuilders {
+    field public static final int ANIMATED_IMAGE_FORMAT_AVD = 1; // 0x1
+    field public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+    field public static final int IMAGE_FORMAT_ARGB_8888 = 2; // 0x2
+    field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+  }
+
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setStartTrigger(androidx.wear.protolayout.TriggerBuilders.Trigger);
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setProgress(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  public static final class ResourceBuilders.ImageResource {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  public static final class ResourceBuilders.ImageResource.Builder {
+    ctor public ResourceBuilders.ImageResource.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidSeekableAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.protolayout.ResourceBuilders.InlineImageResource);
+  }
+
+  public static final class ResourceBuilders.InlineImageResource {
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor public ResourceBuilders.InlineImageResource.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource build();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  public static final class ResourceBuilders.Resources {
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
+  }
+
+  public static final class ResourceBuilders.Resources.Builder {
+    ctor public ResourceBuilders.Resources.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.protolayout.ResourceBuilders.ImageResource);
+    method public androidx.wear.protolayout.ResourceBuilders.Resources build();
+    method public androidx.wear.protolayout.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  public final class StateBuilders {
+  }
+
+  public static final class StateBuilders.State {
+    method public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
+    method public String getLastClickableId();
+    method public static int getMaxStateEntryCount();
+  }
+
+  public static final class StateBuilders.State.Builder {
+    ctor public StateBuilders.State.Builder();
+    method public <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+    method public androidx.wear.protolayout.StateBuilders.State build();
+  }
+
+  public final class TimelineBuilders {
+  }
+
+  public static final class TimelineBuilders.TimeInterval {
+    method public long getEndMillis();
+    method public long getStartMillis();
+  }
+
+  public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor public TimelineBuilders.TimeInterval.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval build();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  public static final class TimelineBuilders.Timeline {
+    method public static androidx.wear.protolayout.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  public static final class TimelineBuilders.Timeline.Builder {
+    ctor public TimelineBuilders.Timeline.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.protolayout.TimelineBuilders.TimelineEntry);
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline build();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry {
+    method public static androidx.wear.protolayout.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor public TimelineBuilders.TimelineEntry.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry build();
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.protolayout.LayoutElementBuilders.Layout);
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.protolayout.TimelineBuilders.TimeInterval);
+  }
+
+  public final class TriggerBuilders {
+    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnLoadTrigger();
+  }
+
+  public static interface TriggerBuilders.Trigger {
+  }
+
+  public final class TypeBuilders {
+  }
+
+  public static final class TypeBuilders.BoolProp {
+    method public boolean getValue();
+  }
+
+  public static final class TypeBuilders.BoolProp.Builder {
+    ctor public TypeBuilders.BoolProp.Builder();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp build();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  public static final class TypeBuilders.FloatProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
+  }
+
+  public static final class TypeBuilders.FloatProp.Builder {
+    ctor @Deprecated public TypeBuilders.FloatProp.Builder();
+    ctor public TypeBuilders.FloatProp.Builder(float);
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp build();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  public static final class TypeBuilders.Int32Prop {
+    method public int getValue();
+  }
+
+  public static final class TypeBuilders.Int32Prop.Builder {
+    ctor public TypeBuilders.Int32Prop.Builder();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop build();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  public static final class TypeBuilders.StringLayoutConstraint {
+    method public int getAlignment();
+    method public String getPatternForLayout();
+  }
+
+  public static final class TypeBuilders.StringLayoutConstraint.Builder {
+    ctor public TypeBuilders.StringLayoutConstraint.Builder(String);
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint build();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint.Builder setAlignment(int);
+  }
+
+  public static final class TypeBuilders.StringProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
+    method public String getValue();
+  }
+
+  public static final class TypeBuilders.StringProp.Builder {
+    ctor @Deprecated public TypeBuilders.StringProp.Builder();
+    ctor public TypeBuilders.StringProp.Builder(String);
+    method public androidx.wear.protolayout.TypeBuilders.StringProp build();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method public androidx.wear.protolayout.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/protolayout/protolayout/api/res-1.0.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/protolayout/protolayout/api/res-1.0.0-beta01.txt
diff --git a/wear/protolayout/protolayout/api/restricted_1.0.0-beta01.txt b/wear/protolayout/protolayout/api/restricted_1.0.0-beta01.txt
new file mode 100644
index 0000000..4089bc7
--- /dev/null
+++ b/wear/protolayout/protolayout/api/restricted_1.0.0-beta01.txt
@@ -0,0 +1,1295 @@
+// Signature format: 4.0
+package androidx.wear.protolayout {
+
+  public final class ActionBuilders {
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidIntExtra intExtra(int);
+    method public static androidx.wear.protolayout.ActionBuilders.LaunchAction launchAction(android.content.ComponentName);
+    method public static androidx.wear.protolayout.ActionBuilders.LaunchAction launchAction(android.content.ComponentName, java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!>);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidLongExtra longExtra(long);
+    method public static androidx.wear.protolayout.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  public static interface ActionBuilders.Action {
+  }
+
+  public static final class ActionBuilders.AndroidActivity {
+    method public String getClassName();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method public String getPackageName();
+  }
+
+  public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor public ActionBuilders.AndroidActivity.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.protolayout.ActionBuilders.AndroidExtra);
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public boolean getValue();
+  }
+
+  public static final class ActionBuilders.AndroidBooleanExtra.Builder {
+    ctor public ActionBuilders.AndroidBooleanExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public double getValue();
+  }
+
+  public static final class ActionBuilders.AndroidDoubleExtra.Builder {
+    ctor public ActionBuilders.AndroidDoubleExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  public static interface ActionBuilders.AndroidExtra {
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public int getValue();
+  }
+
+  public static final class ActionBuilders.AndroidIntExtra.Builder {
+    ctor public ActionBuilders.AndroidIntExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidIntExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public long getValue();
+  }
+
+  public static final class ActionBuilders.AndroidLongExtra.Builder {
+    ctor public ActionBuilders.AndroidLongExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidLongExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.protolayout.ActionBuilders.AndroidExtra {
+    method public String getValue();
+  }
+
+  public static final class ActionBuilders.AndroidStringExtra.Builder {
+    ctor public ActionBuilders.AndroidStringExtra.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidStringExtra build();
+    method public androidx.wear.protolayout.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  public static final class ActionBuilders.LaunchAction implements androidx.wear.protolayout.ActionBuilders.Action {
+    method public androidx.wear.protolayout.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  public static final class ActionBuilders.LaunchAction.Builder {
+    ctor public ActionBuilders.LaunchAction.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.LaunchAction build();
+    method public androidx.wear.protolayout.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.protolayout.ActionBuilders.AndroidActivity);
+  }
+
+  public static final class ActionBuilders.LoadAction implements androidx.wear.protolayout.ActionBuilders.Action {
+    method public androidx.wear.protolayout.StateBuilders.State? getRequestState();
+  }
+
+  public static final class ActionBuilders.LoadAction.Builder {
+    ctor public ActionBuilders.LoadAction.Builder();
+    method public androidx.wear.protolayout.ActionBuilders.LoadAction build();
+    method public androidx.wear.protolayout.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.protolayout.StateBuilders.State);
+  }
+
+  public final class ColorBuilders {
+    method public static androidx.wear.protolayout.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  public static final class ColorBuilders.ColorProp {
+    method @ColorInt public int getArgb();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor? getDynamicValue();
+  }
+
+  public static final class ColorBuilders.ColorProp.Builder {
+    ctor @Deprecated public ColorBuilders.ColorProp.Builder();
+    ctor public ColorBuilders.ColorProp.Builder(@ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp build();
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor);
+  }
+
+  public final class DeviceParametersBuilders {
+    field public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class DeviceParametersBuilders.Capabilities {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public long getMinimumFreshnessLimitMillis();
+  }
+
+  public static final class DeviceParametersBuilders.Capabilities.Builder {
+    ctor public DeviceParametersBuilders.Capabilities.Builder();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities.Builder setMinimumFreshnessLimitMillis(long);
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.Capabilities? getCapabilities();
+    method public int getDevicePlatform();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getFontScale();
+    method public androidx.wear.protolayout.expression.VersionBuilders.VersionInfo getRendererSchemaVersion();
+    method @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method public int getScreenShape();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor public DeviceParametersBuilders.DeviceParameters.Builder();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setCapabilities(androidx.wear.protolayout.DeviceParametersBuilders.Capabilities);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setFontScale(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setRendererSchemaVersion(androidx.wear.protolayout.expression.VersionBuilders.VersionInfo);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  public final class DimensionBuilders {
+    method public static androidx.wear.protolayout.DimensionBuilders.DegreesProp degrees(float);
+    method public static androidx.wear.protolayout.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(float);
+    method public static androidx.wear.protolayout.DimensionBuilders.EmProp em(int);
+    method public static androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp expand();
+    method public static androidx.wear.protolayout.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method public static androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  public static final class DimensionBuilders.AngularLayoutConstraint {
+    method public int getAngularAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.AngularLayoutConstraint.Builder {
+    ctor public DimensionBuilders.AngularLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint.Builder setAngularAlignment(int);
+  }
+
+  public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  public static final class DimensionBuilders.DegreesProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DegreesProp.Builder();
+    ctor public DimensionBuilders.DegreesProp.Builder(float);
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.DpProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ExtensionDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension androidx.wear.protolayout.DimensionBuilders.SpacerDimension {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.DpProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DpProp.Builder();
+    ctor public DimensionBuilders.DpProp.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  public static final class DimensionBuilders.EmProp {
+    method public float getValue();
+  }
+
+  public static final class DimensionBuilders.EmProp.Builder {
+    ctor public DimensionBuilders.EmProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension androidx.wear.protolayout.DimensionBuilders.ImageDimension {
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp? getLayoutWeight();
+  }
+
+  public static final class DimensionBuilders.ExpandedDimensionProp.Builder {
+    ctor public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.ExpandedDimensionProp.Builder setLayoutWeight(androidx.wear.protolayout.TypeBuilders.FloatProp);
+  }
+
+  @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi public static interface DimensionBuilders.ExtensionDimension {
+  }
+
+  public static final class DimensionBuilders.HorizontalLayoutConstraint {
+    method public int getHorizontalAlignment();
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.HorizontalLayoutConstraint.Builder {
+    ctor public DimensionBuilders.HorizontalLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint.Builder setHorizontalAlignment(int);
+  }
+
+  public static interface DimensionBuilders.ImageDimension {
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ImageDimension {
+    method @IntRange(from=0) public int getAspectRatioHeight();
+    method @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  public static final class DimensionBuilders.ProportionalDimensionProp.Builder {
+    ctor public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method public androidx.wear.protolayout.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  public static final class DimensionBuilders.SpProp {
+    method @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  public static final class DimensionBuilders.SpProp.Builder {
+    ctor public DimensionBuilders.SpProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  public static final class DimensionBuilders.VerticalLayoutConstraint {
+    method @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+    method public int getVerticalAlignment();
+  }
+
+  public static final class DimensionBuilders.VerticalLayoutConstraint.Builder {
+    ctor public DimensionBuilders.VerticalLayoutConstraint.Builder(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint build();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint.Builder setVerticalAlignment(int);
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.protolayout.DimensionBuilders.ContainerDimension {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getMinimumSize();
+  }
+
+  public static final class DimensionBuilders.WrappedDimensionProp.Builder {
+    ctor public DimensionBuilders.WrappedDimensionProp.Builder();
+    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp build();
+    method public androidx.wear.protolayout.DimensionBuilders.WrappedDimensionProp.Builder setMinimumSize(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public final class LayoutElementBuilders {
+    field public static final int ANGULAR_ALIGNMENT_CENTER = 2; // 0x2
+    field public static final int ANGULAR_ALIGNMENT_END = 3; // 0x3
+    field public static final int ANGULAR_ALIGNMENT_START = 1; // 0x1
+    field public static final int ANGULAR_ALIGNMENT_UNDEFINED = 0; // 0x0
+    field public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field public static final int ARC_ANCHOR_END = 3; // 0x3
+    field public static final int ARC_ANCHOR_START = 1; // 0x1
+    field public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int STROKE_CAP_BUTT = 1; // 0x1
+    field public static final int STROKE_CAP_ROUND = 2; // 0x2
+    field public static final int STROKE_CAP_SQUARE = 3; // 0x3
+    field public static final int STROKE_CAP_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field public static final int TEXT_ALIGN_END = 3; // 0x3
+    field public static final int TEXT_ALIGN_START = 1; // 0x1
+    field public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int TEXT_OVERFLOW_MARQUEE = 3; // 0x3
+    field public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class LayoutElementBuilders.AndroidTextStyle {
+    method public boolean getExcludeFontPadding();
+  }
+
+  public static final class LayoutElementBuilders.AndroidTextStyle.Builder {
+    ctor public LayoutElementBuilders.AndroidTextStyle.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle.Builder setExcludeFontPadding(boolean);
+  }
+
+  public static final class LayoutElementBuilders.Arc implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicAnchorAngle();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  public static final class LayoutElementBuilders.Arc.Builder {
+    ctor public LayoutElementBuilders.Arc.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setLayoutConstraintsForDynamicAnchorAngle(androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getContent();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  public static final class LayoutElementBuilders.ArcAdapter.Builder {
+    ctor public LayoutElementBuilders.ArcAdapter.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  public static final class LayoutElementBuilders.ArcLine implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint? getLayoutConstraintsForDynamicLength();
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp? getStrokeCap();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcLine.Builder {
+    ctor public LayoutElementBuilders.ArcLine.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setLayoutConstraintsForDynamicLength(androidx.wear.protolayout.DimensionBuilders.AngularLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setStrokeCap(androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setStrokeCap(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.DegreesProp? getLength();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getThickness();
+  }
+
+  public static final class LayoutElementBuilders.ArcSpacer.Builder {
+    ctor public LayoutElementBuilders.ArcSpacer.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.protolayout.DimensionBuilders.DegreesProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.ArcText implements androidx.wear.protolayout.LayoutElementBuilders.ArcLayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.ArcText.Builder {
+    ctor public LayoutElementBuilders.ArcText.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.ArcModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.Box implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Box.Builder {
+    ctor public LayoutElementBuilders.Box.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getTint();
+  }
+
+  public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor public LayoutElementBuilders.ColorFilter.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.protolayout.ColorBuilders.ColorProp);
+  }
+
+  public static final class LayoutElementBuilders.Column implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Column.Builder {
+    ctor public LayoutElementBuilders.Column.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  @androidx.wear.protolayout.expression.ExperimentalProtoLayoutExtensionApi public static final class LayoutElementBuilders.ExtensionLayoutElement implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public String getExtensionId();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getHeight();
+    method public byte[] getPayload();
+    method public androidx.wear.protolayout.DimensionBuilders.ExtensionDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.ExtensionLayoutElement.Builder {
+    ctor public LayoutElementBuilders.ExtensionLayoutElement.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setExtensionId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ExtensionDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setPayload(byte[]);
+    method public androidx.wear.protolayout.LayoutElementBuilders.ExtensionLayoutElement.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ExtensionDimension);
+  }
+
+  public static final class LayoutElementBuilders.FontStyle {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getItalic();
+    method public androidx.wear.protolayout.DimensionBuilders.EmProp? getLetterSpacing();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getSize();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getUnderline();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp? getVariant();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor public LayoutElementBuilders.FontStyle.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.protolayout.DimensionBuilders.EmProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setVariant(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyles {
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.protolayout.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class LayoutElementBuilders.FontVariantProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontVariantProp.Builder {
+    ctor public LayoutElementBuilders.FontVariantProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontVariantProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor public LayoutElementBuilders.FontWeightProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Image implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method public androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Image.Builder {
+    ctor public LayoutElementBuilders.Image.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setColorFilter(androidx.wear.protolayout.LayoutElementBuilders.ColorFilter);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.protolayout.LayoutElementBuilders.ContentScaleModeProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ImageDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ImageDimension);
+  }
+
+  public static final class LayoutElementBuilders.Layout {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.LayoutElementBuilders.Layout? fromByteArray(byte[]);
+    method public static androidx.wear.protolayout.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.LayoutElement? getRoot();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public byte[] toByteArray();
+  }
+
+  public static final class LayoutElementBuilders.Layout.Builder {
+    ctor public LayoutElementBuilders.Layout.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+  }
+
+  public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  public static final class LayoutElementBuilders.Row implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.LayoutElement!> getContents();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Row.Builder {
+    ctor public LayoutElementBuilders.Row.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder addContent(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.ContainerDimension);
+  }
+
+  public static final class LayoutElementBuilders.Spacer implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint? getLayoutConstraintsForDynamicHeight();
+    method public androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint? getLayoutConstraintsForDynamicWidth();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.Spacer.Builder {
+    ctor public LayoutElementBuilders.Spacer.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.SpacerDimension);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setLayoutConstraintsForDynamicHeight(androidx.wear.protolayout.DimensionBuilders.VerticalLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setLayoutConstraintsForDynamicWidth(androidx.wear.protolayout.DimensionBuilders.HorizontalLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.SpacerDimension);
+  }
+
+  public static interface LayoutElementBuilders.Span {
+  }
+
+  public static final class LayoutElementBuilders.SpanImage implements androidx.wear.protolayout.LayoutElementBuilders.Span {
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getHeight();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getResourceId();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class LayoutElementBuilders.SpanImage.Builder {
+    ctor public LayoutElementBuilders.SpanImage.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class LayoutElementBuilders.SpanText implements androidx.wear.protolayout.LayoutElementBuilders.Span {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers? getModifiers();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.SpanText.Builder {
+    ctor public LayoutElementBuilders.SpanText.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setAndroidTextStyle(androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.SpanModifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Spannable implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public java.util.List<androidx.wear.protolayout.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  public static final class LayoutElementBuilders.Spannable.Builder {
+    ctor public LayoutElementBuilders.Spannable.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.protolayout.LayoutElementBuilders.Span);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMarqueeIterations(@IntRange(from=0xffffffff) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.protolayout.TypeBuilders.Int32Prop);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.protolayout.LayoutElementBuilders.HorizontalAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  public static final class LayoutElementBuilders.StrokeCapProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.StrokeCapProp.Builder {
+    ctor public LayoutElementBuilders.StrokeCapProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.StrokeCapProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.Text implements androidx.wear.protolayout.LayoutElementBuilders.LayoutElement {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle? getAndroidTextStyle();
+    method public androidx.wear.protolayout.LayoutElementBuilders.FontStyle? getFontStyle();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint? getLayoutConstraintsForDynamicText();
+    method public androidx.wear.protolayout.DimensionBuilders.SpProp? getLineHeight();
+    method @IntRange(from=0xffffffff) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public int getMarqueeIterations();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop? getMaxLines();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers? getModifiers();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getText();
+  }
+
+  public static final class LayoutElementBuilders.Text.Builder {
+    ctor public LayoutElementBuilders.Text.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setAndroidTextStyle(androidx.wear.protolayout.LayoutElementBuilders.AndroidTextStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.protolayout.LayoutElementBuilders.FontStyle);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setLayoutConstraintsForDynamicText(androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.protolayout.DimensionBuilders.SpProp);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMarqueeIterations(@IntRange(from=0xffffffff) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.protolayout.TypeBuilders.Int32Prop);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.protolayout.ModifiersBuilders.Modifiers);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setText(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor public LayoutElementBuilders.TextOverflowProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method public int getValue();
+  }
+
+  public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp build();
+    method public androidx.wear.protolayout.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  public final class ModifiersBuilders {
+    field public static final int SEMANTICS_ROLE_BUTTON = 2; // 0x2
+    field public static final int SEMANTICS_ROLE_CHECKBOX = 3; // 0x3
+    field public static final int SEMANTICS_ROLE_IMAGE = 1; // 0x1
+    field public static final int SEMANTICS_ROLE_NONE = 0; // 0x0
+    field public static final int SEMANTICS_ROLE_RADIOBUTTON = 5; // 0x5
+    field public static final int SEMANTICS_ROLE_SWITCH = 4; // 0x4
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_BOTTOM_TO_TOP = 4; // 0x4
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_LEFT_TO_RIGHT = 1; // 0x1
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_RIGHT_TO_LEFT = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_TOP_TO_BOTTOM = 3; // 0x3
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_DIRECTION_UNDEFINED = 0; // 0x0
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_TO_INSIDE = 1; // 0x1
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_TO_OUTSIDE = 2; // 0x2
+    field @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final int SLIDE_PARENT_SNAP_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.AnimatedVisibility {
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition? getEnterTransition();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition? getExitTransition();
+  }
+
+  public static final class ModifiersBuilders.AnimatedVisibility.Builder {
+    ctor public ModifiersBuilders.AnimatedVisibility.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility build();
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility.Builder setEnterTransition(androidx.wear.protolayout.ModifiersBuilders.EnterTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility.Builder setExitTransition(androidx.wear.protolayout.ModifiersBuilders.ExitTransition);
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor public ModifiersBuilders.ArcModifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method public androidx.wear.protolayout.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Background {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner? getCorner();
+  }
+
+  public static final class ModifiersBuilders.Background.Builder {
+    ctor public ModifiersBuilders.Background.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Background.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Background.Builder setCorner(androidx.wear.protolayout.ModifiersBuilders.Corner);
+  }
+
+  public static final class ModifiersBuilders.Border {
+    method public androidx.wear.protolayout.ColorBuilders.ColorProp? getColor();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getWidth();
+  }
+
+  public static final class ModifiersBuilders.Border.Builder {
+    ctor public ModifiersBuilders.Border.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border.Builder setColor(androidx.wear.protolayout.ColorBuilders.ColorProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Border.Builder setWidth(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Clickable {
+    method public String getId();
+    method public androidx.wear.protolayout.ActionBuilders.Action? getOnClick();
+  }
+
+  public static final class ModifiersBuilders.Clickable.Builder {
+    ctor public ModifiersBuilders.Clickable.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable.Builder setId(String);
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.protolayout.ActionBuilders.Action);
+  }
+
+  public static final class ModifiersBuilders.Corner {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getRadius();
+  }
+
+  public static final class ModifiersBuilders.Corner.Builder {
+    ctor public ModifiersBuilders.Corner.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.DefaultContentTransitions {
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeIn();
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition fadeInSlideIn(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOut();
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition fadeOutSlideOut(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.EnterTransition slideIn(int);
+    method public static androidx.wear.protolayout.ModifiersBuilders.ExitTransition slideOut(int);
+  }
+
+  public static final class ModifiersBuilders.ElementMetadata {
+    method public byte[] getTagData();
+  }
+
+  public static final class ModifiersBuilders.ElementMetadata.Builder {
+    ctor public ModifiersBuilders.ElementMetadata.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata.Builder setTagData(byte[]);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.EnterTransition {
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition? getFadeIn();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition? getSlideIn();
+  }
+
+  public static final class ModifiersBuilders.EnterTransition.Builder {
+    ctor public ModifiersBuilders.EnterTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition.Builder setFadeIn(androidx.wear.protolayout.ModifiersBuilders.FadeInTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.EnterTransition.Builder setSlideIn(androidx.wear.protolayout.ModifiersBuilders.SlideInTransition);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.ExitTransition {
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition? getFadeOut();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition? getSlideOut();
+  }
+
+  public static final class ModifiersBuilders.ExitTransition.Builder {
+    ctor public ModifiersBuilders.ExitTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition.Builder setFadeOut(androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition);
+    method public androidx.wear.protolayout.ModifiersBuilders.ExitTransition.Builder setSlideOut(androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.FadeInTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getInitialAlpha();
+  }
+
+  public static final class ModifiersBuilders.FadeInTransition.Builder {
+    ctor public ModifiersBuilders.FadeInTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeInTransition.Builder setInitialAlpha(@FloatRange(from=0.0, to=1.0) float);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.FadeOutTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method @FloatRange(from=0.0, to=1.0) public float getTargetAlpha();
+  }
+
+  public static final class ModifiersBuilders.FadeOutTransition.Builder {
+    ctor public ModifiersBuilders.FadeOutTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.FadeOutTransition.Builder setTargetAlpha(@FloatRange(from=0.0, to=1.0) float);
+  }
+
+  public static final class ModifiersBuilders.Modifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Background? getBackground();
+    method public androidx.wear.protolayout.ModifiersBuilders.Border? getBorder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility? getContentUpdateAnimation();
+    method public androidx.wear.protolayout.ModifiersBuilders.ElementMetadata? getMetadata();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding? getPadding();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor public ModifiersBuilders.Modifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.protolayout.ModifiersBuilders.Background);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.protolayout.ModifiersBuilders.Border);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setContentUpdateAnimation(androidx.wear.protolayout.ModifiersBuilders.AnimatedVisibility);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.protolayout.ModifiersBuilders.ElementMetadata);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.protolayout.ModifiersBuilders.Padding);
+    method public androidx.wear.protolayout.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.protolayout.ModifiersBuilders.Semantics);
+  }
+
+  public static final class ModifiersBuilders.Padding {
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getBottom();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getEnd();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp? getRtlAware();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getStart();
+    method public androidx.wear.protolayout.DimensionBuilders.DpProp? getTop();
+  }
+
+  public static final class ModifiersBuilders.Padding.Builder {
+    ctor public ModifiersBuilders.Padding.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setAll(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.protolayout.TypeBuilders.BoolProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setStart(androidx.wear.protolayout.DimensionBuilders.DpProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Padding.Builder setTop(androidx.wear.protolayout.DimensionBuilders.DpProp);
+  }
+
+  public static final class ModifiersBuilders.Semantics {
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getContentDescription();
+    method public int getRole();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp? getStateDescription();
+  }
+
+  public static final class ModifiersBuilders.Semantics.Builder {
+    ctor public ModifiersBuilders.Semantics.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics build();
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setContentDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setRole(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.Semantics.Builder setStateDescription(androidx.wear.protolayout.TypeBuilders.StringProp);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static interface ModifiersBuilders.SlideBound {
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideInTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getInitialSlideBound();
+  }
+
+  public static final class ModifiersBuilders.SlideInTransition.Builder {
+    ctor public ModifiersBuilders.SlideInTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setDirection(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideInTransition.Builder setInitialSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideOutTransition {
+    method public androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec? getAnimationSpec();
+    method public int getDirection();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideBound? getTargetSlideBound();
+  }
+
+  public static final class ModifiersBuilders.SlideOutTransition.Builder {
+    ctor public ModifiersBuilders.SlideOutTransition.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setAnimationSpec(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setDirection(int);
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideOutTransition.Builder setTargetSlideBound(androidx.wear.protolayout.ModifiersBuilders.SlideBound);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ModifiersBuilders.SlideParentBound implements androidx.wear.protolayout.ModifiersBuilders.SlideBound {
+    method public int getSnapTo();
+  }
+
+  public static final class ModifiersBuilders.SlideParentBound.Builder {
+    ctor public ModifiersBuilders.SlideParentBound.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideParentBound build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SlideParentBound.Builder setSnapTo(int);
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers {
+    method public androidx.wear.protolayout.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor public ModifiersBuilders.SpanModifiers.Builder();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers build();
+    method public androidx.wear.protolayout.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.protolayout.ModifiersBuilders.Clickable);
+  }
+
+  public final class ResourceBuilders {
+    field public static final int ANIMATED_IMAGE_FORMAT_AVD = 1; // 0x1
+    field public static final int ANIMATED_IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+    field public static final int IMAGE_FORMAT_ARGB_8888 = 2; // 0x2
+    field public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method @DrawableRes public int getResourceId();
+    method public androidx.wear.protolayout.TriggerBuilders.Trigger? getStartTrigger();
+  }
+
+  public static final class ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId.Builder setStartTrigger(androidx.wear.protolayout.TriggerBuilders.Trigger);
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId {
+    method public int getAnimatedImageFormat();
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getProgress();
+    method @DrawableRes public int getResourceId();
+  }
+
+  public static final class ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder {
+    ctor public ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId build();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setAnimatedImageFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setProgress(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  public static final class ResourceBuilders.ImageResource {
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId? getAndroidAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId? getAndroidSeekableAnimatedResourceByResId();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  public static final class ResourceBuilders.ImageResource.Builder {
+    ctor public ResourceBuilders.ImageResource.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource build();
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidAnimatedImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidImageResourceByResId);
+    method @androidx.wear.protolayout.expression.ProtoLayoutExperimental public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setAndroidSeekableAnimatedResourceByResId(androidx.wear.protolayout.ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId);
+    method public androidx.wear.protolayout.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.protolayout.ResourceBuilders.InlineImageResource);
+  }
+
+  public static final class ResourceBuilders.InlineImageResource {
+    method public byte[] getData();
+    method public int getFormat();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor public ResourceBuilders.InlineImageResource.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource build();
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method public androidx.wear.protolayout.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  public static final class ResourceBuilders.Resources {
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method public String getVersion();
+  }
+
+  public static final class ResourceBuilders.Resources.Builder {
+    ctor public ResourceBuilders.Resources.Builder();
+    method public androidx.wear.protolayout.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.protolayout.ResourceBuilders.ImageResource);
+    method public androidx.wear.protolayout.ResourceBuilders.Resources build();
+    method public androidx.wear.protolayout.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  public final class StateBuilders {
+  }
+
+  public static final class StateBuilders.State {
+    method public java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!> getKeyToValueMapping();
+    method public String getLastClickableId();
+    method public static int getMaxStateEntryCount();
+  }
+
+  public static final class StateBuilders.State.Builder {
+    ctor public StateBuilders.State.Builder();
+    method public <T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<T!>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<T!>);
+    method public androidx.wear.protolayout.StateBuilders.State build();
+  }
+
+  public final class TimelineBuilders {
+  }
+
+  public static final class TimelineBuilders.TimeInterval {
+    method public long getEndMillis();
+    method public long getStartMillis();
+  }
+
+  public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor public TimelineBuilders.TimeInterval.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval build();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  public static final class TimelineBuilders.Timeline {
+    method public static androidx.wear.protolayout.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public java.util.List<androidx.wear.protolayout.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  public static final class TimelineBuilders.Timeline.Builder {
+    ctor public TimelineBuilders.Timeline.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.protolayout.TimelineBuilders.TimelineEntry);
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline build();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry {
+    method public static androidx.wear.protolayout.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.protolayout.LayoutElementBuilders.LayoutElement);
+    method public androidx.wear.protolayout.LayoutElementBuilders.Layout? getLayout();
+    method public androidx.wear.protolayout.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor public TimelineBuilders.TimelineEntry.Builder();
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry build();
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.protolayout.LayoutElementBuilders.Layout);
+    method public androidx.wear.protolayout.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.protolayout.TimelineBuilders.TimeInterval);
+  }
+
+  public final class TriggerBuilders {
+    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnConditionMetTrigger(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.TriggerBuilders.Trigger createOnLoadTrigger();
+  }
+
+  public static interface TriggerBuilders.Trigger {
+  }
+
+  public final class TypeBuilders {
+  }
+
+  public static final class TypeBuilders.BoolProp {
+    method public boolean getValue();
+  }
+
+  public static final class TypeBuilders.BoolProp.Builder {
+    ctor public TypeBuilders.BoolProp.Builder();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp build();
+    method public androidx.wear.protolayout.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  public static final class TypeBuilders.FloatProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat? getDynamicValue();
+    method public float getValue();
+  }
+
+  public static final class TypeBuilders.FloatProp.Builder {
+    ctor @Deprecated public TypeBuilders.FloatProp.Builder();
+    ctor public TypeBuilders.FloatProp.Builder(float);
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp build();
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
+    method public androidx.wear.protolayout.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  public static final class TypeBuilders.Int32Prop {
+    method public int getValue();
+  }
+
+  public static final class TypeBuilders.Int32Prop.Builder {
+    ctor public TypeBuilders.Int32Prop.Builder();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop build();
+    method public androidx.wear.protolayout.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  public static final class TypeBuilders.StringLayoutConstraint {
+    method public int getAlignment();
+    method public String getPatternForLayout();
+  }
+
+  public static final class TypeBuilders.StringLayoutConstraint.Builder {
+    ctor public TypeBuilders.StringLayoutConstraint.Builder(String);
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint build();
+    method public androidx.wear.protolayout.TypeBuilders.StringLayoutConstraint.Builder setAlignment(int);
+  }
+
+  public static final class TypeBuilders.StringProp {
+    method public androidx.wear.protolayout.expression.DynamicBuilders.DynamicString? getDynamicValue();
+    method public String getValue();
+  }
+
+  public static final class TypeBuilders.StringProp.Builder {
+    ctor @Deprecated public TypeBuilders.StringProp.Builder();
+    ctor public TypeBuilders.StringProp.Builder(String);
+    method public androidx.wear.protolayout.TypeBuilders.StringProp build();
+    method public androidx.wear.protolayout.TypeBuilders.StringProp.Builder setDynamicValue(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
+    method public androidx.wear.protolayout.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/wear/protolayout/protolayout/src/test/resources/robolectric.properties b/wear/protolayout/protolayout/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/protolayout/protolayout/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/tiles/tiles-material/api/1.2.0-beta01.txt b/wear/tiles/tiles-material/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..85c110b
--- /dev/null
+++ b/wear/tiles/tiles-material/api/1.2.0-beta01.txt
@@ -0,0 +1,298 @@
+// Signature format: 4.0
+package androidx.wear.tiles.material {
+
+  @Deprecated public class Button implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Button? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ButtonColors getButtonColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method @Deprecated public String? getIconContent();
+    method @Deprecated public String? getImageContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getSize();
+    method @Deprecated public String? getTextContent();
+  }
+
+  @Deprecated public static final class Button.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Button.Builder(android.content.Context, androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.material.Button build();
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setButtonColors(androidx.wear.tiles.material.ButtonColors);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setCustomContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setIconContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setIconContent(String, androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setImageContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setSize(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setTextContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setTextContent(String, int);
+  }
+
+  @Deprecated public class ButtonColors {
+    ctor @Deprecated public ButtonColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ButtonColors(@ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getBackgroundColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getContentColor();
+    method @Deprecated public static androidx.wear.tiles.material.ButtonColors primaryButtonColors(androidx.wear.tiles.material.Colors);
+    method @Deprecated public static androidx.wear.tiles.material.ButtonColors secondaryButtonColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ButtonDefaults {
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp recommendedIconSize(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp recommendedIconSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp EXTRA_LARGE_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp LARGE_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.material.ButtonColors PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ButtonColors SECONDARY_COLORS;
+  }
+
+  @Deprecated public class Chip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Chip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getHeight();
+    method @Deprecated public int getHorizontalAlignment();
+    method @Deprecated public String? getIconContent();
+    method @Deprecated public String? getPrimaryLabelContent();
+    method @Deprecated public String? getSecondaryLabelContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  @Deprecated public static final class Chip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Chip.Builder(android.content.Context, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.Chip build();
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setCustomContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setIconContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setPrimaryLabelContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setSecondaryLabelContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class ChipColors {
+    ctor @Deprecated public ChipColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ChipColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ChipColors(@ColorInt int, @ColorInt int);
+    ctor @Deprecated public ChipColors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getBackgroundColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getContentColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getIconColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getSecondaryContentColor();
+    method @Deprecated public static androidx.wear.tiles.material.ChipColors primaryChipColors(androidx.wear.tiles.material.Colors);
+    method @Deprecated public static androidx.wear.tiles.material.ChipColors secondaryChipColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ChipDefaults {
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors COMPACT_PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors COMPACT_SECONDARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors SECONDARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors TITLE_PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors TITLE_SECONDARY_COLORS;
+  }
+
+  @Deprecated public class CircularProgressIndicator implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.CircularProgressIndicator? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ProgressIndicatorColors getCircularProgressIndicatorColors();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getEndAngle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getProgress();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getStartAngle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp getStrokeWidth();
+  }
+
+  @Deprecated public static final class CircularProgressIndicator.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public CircularProgressIndicator.Builder();
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator build();
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setCircularProgressIndicatorColors(androidx.wear.tiles.material.ProgressIndicatorColors);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setEndAngle(float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setProgress(@FloatRange(from=0, to=1) float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStartAngle(float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStrokeWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStrokeWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class Colors {
+    ctor @Deprecated public Colors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @Deprecated @ColorInt public int getOnPrimary();
+    method @Deprecated @ColorInt public int getOnSurface();
+    method @Deprecated @ColorInt public int getPrimary();
+    method @Deprecated @ColorInt public int getSurface();
+    field @Deprecated public static final androidx.wear.tiles.material.Colors DEFAULT;
+  }
+
+  @Deprecated public class CompactChip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.CompactChip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public String getText();
+  }
+
+  @Deprecated public static final class CompactChip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public CompactChip.Builder(android.content.Context, String, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.CompactChip build();
+    method @Deprecated public androidx.wear.tiles.material.CompactChip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+  }
+
+  @Deprecated public class ProgressIndicatorColors {
+    ctor @Deprecated public ProgressIndicatorColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ProgressIndicatorColors(@ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getIndicatorColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getTrackColor();
+    method @Deprecated public static androidx.wear.tiles.material.ProgressIndicatorColors progressIndicatorColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ProgressIndicatorDefaults {
+    field @Deprecated public static final androidx.wear.tiles.material.ProgressIndicatorColors DEFAULT_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_STROKE_WIDTH;
+    field @Deprecated public static final float GAP_END_ANGLE = 156.1f;
+    field @Deprecated public static final float GAP_START_ANGLE = -156.1f;
+  }
+
+  @Deprecated public class Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Text? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getColor();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle getFontStyle();
+    method @Deprecated public float getLineHeight();
+    method @Deprecated public int getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers getModifiers();
+    method @Deprecated public int getMultilineAlignment();
+    method @Deprecated public int getOverflow();
+    method @Deprecated public String getText();
+    method @Deprecated public int getWeight();
+    method @Deprecated public boolean isItalic();
+    method @Deprecated public boolean isUnderline();
+  }
+
+  @Deprecated public static final class Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Text.Builder(android.content.Context, String);
+    method @Deprecated public androidx.wear.tiles.material.Text build();
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setItalic(boolean);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setOverflow(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setTypography(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setUnderline(boolean);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setWeight(int);
+  }
+
+  @Deprecated public class TitleChip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.TitleChip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public int getHorizontalAlignment();
+    method @Deprecated public String getText();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  @Deprecated public static final class TitleChip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public TitleChip.Builder(android.content.Context, String, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip build();
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class Typography {
+    field @Deprecated public static final int TYPOGRAPHY_BODY1 = 7; // 0x7
+    field @Deprecated public static final int TYPOGRAPHY_BODY2 = 8; // 0x8
+    field @Deprecated public static final int TYPOGRAPHY_BUTTON = 9; // 0x9
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION1 = 10; // 0xa
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION2 = 11; // 0xb
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION3 = 12; // 0xc
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY1 = 1; // 0x1
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY2 = 2; // 0x2
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY3 = 3; // 0x3
+    field @Deprecated public static final int TYPOGRAPHY_TITLE1 = 4; // 0x4
+    field @Deprecated public static final int TYPOGRAPHY_TITLE2 = 5; // 0x5
+    field @Deprecated public static final int TYPOGRAPHY_TITLE3 = 6; // 0x6
+  }
+
+}
+
+package androidx.wear.tiles.material.layouts {
+
+  @Deprecated public class EdgeContentLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.EdgeContentLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getEdgeContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+  }
+
+  @Deprecated public static final class EdgeContentLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public EdgeContentLayout.Builder(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setEdgeContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setPrimaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setSecondaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  @Deprecated public class LayoutDefaults {
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_VERTICAL_SPACER_HEIGHT;
+    field @Deprecated public static final float EDGE_CONTENT_LAYOUT_PADDING_ABOVE_MAIN_CONTENT_DP = 6.0f;
+    field @Deprecated public static final float EDGE_CONTENT_LAYOUT_PADDING_BELOW_MAIN_CONTENT_DP = 8.0f;
+    field @Deprecated public static final int MULTI_BUTTON_MAX_NUMBER = 7; // 0x7
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp MULTI_SLOT_LAYOUT_HORIZONTAL_SPACER_WIDTH;
+  }
+
+  @Deprecated public class MultiButtonLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.MultiButtonLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getButtonContents();
+    method @Deprecated public int getFiveButtonDistribution();
+    field @Deprecated public static final int FIVE_BUTTON_DISTRIBUTION_BOTTOM_HEAVY = 2; // 0x2
+    field @Deprecated public static final int FIVE_BUTTON_DISTRIBUTION_TOP_HEAVY = 1; // 0x1
+  }
+
+  @Deprecated public static final class MultiButtonLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public MultiButtonLayout.Builder();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout.Builder addButtonContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout.Builder setFiveButtonDistribution(int);
+  }
+
+  @Deprecated public class MultiSlotLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.MultiSlotLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getHorizontalSpacerWidth();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getSlotContents();
+  }
+
+  @Deprecated public static final class MultiSlotLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public MultiSlotLayout.Builder();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout.Builder addSlotContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout.Builder setHorizontalSpacerWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class PrimaryLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.PrimaryLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryChipContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getVerticalSpacerHeight();
+  }
+
+  @Deprecated public static final class PrimaryLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public PrimaryLayout.Builder(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setPrimaryChipContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setPrimaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setSecondaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setVerticalSpacerHeight(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/tiles/tiles-material/api/res-1.2.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/tiles/tiles-material/api/res-1.2.0-beta01.txt
diff --git a/wear/tiles/tiles-material/api/restricted_1.2.0-beta01.txt b/wear/tiles/tiles-material/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..85c110b
--- /dev/null
+++ b/wear/tiles/tiles-material/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,298 @@
+// Signature format: 4.0
+package androidx.wear.tiles.material {
+
+  @Deprecated public class Button implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Button? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ButtonColors getButtonColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method @Deprecated public String? getIconContent();
+    method @Deprecated public String? getImageContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getSize();
+    method @Deprecated public String? getTextContent();
+  }
+
+  @Deprecated public static final class Button.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Button.Builder(android.content.Context, androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.material.Button build();
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setButtonColors(androidx.wear.tiles.material.ButtonColors);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setCustomContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setIconContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setIconContent(String, androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setImageContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setSize(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setTextContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Button.Builder setTextContent(String, int);
+  }
+
+  @Deprecated public class ButtonColors {
+    ctor @Deprecated public ButtonColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ButtonColors(@ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getBackgroundColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getContentColor();
+    method @Deprecated public static androidx.wear.tiles.material.ButtonColors primaryButtonColors(androidx.wear.tiles.material.Colors);
+    method @Deprecated public static androidx.wear.tiles.material.ButtonColors secondaryButtonColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ButtonDefaults {
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp recommendedIconSize(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp recommendedIconSize(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp EXTRA_LARGE_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp LARGE_SIZE;
+    field @Deprecated public static final androidx.wear.tiles.material.ButtonColors PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ButtonColors SECONDARY_COLORS;
+  }
+
+  @Deprecated public class Chip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Chip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getCustomContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getHeight();
+    method @Deprecated public int getHorizontalAlignment();
+    method @Deprecated public String? getIconContent();
+    method @Deprecated public String? getPrimaryLabelContent();
+    method @Deprecated public String? getSecondaryLabelContent();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  @Deprecated public static final class Chip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Chip.Builder(android.content.Context, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.Chip build();
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setCustomContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setIconContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setPrimaryLabelContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setSecondaryLabelContent(String);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.material.Chip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class ChipColors {
+    ctor @Deprecated public ChipColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ChipColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ChipColors(@ColorInt int, @ColorInt int);
+    ctor @Deprecated public ChipColors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getBackgroundColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getContentColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getIconColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getSecondaryContentColor();
+    method @Deprecated public static androidx.wear.tiles.material.ChipColors primaryChipColors(androidx.wear.tiles.material.Colors);
+    method @Deprecated public static androidx.wear.tiles.material.ChipColors secondaryChipColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ChipDefaults {
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors COMPACT_PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors COMPACT_SECONDARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors SECONDARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors TITLE_PRIMARY_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.material.ChipColors TITLE_SECONDARY_COLORS;
+  }
+
+  @Deprecated public class CircularProgressIndicator implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.CircularProgressIndicator? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ProgressIndicatorColors getCircularProgressIndicatorColors();
+    method @Deprecated public CharSequence? getContentDescription();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getEndAngle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getProgress();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp getStartAngle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp getStrokeWidth();
+  }
+
+  @Deprecated public static final class CircularProgressIndicator.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public CircularProgressIndicator.Builder();
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator build();
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setCircularProgressIndicatorColors(androidx.wear.tiles.material.ProgressIndicatorColors);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setContentDescription(CharSequence);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setEndAngle(float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setProgress(@FloatRange(from=0, to=1) float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStartAngle(float);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStrokeWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.material.CircularProgressIndicator.Builder setStrokeWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class Colors {
+    ctor @Deprecated public Colors(@ColorInt int, @ColorInt int, @ColorInt int, @ColorInt int);
+    method @Deprecated @ColorInt public int getOnPrimary();
+    method @Deprecated @ColorInt public int getOnSurface();
+    method @Deprecated @ColorInt public int getPrimary();
+    method @Deprecated @ColorInt public int getSurface();
+    field @Deprecated public static final androidx.wear.tiles.material.Colors DEFAULT;
+  }
+
+  @Deprecated public class CompactChip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.CompactChip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public String getText();
+  }
+
+  @Deprecated public static final class CompactChip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public CompactChip.Builder(android.content.Context, String, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.CompactChip build();
+    method @Deprecated public androidx.wear.tiles.material.CompactChip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+  }
+
+  @Deprecated public class ProgressIndicatorColors {
+    ctor @Deprecated public ProgressIndicatorColors(androidx.wear.tiles.ColorBuilders.ColorProp, androidx.wear.tiles.ColorBuilders.ColorProp);
+    ctor @Deprecated public ProgressIndicatorColors(@ColorInt int, @ColorInt int);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getIndicatorColor();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getTrackColor();
+    method @Deprecated public static androidx.wear.tiles.material.ProgressIndicatorColors progressIndicatorColors(androidx.wear.tiles.material.Colors);
+  }
+
+  @Deprecated public class ProgressIndicatorDefaults {
+    field @Deprecated public static final androidx.wear.tiles.material.ProgressIndicatorColors DEFAULT_COLORS;
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_STROKE_WIDTH;
+    field @Deprecated public static final float GAP_END_ANGLE = 156.1f;
+    field @Deprecated public static final float GAP_START_ANGLE = -156.1f;
+  }
+
+  @Deprecated public class Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.Text? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp getColor();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle getFontStyle();
+    method @Deprecated public float getLineHeight();
+    method @Deprecated public int getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers getModifiers();
+    method @Deprecated public int getMultilineAlignment();
+    method @Deprecated public int getOverflow();
+    method @Deprecated public String getText();
+    method @Deprecated public int getWeight();
+    method @Deprecated public boolean isItalic();
+    method @Deprecated public boolean isUnderline();
+  }
+
+  @Deprecated public static final class Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public Text.Builder(android.content.Context, String);
+    method @Deprecated public androidx.wear.tiles.material.Text build();
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setItalic(boolean);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setOverflow(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setTypography(int);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setUnderline(boolean);
+    method @Deprecated public androidx.wear.tiles.material.Text.Builder setWeight(int);
+  }
+
+  @Deprecated public class TitleChip implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.TitleChip? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.ChipColors getChipColors();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable getClickable();
+    method @Deprecated public int getHorizontalAlignment();
+    method @Deprecated public String getText();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension getWidth();
+  }
+
+  @Deprecated public static final class TitleChip.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public TitleChip.Builder(android.content.Context, String, androidx.wear.tiles.ModifiersBuilders.Clickable, androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip build();
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setChipColors(androidx.wear.tiles.material.ChipColors);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.material.TitleChip.Builder setWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class Typography {
+    field @Deprecated public static final int TYPOGRAPHY_BODY1 = 7; // 0x7
+    field @Deprecated public static final int TYPOGRAPHY_BODY2 = 8; // 0x8
+    field @Deprecated public static final int TYPOGRAPHY_BUTTON = 9; // 0x9
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION1 = 10; // 0xa
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION2 = 11; // 0xb
+    field @Deprecated public static final int TYPOGRAPHY_CAPTION3 = 12; // 0xc
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY1 = 1; // 0x1
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY2 = 2; // 0x2
+    field @Deprecated public static final int TYPOGRAPHY_DISPLAY3 = 3; // 0x3
+    field @Deprecated public static final int TYPOGRAPHY_TITLE1 = 4; // 0x4
+    field @Deprecated public static final int TYPOGRAPHY_TITLE2 = 5; // 0x5
+    field @Deprecated public static final int TYPOGRAPHY_TITLE3 = 6; // 0x6
+  }
+
+}
+
+package androidx.wear.tiles.material.layouts {
+
+  @Deprecated public class EdgeContentLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.EdgeContentLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getEdgeContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+  }
+
+  @Deprecated public static final class EdgeContentLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public EdgeContentLayout.Builder(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setEdgeContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setPrimaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.EdgeContentLayout.Builder setSecondaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  @Deprecated public class LayoutDefaults {
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp DEFAULT_VERTICAL_SPACER_HEIGHT;
+    field @Deprecated public static final float EDGE_CONTENT_LAYOUT_PADDING_ABOVE_MAIN_CONTENT_DP = 6.0f;
+    field @Deprecated public static final float EDGE_CONTENT_LAYOUT_PADDING_BELOW_MAIN_CONTENT_DP = 8.0f;
+    field @Deprecated public static final int MULTI_BUTTON_MAX_NUMBER = 7; // 0x7
+    field @Deprecated public static final androidx.wear.tiles.DimensionBuilders.DpProp MULTI_SLOT_LAYOUT_HORIZONTAL_SPACER_WIDTH;
+  }
+
+  @Deprecated public class MultiButtonLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.MultiButtonLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getButtonContents();
+    method @Deprecated public int getFiveButtonDistribution();
+    field @Deprecated public static final int FIVE_BUTTON_DISTRIBUTION_BOTTOM_HEAVY = 2; // 0x2
+    field @Deprecated public static final int FIVE_BUTTON_DISTRIBUTION_TOP_HEAVY = 1; // 0x1
+  }
+
+  @Deprecated public static final class MultiButtonLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public MultiButtonLayout.Builder();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout.Builder addButtonContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiButtonLayout.Builder setFiveButtonDistribution(int);
+  }
+
+  @Deprecated public class MultiSlotLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.MultiSlotLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getHorizontalSpacerWidth();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getSlotContents();
+  }
+
+  @Deprecated public static final class MultiSlotLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public MultiSlotLayout.Builder();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout.Builder addSlotContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.MultiSlotLayout.Builder setHorizontalSpacerWidth(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public class PrimaryLayout implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public static androidx.wear.tiles.material.layouts.PrimaryLayout? fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryChipContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getPrimaryLabelTextContent();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getSecondaryLabelTextContent();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getVerticalSpacerHeight();
+  }
+
+  @Deprecated public static final class PrimaryLayout.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public PrimaryLayout.Builder(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout build();
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setPrimaryChipContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setPrimaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setSecondaryLabelTextContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.material.layouts.PrimaryLayout.Builder setVerticalSpacerHeight(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+}
+
diff --git a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/MaterialGoldenXLTest.java b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/MaterialGoldenXLTest.java
index 094ad5a..2115394 100644
--- a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/MaterialGoldenXLTest.java
+++ b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/MaterialGoldenXLTest.java
@@ -74,6 +74,8 @@
     }
 
     @Parameterized.Parameters(name = "{0}")
+    // TODO(b/267744228): Remove the warning suppression.
+    @SuppressWarnings("deprecation")
     public static Collection<Object[]> data() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         DisplayMetrics currentDisplayMetrics = new DisplayMetrics();
diff --git a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/layouts/LayoutsGoldenXLTest.java b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/layouts/LayoutsGoldenXLTest.java
index 45a10ef..f05d0b2 100644
--- a/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/layouts/LayoutsGoldenXLTest.java
+++ b/wear/tiles/tiles-material/src/androidTest/java/androidx/wear/tiles/material/layouts/LayoutsGoldenXLTest.java
@@ -74,6 +74,8 @@
     }
 
     @Parameterized.Parameters(name = "{0}")
+    // TODO(b/267744228): Remove the warning suppression.
+    @SuppressWarnings("deprecation")
     public static Collection<Object[]> data() {
         Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
         DisplayMetrics currentDisplayMetrics = new DisplayMetrics();
diff --git a/wear/tiles/tiles-material/src/test/resources/robolectric.properties b/wear/tiles/tiles-material/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..34d9449
--- /dev/null
+++ b/wear/tiles/tiles-material/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
+sdk=29
diff --git a/wear/tiles/tiles-renderer/api/1.2.0-beta01.txt b/wear/tiles/tiles-renderer/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..2d38960
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/1.2.0-beta01.txt
@@ -0,0 +1,93 @@
+// Signature format: 4.0
+package androidx.wear.tiles.client {
+
+  public interface TileClient {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method public default com.google.common.util.concurrent.ListenableFuture<androidx.wear.protolayout.ResourceBuilders.Resources!> requestTileResourcesAsync(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.connection {
+
+  public final class DefaultTileClient implements androidx.wear.tiles.client.TileClient {
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, java.util.concurrent.Executor executor);
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.manager {
+
+  public final class TileUiClient implements java.lang.AutoCloseable {
+    ctor public TileUiClient(android.content.Context context, android.content.ComponentName component, android.view.ViewGroup parentView);
+    method @MainThread public void close();
+    method @MainThread public void connect();
+  }
+
+}
+
+package androidx.wear.tiles.renderer {
+
+  public final class TileRenderer {
+    ctor @Deprecated public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor @Deprecated public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, @StyleRes int, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor public TileRenderer(android.content.Context, java.util.concurrent.Executor, java.util.function.Consumer<androidx.wear.protolayout.StateBuilders.State!>);
+    method @Deprecated public android.view.View? inflate(android.view.ViewGroup);
+    method public com.google.common.util.concurrent.ListenableFuture<android.view.View!> inflateAsync(androidx.wear.protolayout.LayoutElementBuilders.Layout, androidx.wear.protolayout.ResourceBuilders.Resources, android.view.ViewGroup);
+    method public void setState(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+  }
+
+  @Deprecated public static interface TileRenderer.LoadActionListener {
+    method @Deprecated public void onClick(androidx.wear.tiles.StateBuilders.State);
+  }
+
+}
+
+package androidx.wear.tiles.timeline {
+
+  public final class TilesTimelineCache {
+    ctor public TilesTimelineCache(androidx.wear.protolayout.TimelineBuilders.Timeline);
+    ctor @Deprecated public TilesTimelineCache(androidx.wear.tiles.TimelineBuilders.Timeline);
+    method @MainThread public androidx.wear.protolayout.TimelineBuilders.TimelineEntry? findClosestTileTimelineEntry(long);
+    method @Deprecated @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findClosestTimelineEntry(long);
+    method @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.protolayout.TimelineBuilders.TimelineEntry, long);
+    method @Deprecated @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.tiles.TimelineBuilders.TimelineEntry, long);
+    method @MainThread public androidx.wear.protolayout.TimelineBuilders.TimelineEntry? findTileTimelineEntryForTime(long);
+    method @Deprecated @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findTimelineEntryForTime(long);
+  }
+
+  public class TilesTimelineManager implements java.lang.AutoCloseable {
+    ctor public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.protolayout.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.LayoutUpdateListener);
+    ctor @Deprecated public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.tiles.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.Listener);
+    method public void close();
+    method public void init();
+  }
+
+  public static interface TilesTimelineManager.Clock {
+    method public long getCurrentTimeMillis();
+  }
+
+  public static interface TilesTimelineManager.LayoutUpdateListener {
+    method public void onLayoutUpdate(int, androidx.wear.protolayout.LayoutElementBuilders.Layout);
+  }
+
+  @Deprecated public static interface TilesTimelineManager.Listener {
+    method @Deprecated public void onLayoutUpdate(int, androidx.wear.tiles.LayoutElementBuilders.Layout);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/tiles/tiles-renderer/api/res-1.2.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/tiles/tiles-renderer/api/res-1.2.0-beta01.txt
diff --git a/wear/tiles/tiles-renderer/api/restricted_1.2.0-beta01.txt b/wear/tiles/tiles-renderer/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..2d38960
--- /dev/null
+++ b/wear/tiles/tiles-renderer/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,93 @@
+// Signature format: 4.0
+package androidx.wear.tiles.client {
+
+  public interface TileClient {
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer!> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method public default com.google.common.util.concurrent.ListenableFuture<androidx.wear.protolayout.ResourceBuilders.Resources!> requestTileResourcesAsync(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.connection {
+
+  public final class DefaultTileClient implements androidx.wear.tiles.client.TileClient {
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, java.util.concurrent.Executor executor);
+    ctor public DefaultTileClient(android.content.Context context, android.content.ComponentName componentName, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
+package androidx.wear.tiles.manager {
+
+  public final class TileUiClient implements java.lang.AutoCloseable {
+    ctor public TileUiClient(android.content.Context context, android.content.ComponentName component, android.view.ViewGroup parentView);
+    method @MainThread public void close();
+    method @MainThread public void connect();
+  }
+
+}
+
+package androidx.wear.tiles.renderer {
+
+  public final class TileRenderer {
+    ctor @Deprecated public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor @Deprecated public TileRenderer(android.content.Context, androidx.wear.tiles.LayoutElementBuilders.Layout, @StyleRes int, androidx.wear.tiles.ResourceBuilders.Resources, java.util.concurrent.Executor, androidx.wear.tiles.renderer.TileRenderer.LoadActionListener);
+    ctor public TileRenderer(android.content.Context, java.util.concurrent.Executor, java.util.function.Consumer<androidx.wear.protolayout.StateBuilders.State!>);
+    method @Deprecated public android.view.View? inflate(android.view.ViewGroup);
+    method public com.google.common.util.concurrent.ListenableFuture<android.view.View!> inflateAsync(androidx.wear.protolayout.LayoutElementBuilders.Layout, androidx.wear.protolayout.ResourceBuilders.Resources, android.view.ViewGroup);
+    method public void setState(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue<?>!>);
+  }
+
+  @Deprecated public static interface TileRenderer.LoadActionListener {
+    method @Deprecated public void onClick(androidx.wear.tiles.StateBuilders.State);
+  }
+
+}
+
+package androidx.wear.tiles.timeline {
+
+  public final class TilesTimelineCache {
+    ctor public TilesTimelineCache(androidx.wear.protolayout.TimelineBuilders.Timeline);
+    ctor @Deprecated public TilesTimelineCache(androidx.wear.tiles.TimelineBuilders.Timeline);
+    method @MainThread public androidx.wear.protolayout.TimelineBuilders.TimelineEntry? findClosestTileTimelineEntry(long);
+    method @Deprecated @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findClosestTimelineEntry(long);
+    method @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.protolayout.TimelineBuilders.TimelineEntry, long);
+    method @Deprecated @MainThread public long findCurrentTimelineEntryExpiry(androidx.wear.tiles.TimelineBuilders.TimelineEntry, long);
+    method @MainThread public androidx.wear.protolayout.TimelineBuilders.TimelineEntry? findTileTimelineEntryForTime(long);
+    method @Deprecated @MainThread public androidx.wear.tiles.TimelineBuilders.TimelineEntry? findTimelineEntryForTime(long);
+  }
+
+  public class TilesTimelineManager implements java.lang.AutoCloseable {
+    ctor public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.protolayout.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.LayoutUpdateListener);
+    ctor @Deprecated public TilesTimelineManager(android.app.AlarmManager, androidx.wear.tiles.timeline.TilesTimelineManager.Clock, androidx.wear.tiles.TimelineBuilders.Timeline, int, java.util.concurrent.Executor, androidx.wear.tiles.timeline.TilesTimelineManager.Listener);
+    method public void close();
+    method public void init();
+  }
+
+  public static interface TilesTimelineManager.Clock {
+    method public long getCurrentTimeMillis();
+  }
+
+  public static interface TilesTimelineManager.LayoutUpdateListener {
+    method public void onLayoutUpdate(int, androidx.wear.protolayout.LayoutElementBuilders.Layout);
+  }
+
+  @Deprecated public static interface TilesTimelineManager.Listener {
+    method @Deprecated public void onLayoutUpdate(int, androidx.wear.tiles.LayoutElementBuilders.Layout);
+  }
+
+}
+
diff --git a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/manager/UpdateSchedulerTest.java b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/manager/UpdateSchedulerTest.java
index b9696c8..c96a0bc 100644
--- a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/manager/UpdateSchedulerTest.java
+++ b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/manager/UpdateSchedulerTest.java
@@ -292,7 +292,6 @@
         expect.that(mFired).isEmpty();
     }
 
-    @SuppressWarnings("deprecation") // ScheduledAlarm usage, see b/284981234
     private void advanceToTime(Long targetTime) {
         while (mShadowAlarmManager.peekNextScheduledAlarm() != null
                 && mShadowAlarmManager.peekNextScheduledAlarm().triggerAtTime <= targetTime) {
diff --git a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/timeline/TilesTimelineManagerTest.java b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/timeline/TilesTimelineManagerTest.java
index ba44a1f..cd97c3c 100644
--- a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/timeline/TilesTimelineManagerTest.java
+++ b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/timeline/TilesTimelineManagerTest.java
@@ -365,7 +365,6 @@
                 .build();
     }
 
-    @SuppressWarnings("deprecation") // ScheduledAlarm usage, see b/284981234
     private void seekToTime(long timeMillis) {
         ShadowAlarmManager shadowAlarmManager = shadowOf(mAlarmManager);
 
diff --git a/wear/tiles/tiles-renderer/src/test/resources/robolectric.properties b/wear/tiles/tiles-renderer/src/test/resources/robolectric.properties
index 71111c5..69fde47 100644
--- a/wear/tiles/tiles-renderer/src/test/resources/robolectric.properties
+++ b/wear/tiles/tiles-renderer/src/test/resources/robolectric.properties
@@ -1,17 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/tiles/tiles-testing/api/1.2.0-beta01.txt b/wear/tiles/tiles-testing/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..17cae9a
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/1.2.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.wear.tiles.testing {
+
+  public final class TestTileClient<T extends androidx.wear.tiles.TileService> implements androidx.wear.tiles.client.TileClient {
+    ctor public TestTileClient(T service, java.util.concurrent.Executor executor);
+    ctor public TestTileClient(T service, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/tiles/tiles-testing/api/res-1.2.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/tiles/tiles-testing/api/res-1.2.0-beta01.txt
diff --git a/wear/tiles/tiles-testing/api/restricted_1.2.0-beta01.txt b/wear/tiles/tiles-testing/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..17cae9a
--- /dev/null
+++ b/wear/tiles/tiles-testing/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,17 @@
+// Signature format: 4.0
+package androidx.wear.tiles.testing {
+
+  public final class TestTileClient<T extends androidx.wear.tiles.TileService> implements androidx.wear.tiles.client.TileClient {
+    ctor public TestTileClient(T service, java.util.concurrent.Executor executor);
+    ctor public TestTileClient(T service, kotlinx.coroutines.CoroutineScope coroutineScope, kotlinx.coroutines.CoroutineDispatcher coroutineDispatcher);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Integer> requestApiVersion();
+    method @Deprecated public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources> requestResources(androidx.wear.tiles.RequestBuilders.ResourcesRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile> requestTile(androidx.wear.tiles.RequestBuilders.TileRequest requestParams);
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileAddedEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileEnterEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileLeaveEvent();
+    method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void> sendOnTileRemovedEvent();
+  }
+
+}
+
diff --git a/wear/tiles/tiles-testing/build.gradle b/wear/tiles/tiles-testing/build.gradle
index e0ff8e58..c1b3d58 100644
--- a/wear/tiles/tiles-testing/build.gradle
+++ b/wear/tiles/tiles-testing/build.gradle
@@ -38,7 +38,7 @@
     implementation(libs.kotlinCoroutinesCore)
     implementation(libs.kotlinCoroutinesAndroid)
     implementation(libs.robolectric)
-    implementation(libs.testCore)
+    implementation("androidx.test:core:1.5.0")
 
     testImplementation(libs.testExtJunit)
     testImplementation(libs.testExtTruth)
diff --git a/wear/tiles/tiles-testing/src/test/resources/robolectric.properties b/wear/tiles/tiles-testing/src/test/resources/robolectric.properties
index 27d4acf..69fde47 100644
--- a/wear/tiles/tiles-testing/src/test/resources/robolectric.properties
+++ b/wear/tiles/tiles-testing/src/test/resources/robolectric.properties
@@ -1,18 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
 # robolectric properties
-
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/tiles/tiles-tooling/api/1.2.0-beta01.txt b/wear/tiles/tiles-tooling/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/wear/tiles/tiles-tooling/api/1.2.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/tiles/tiles-tooling/api/res-1.2.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/tiles/tiles-tooling/api/res-1.2.0-beta01.txt
diff --git a/wear/tiles/tiles-tooling/api/restricted_1.2.0-beta01.txt b/wear/tiles/tiles-tooling/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/wear/tiles/tiles-tooling/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/wear/tiles/tiles/api/1.2.0-beta01.txt b/wear/tiles/tiles/api/1.2.0-beta01.txt
new file mode 100644
index 0000000..5f0bde2
--- /dev/null
+++ b/wear/tiles/tiles/api/1.2.0-beta01.txt
@@ -0,0 +1,1128 @@
+// Signature format: 4.0
+package androidx.wear.tiles {
+
+  @Deprecated public final class ActionBuilders {
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidIntExtra intExtra(int);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidLongExtra longExtra(long);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  @Deprecated public static interface ActionBuilders.Action {
+  }
+
+  @Deprecated public static interface ActionBuilders.Action.Builder {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.Action build();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidActivity {
+    method @Deprecated public String getClassName();
+    method @Deprecated public java.util.Map<java.lang.String!,androidx.wear.tiles.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method @Deprecated public String getPackageName();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidActivity.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.tiles.ActionBuilders.AndroidExtra);
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public boolean getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidBooleanExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidBooleanExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public double getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidDoubleExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidDoubleExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  @Deprecated public static interface ActionBuilders.AndroidExtra {
+  }
+
+  @Deprecated public static interface ActionBuilders.AndroidExtra.Builder {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidExtra build();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidIntExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidIntExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidIntExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public long getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidLongExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidLongExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidLongExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public String getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidStringExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidStringExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidStringExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  @Deprecated public static final class ActionBuilders.LaunchAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  @Deprecated public static final class ActionBuilders.LaunchAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor @Deprecated public ActionBuilders.LaunchAction.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LaunchAction build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.tiles.ActionBuilders.AndroidActivity);
+  }
+
+  @Deprecated public static final class ActionBuilders.LoadAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State? getRequestState();
+  }
+
+  @Deprecated public static final class ActionBuilders.LoadAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor @Deprecated public ActionBuilders.LoadAction.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LoadAction build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  @Deprecated public final class ColorBuilders {
+    method @Deprecated public static androidx.wear.tiles.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  @Deprecated public static final class ColorBuilders.ColorProp {
+    method @Deprecated @ColorInt public int getArgb();
+  }
+
+  @Deprecated public static final class ColorBuilders.ColorProp.Builder {
+    ctor @Deprecated public ColorBuilders.ColorProp.Builder();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp build();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+  }
+
+  @Deprecated public final class DeviceParametersBuilders {
+    field @Deprecated public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field @Deprecated public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field @Deprecated public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field @Deprecated public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class DeviceParametersBuilders.DeviceParameters {
+    method @Deprecated public int getDevicePlatform();
+    method @Deprecated @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method @Deprecated public int getScreenShape();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  @Deprecated public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor @Deprecated public DeviceParametersBuilders.DeviceParameters.Builder();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters build();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  @Deprecated public final class DimensionBuilders {
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DegreesProp degrees(float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.EmProp em(float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.EmProp em(int);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp expand();
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  @Deprecated public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.ContainerDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DegreesProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DegreesProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.DpProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension androidx.wear.tiles.DimensionBuilders.SpacerDimension {
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DpProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder androidx.wear.tiles.DimensionBuilders.SpacerDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.DpProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.EmProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.EmProp.Builder {
+    ctor @Deprecated public DimensionBuilders.EmProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension {
+  }
+
+  @Deprecated public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp build();
+  }
+
+  @Deprecated public static interface DimensionBuilders.ImageDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.ImageDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.tiles.DimensionBuilders.ImageDimension {
+    method @Deprecated @IntRange(from=0) public int getAspectRatioHeight();
+    method @Deprecated @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  @Deprecated public static final class DimensionBuilders.ProportionalDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  @Deprecated public static final class DimensionBuilders.SpProp {
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.SpProp.Builder {
+    ctor @Deprecated public DimensionBuilders.SpProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  @Deprecated public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.SpacerDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension {
+  }
+
+  @Deprecated public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.WrappedDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp build();
+  }
+
+  public final class EventBuilders {
+  }
+
+  public static final class EventBuilders.TileAddEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileAddEvent.Builder {
+    ctor public EventBuilders.TileAddEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileEnterEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileEnterEvent.Builder {
+    ctor public EventBuilders.TileEnterEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileLeaveEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileLeaveEvent.Builder {
+    ctor public EventBuilders.TileLeaveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileRemoveEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileRemoveEvent.Builder {
+    ctor public EventBuilders.TileRemoveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent.Builder setTileId(int);
+  }
+
+  @Deprecated public final class LayoutElementBuilders {
+    field @Deprecated public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field @Deprecated public static final int ARC_ANCHOR_END = 3; // 0x3
+    field @Deprecated public static final int ARC_ANCHOR_START = 1; // 0x1
+    field @Deprecated public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field @Deprecated public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field @Deprecated public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field @Deprecated public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field @Deprecated public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field @Deprecated public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field @Deprecated @androidx.wear.tiles.TilesExperimental public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field @Deprecated public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field @Deprecated public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field @Deprecated public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field @Deprecated public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field @Deprecated public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field @Deprecated public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int TEXT_ALIGN_END = 3; // 0x3
+    field @Deprecated public static final int TEXT_ALIGN_START = 1; // 0x1
+    field @Deprecated public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field @Deprecated public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field @Deprecated public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field @Deprecated public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field @Deprecated public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Arc implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Arc.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Arc.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAdapter.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcAdapter.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.ArcLayoutElement.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcLine implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcLine.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcLine.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcSpacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcSpacer.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcText implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcText.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcText.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Box implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Box.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Box.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ColorFilter {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getTint();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ColorFilter.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.tiles.ColorBuilders.ColorProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Column implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Column.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Column.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyle {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getItalic();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp? getLetterSpacing();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getSize();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getUnderline();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp? getVariant();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontStyle.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.tiles.DimensionBuilders.EmProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.tiles.LayoutElementBuilders.FontVariantProp);
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.tiles.LayoutElementBuilders.FontWeightProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  @Deprecated public static class LayoutElementBuilders.FontStyles {
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  @Deprecated @androidx.wear.tiles.TilesExperimental public static final class LayoutElementBuilders.FontVariantProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontVariantProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontVariantProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontWeightProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontWeightProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Image implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Image.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Image.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setColorFilter(androidx.wear.tiles.LayoutElementBuilders.ColorFilter);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Layout {
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public static androidx.wear.tiles.LayoutElementBuilders.Layout? fromByteArray(byte[]);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getRoot();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public byte[] toByteArray();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Layout.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Layout.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.LayoutElement.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Row implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Row.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Row.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spacer implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Spacer.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.Span {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.Span.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Span build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanImage implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanImage.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanImage.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanText implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanText.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanText.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spannable implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spannable.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Spannable.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.tiles.LayoutElementBuilders.Span);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Text.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextOverflowProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.TextOverflowProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public final class ModifiersBuilders {
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ArcModifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.ArcModifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Background {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner? getCorner();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Background.Builder {
+    ctor @Deprecated public ModifiersBuilders.Background.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background.Builder setCorner(androidx.wear.tiles.ModifiersBuilders.Corner);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Border {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Border.Builder {
+    ctor @Deprecated public ModifiersBuilders.Border.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Clickable {
+    method @Deprecated public String getId();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.Action? getOnClick();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Clickable.Builder {
+    ctor @Deprecated public ModifiersBuilders.Clickable.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setId(String);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.tiles.ActionBuilders.Action);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Corner {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getRadius();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Corner.Builder {
+    ctor @Deprecated public ModifiersBuilders.Corner.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ElementMetadata {
+    method @Deprecated public byte[] getTagData();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ElementMetadata.Builder {
+    ctor @Deprecated public ModifiersBuilders.ElementMetadata.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata.Builder setTagData(byte[]);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Modifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background? getBackground();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border? getBorder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata? getMetadata();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding? getPadding();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.Modifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.tiles.ModifiersBuilders.Background);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.tiles.ModifiersBuilders.Border);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.tiles.ModifiersBuilders.ElementMetadata);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.tiles.ModifiersBuilders.Padding);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Padding {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getBottom();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getEnd();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getRtlAware();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getStart();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getTop();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Padding.Builder {
+    ctor @Deprecated public ModifiersBuilders.Padding.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setStart(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setTop(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Semantics {
+    method @Deprecated public String getContentDescription();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Semantics.Builder {
+    ctor @Deprecated public ModifiersBuilders.Semantics.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.SpanModifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.SpanModifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+  }
+
+  public final class RequestBuilders {
+  }
+
+  public static final class RequestBuilders.ResourcesRequest {
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public java.util.List<java.lang.String!> getResourceIds();
+    method public int getTileId();
+    method public String getVersion();
+  }
+
+  public static final class RequestBuilders.ResourcesRequest.Builder {
+    ctor public RequestBuilders.ResourcesRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder addResourceId(String);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setTileId(int);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
+  }
+
+  public static final class RequestBuilders.TileRequest {
+    method public androidx.wear.protolayout.StateBuilders.State getCurrentState();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State? getState();
+    method public int getTileId();
+  }
+
+  public static final class RequestBuilders.TileRequest.Builder {
+    ctor public RequestBuilders.TileRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest build();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setCurrentState(androidx.wear.protolayout.StateBuilders.State);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setTileId(int);
+  }
+
+  @Deprecated public final class ResourceBuilders {
+    field @Deprecated public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field @Deprecated public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @Deprecated @DrawableRes public int getResourceId();
+  }
+
+  @Deprecated public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor @Deprecated public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  @Deprecated public static final class ResourceBuilders.ImageResource {
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  @Deprecated public static final class ResourceBuilders.ImageResource.Builder {
+    ctor @Deprecated public ResourceBuilders.ImageResource.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.tiles.ResourceBuilders.InlineImageResource);
+  }
+
+  @Deprecated public static final class ResourceBuilders.InlineImageResource {
+    method @Deprecated public byte[] getData();
+    method @Deprecated public int getFormat();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  @Deprecated public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor @Deprecated public ResourceBuilders.InlineImageResource.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  @Deprecated public static final class ResourceBuilders.Resources {
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public static androidx.wear.tiles.ResourceBuilders.Resources? fromByteArray(byte[]);
+    method @Deprecated public java.util.Map<java.lang.String!,androidx.wear.tiles.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method @Deprecated public String getVersion();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public byte[] toByteArray();
+  }
+
+  @Deprecated public static final class ResourceBuilders.Resources.Builder {
+    ctor @Deprecated public ResourceBuilders.Resources.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.tiles.ResourceBuilders.ImageResource);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  @Deprecated public final class StateBuilders {
+  }
+
+  @Deprecated public static final class StateBuilders.State {
+    method @Deprecated public String getLastClickableId();
+  }
+
+  @Deprecated public static final class StateBuilders.State.Builder {
+    ctor @Deprecated public StateBuilders.State.Builder();
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State build();
+  }
+
+  public final class TileBuilders {
+  }
+
+  public static final class TileBuilders.Tile {
+    method public long getFreshnessIntervalMillis();
+    method public String getResourcesVersion();
+    method public androidx.wear.protolayout.StateBuilders.State? getState();
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline? getTileTimeline();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline? getTimeline();
+  }
+
+  public static final class TileBuilders.Tile.Builder {
+    ctor public TileBuilders.Tile.Builder();
+    method public androidx.wear.tiles.TileBuilders.Tile build();
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setFreshnessIntervalMillis(long);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setResourcesVersion(String);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setState(androidx.wear.protolayout.StateBuilders.State);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setTileTimeline(androidx.wear.protolayout.TimelineBuilders.Timeline);
+    method @Deprecated public androidx.wear.tiles.TileBuilders.Tile.Builder setTimeline(androidx.wear.tiles.TimelineBuilders.Timeline);
+  }
+
+  public abstract class TileService extends android.app.Service {
+    ctor public TileService();
+    method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
+    method public android.os.IBinder? onBind(android.content.Intent);
+    method @Deprecated @MainThread protected com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method @MainThread protected void onTileAddEvent(androidx.wear.tiles.EventBuilders.TileAddEvent);
+    method @MainThread protected void onTileEnterEvent(androidx.wear.tiles.EventBuilders.TileEnterEvent);
+    method @MainThread protected void onTileLeaveEvent(androidx.wear.tiles.EventBuilders.TileLeaveEvent);
+    method @MainThread protected void onTileRemoveEvent(androidx.wear.tiles.EventBuilders.TileRemoveEvent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method @MainThread protected com.google.common.util.concurrent.ListenableFuture<androidx.wear.protolayout.ResourceBuilders.Resources!> onTileResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    field public static final String ACTION_BIND_TILE_PROVIDER = "androidx.wear.tiles.action.BIND_TILE_PROVIDER";
+    field public static final String EXTRA_CLICKABLE_ID = "androidx.wear.tiles.extra.CLICKABLE_ID";
+    field public static final String METADATA_PREVIEW_KEY = "androidx.wear.tiles.PREVIEW";
+  }
+
+  public interface TileUpdateRequester {
+    method public void requestUpdate(Class<? extends androidx.wear.tiles.TileService>);
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TilesExperimental {
+  }
+
+  @Deprecated public final class TimelineBuilders {
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimeInterval {
+    method @Deprecated public long getEndMillis();
+    method @Deprecated public long getStartMillis();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor @Deprecated public TimelineBuilders.TimeInterval.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval build();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  @Deprecated public static final class TimelineBuilders.Timeline {
+    method @Deprecated public static androidx.wear.tiles.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public java.util.List<androidx.wear.tiles.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  @Deprecated public static final class TimelineBuilders.Timeline.Builder {
+    ctor @Deprecated public TimelineBuilders.Timeline.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.tiles.TimelineBuilders.TimelineEntry);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline build();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimelineEntry {
+    method @Deprecated public static androidx.wear.tiles.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout? getLayout();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor @Deprecated public TimelineBuilders.TimelineEntry.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry build();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.tiles.LayoutElementBuilders.Layout);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.tiles.TimelineBuilders.TimeInterval);
+  }
+
+  @Deprecated public final class TypeBuilders {
+  }
+
+  @Deprecated public static final class TypeBuilders.BoolProp {
+    method @Deprecated public boolean getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.BoolProp.Builder {
+    ctor @Deprecated public TypeBuilders.BoolProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  @Deprecated public static final class TypeBuilders.FloatProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.FloatProp.Builder {
+    ctor @Deprecated public TypeBuilders.FloatProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.FloatProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class TypeBuilders.Int32Prop {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.Int32Prop.Builder {
+    ctor @Deprecated public TypeBuilders.Int32Prop.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  @Deprecated public static final class TypeBuilders.StringProp {
+    method @Deprecated public String getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.StringProp.Builder {
+    ctor @Deprecated public TypeBuilders.StringProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/webkit/webkit/api/res-1.6.0-beta02.txt b/wear/tiles/tiles/api/res-1.2.0-beta01.txt
similarity index 100%
copy from webkit/webkit/api/res-1.6.0-beta02.txt
copy to wear/tiles/tiles/api/res-1.2.0-beta01.txt
diff --git a/wear/tiles/tiles/api/restricted_1.2.0-beta01.txt b/wear/tiles/tiles/api/restricted_1.2.0-beta01.txt
new file mode 100644
index 0000000..5f0bde2
--- /dev/null
+++ b/wear/tiles/tiles/api/restricted_1.2.0-beta01.txt
@@ -0,0 +1,1128 @@
+// Signature format: 4.0
+package androidx.wear.tiles {
+
+  @Deprecated public final class ActionBuilders {
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra booleanExtra(boolean);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra doubleExtra(double);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidIntExtra intExtra(int);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidLongExtra longExtra(long);
+    method @Deprecated public static androidx.wear.tiles.ActionBuilders.AndroidStringExtra stringExtra(String);
+  }
+
+  @Deprecated public static interface ActionBuilders.Action {
+  }
+
+  @Deprecated public static interface ActionBuilders.Action.Builder {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.Action build();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidActivity {
+    method @Deprecated public String getClassName();
+    method @Deprecated public java.util.Map<java.lang.String!,androidx.wear.tiles.ActionBuilders.AndroidExtra!> getKeyToExtraMapping();
+    method @Deprecated public String getPackageName();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidActivity.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidActivity.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder addKeyToExtraMapping(String, androidx.wear.tiles.ActionBuilders.AndroidExtra);
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setClassName(String);
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity.Builder setPackageName(String);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidBooleanExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public boolean getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidBooleanExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidBooleanExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidBooleanExtra.Builder setValue(boolean);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidDoubleExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public double getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidDoubleExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidDoubleExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidDoubleExtra.Builder setValue(double);
+  }
+
+  @Deprecated public static interface ActionBuilders.AndroidExtra {
+  }
+
+  @Deprecated public static interface ActionBuilders.AndroidExtra.Builder {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidExtra build();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidIntExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidIntExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidIntExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidIntExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidIntExtra.Builder setValue(int);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidLongExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public long getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidLongExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidLongExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidLongExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidLongExtra.Builder setValue(long);
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidStringExtra implements androidx.wear.tiles.ActionBuilders.AndroidExtra {
+    method @Deprecated public String getValue();
+  }
+
+  @Deprecated public static final class ActionBuilders.AndroidStringExtra.Builder implements androidx.wear.tiles.ActionBuilders.AndroidExtra.Builder {
+    ctor @Deprecated public ActionBuilders.AndroidStringExtra.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidStringExtra build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidStringExtra.Builder setValue(String);
+  }
+
+  @Deprecated public static final class ActionBuilders.LaunchAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.AndroidActivity? getAndroidActivity();
+  }
+
+  @Deprecated public static final class ActionBuilders.LaunchAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor @Deprecated public ActionBuilders.LaunchAction.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LaunchAction build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LaunchAction.Builder setAndroidActivity(androidx.wear.tiles.ActionBuilders.AndroidActivity);
+  }
+
+  @Deprecated public static final class ActionBuilders.LoadAction implements androidx.wear.tiles.ActionBuilders.Action {
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State? getRequestState();
+  }
+
+  @Deprecated public static final class ActionBuilders.LoadAction.Builder implements androidx.wear.tiles.ActionBuilders.Action.Builder {
+    ctor @Deprecated public ActionBuilders.LoadAction.Builder();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LoadAction build();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.LoadAction.Builder setRequestState(androidx.wear.tiles.StateBuilders.State);
+  }
+
+  @Deprecated public final class ColorBuilders {
+    method @Deprecated public static androidx.wear.tiles.ColorBuilders.ColorProp argb(@ColorInt int);
+  }
+
+  @Deprecated public static final class ColorBuilders.ColorProp {
+    method @Deprecated @ColorInt public int getArgb();
+  }
+
+  @Deprecated public static final class ColorBuilders.ColorProp.Builder {
+    ctor @Deprecated public ColorBuilders.ColorProp.Builder();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp build();
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp.Builder setArgb(@ColorInt int);
+  }
+
+  @Deprecated public final class DeviceParametersBuilders {
+    field @Deprecated public static final int DEVICE_PLATFORM_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int DEVICE_PLATFORM_WEAR_OS = 1; // 0x1
+    field @Deprecated public static final int SCREEN_SHAPE_RECT = 2; // 0x2
+    field @Deprecated public static final int SCREEN_SHAPE_ROUND = 1; // 0x1
+    field @Deprecated public static final int SCREEN_SHAPE_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class DeviceParametersBuilders.DeviceParameters {
+    method @Deprecated public int getDevicePlatform();
+    method @Deprecated @FloatRange(from=0.0, fromInclusive=false, toInclusive=false) public float getScreenDensity();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenHeightDp();
+    method @Deprecated public int getScreenShape();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public int getScreenWidthDp();
+  }
+
+  @Deprecated public static final class DeviceParametersBuilders.DeviceParameters.Builder {
+    ctor @Deprecated public DeviceParametersBuilders.DeviceParameters.Builder();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters build();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setDevicePlatform(int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenDensity(@FloatRange(from=0.0, fromInclusive=false, toInclusive=false) float);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenHeightDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenShape(int);
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters.Builder setScreenWidthDp(@Dimension(unit=androidx.annotation.Dimension.DP) int);
+  }
+
+  @Deprecated public final class DimensionBuilders {
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DegreesProp degrees(float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.DpProp dp(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.EmProp em(float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.EmProp em(int);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp expand();
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.SpProp sp(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+    method @Deprecated public static androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp wrap();
+  }
+
+  @Deprecated public static interface DimensionBuilders.ContainerDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.ContainerDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DegreesProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DegreesProp.Builder {
+    ctor @Deprecated public DimensionBuilders.DegreesProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.DpProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension androidx.wear.tiles.DimensionBuilders.SpacerDimension {
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.DP) public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.DpProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder androidx.wear.tiles.DimensionBuilders.SpacerDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.DpProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.DP) float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.EmProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.EmProp.Builder {
+    ctor @Deprecated public DimensionBuilders.EmProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class DimensionBuilders.ExpandedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension androidx.wear.tiles.DimensionBuilders.ImageDimension {
+  }
+
+  @Deprecated public static final class DimensionBuilders.ExpandedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.ExpandedDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ExpandedDimensionProp build();
+  }
+
+  @Deprecated public static interface DimensionBuilders.ImageDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.ImageDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.ProportionalDimensionProp implements androidx.wear.tiles.DimensionBuilders.ImageDimension {
+    method @Deprecated @IntRange(from=0) public int getAspectRatioHeight();
+    method @Deprecated @IntRange(from=0) public int getAspectRatioWidth();
+  }
+
+  @Deprecated public static final class DimensionBuilders.ProportionalDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ImageDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.ProportionalDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioHeight(@IntRange(from=0) int);
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ProportionalDimensionProp.Builder setAspectRatioWidth(@IntRange(from=0) int);
+  }
+
+  @Deprecated public static final class DimensionBuilders.SpProp {
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.SP) public float getValue();
+  }
+
+  @Deprecated public static final class DimensionBuilders.SpProp.Builder {
+    ctor @Deprecated public DimensionBuilders.SpProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp build();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp.Builder setValue(@Dimension(unit=androidx.annotation.Dimension.SP) float);
+  }
+
+  @Deprecated public static interface DimensionBuilders.SpacerDimension {
+  }
+
+  @Deprecated public static interface DimensionBuilders.SpacerDimension.Builder {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension build();
+  }
+
+  @Deprecated public static final class DimensionBuilders.WrappedDimensionProp implements androidx.wear.tiles.DimensionBuilders.ContainerDimension {
+  }
+
+  @Deprecated public static final class DimensionBuilders.WrappedDimensionProp.Builder implements androidx.wear.tiles.DimensionBuilders.ContainerDimension.Builder {
+    ctor @Deprecated public DimensionBuilders.WrappedDimensionProp.Builder();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.WrappedDimensionProp build();
+  }
+
+  public final class EventBuilders {
+  }
+
+  public static final class EventBuilders.TileAddEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileAddEvent.Builder {
+    ctor public EventBuilders.TileAddEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileAddEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileEnterEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileEnterEvent.Builder {
+    ctor public EventBuilders.TileEnterEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileEnterEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileLeaveEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileLeaveEvent.Builder {
+    ctor public EventBuilders.TileLeaveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileLeaveEvent.Builder setTileId(int);
+  }
+
+  public static final class EventBuilders.TileRemoveEvent {
+    method public int getTileId();
+  }
+
+  public static final class EventBuilders.TileRemoveEvent.Builder {
+    ctor public EventBuilders.TileRemoveEvent.Builder();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent build();
+    method public androidx.wear.tiles.EventBuilders.TileRemoveEvent.Builder setTileId(int);
+  }
+
+  @Deprecated public final class LayoutElementBuilders {
+    field @Deprecated public static final int ARC_ANCHOR_CENTER = 2; // 0x2
+    field @Deprecated public static final int ARC_ANCHOR_END = 3; // 0x3
+    field @Deprecated public static final int ARC_ANCHOR_START = 1; // 0x1
+    field @Deprecated public static final int ARC_ANCHOR_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int CONTENT_SCALE_MODE_CROP = 2; // 0x2
+    field @Deprecated public static final int CONTENT_SCALE_MODE_FILL_BOUNDS = 3; // 0x3
+    field @Deprecated public static final int CONTENT_SCALE_MODE_FIT = 1; // 0x1
+    field @Deprecated public static final int CONTENT_SCALE_MODE_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int FONT_VARIANT_BODY = 2; // 0x2
+    field @Deprecated public static final int FONT_VARIANT_TITLE = 1; // 0x1
+    field @Deprecated public static final int FONT_VARIANT_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field @Deprecated @androidx.wear.tiles.TilesExperimental public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field @Deprecated public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field @Deprecated public static final int FONT_WEIGHT_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int HORIZONTAL_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int HORIZONTAL_ALIGN_END = 5; // 0x5
+    field @Deprecated public static final int HORIZONTAL_ALIGN_LEFT = 1; // 0x1
+    field @Deprecated public static final int HORIZONTAL_ALIGN_RIGHT = 3; // 0x3
+    field @Deprecated public static final int HORIZONTAL_ALIGN_START = 4; // 0x4
+    field @Deprecated public static final int HORIZONTAL_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_BOTTOM = 1; // 0x1
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_TEXT_BASELINE = 2; // 0x2
+    field @Deprecated public static final int SPAN_VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int TEXT_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int TEXT_ALIGN_END = 3; // 0x3
+    field @Deprecated public static final int TEXT_ALIGN_START = 1; // 0x1
+    field @Deprecated public static final int TEXT_ALIGN_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int TEXT_OVERFLOW_ELLIPSIZE_END = 2; // 0x2
+    field @Deprecated public static final int TEXT_OVERFLOW_TRUNCATE = 1; // 0x1
+    field @Deprecated public static final int TEXT_OVERFLOW_UNDEFINED = 0; // 0x0
+    field @Deprecated public static final int VERTICAL_ALIGN_BOTTOM = 3; // 0x3
+    field @Deprecated public static final int VERTICAL_ALIGN_CENTER = 2; // 0x2
+    field @Deprecated public static final int VERTICAL_ALIGN_TOP = 1; // 0x1
+    field @Deprecated public static final int VERTICAL_ALIGN_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Arc implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getAnchorAngle();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp? getAnchorType();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlign();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Arc.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Arc.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorAngle(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setAnchorType(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Arc.Builder setVerticalAlign(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAdapter implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getContent();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getRotateContents();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAdapter.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcAdapter.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAdapter.Builder setRotateContents(boolean);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAnchorTypeProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcAnchorTypeProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcAnchorTypeProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcAnchorTypeProp.Builder setValue(int);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.ArcLayoutElement {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.ArcLayoutElement.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcLine implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcLine.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcLine.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcLine.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcSpacer implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DegreesProp? getLength();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getThickness();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcSpacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcSpacer.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setLength(androidx.wear.tiles.DimensionBuilders.DegreesProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcSpacer.Builder setThickness(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcText implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ArcText.Builder implements androidx.wear.tiles.LayoutElementBuilders.ArcLayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ArcText.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.ArcModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ArcText.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Box implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Box.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Box.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setVerticalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Box.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ColorFilter {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getTint();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ColorFilter.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ColorFilter.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter.Builder setTint(androidx.wear.tiles.ColorBuilders.ColorProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Column implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getHorizontalAlignment();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Column.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Column.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setHorizontalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Column.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ContentScaleModeProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.ContentScaleModeProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.ContentScaleModeProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyle {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getItalic();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.EmProp? getLetterSpacing();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getSize();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getUnderline();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp? getVariant();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp? getWeight();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontStyle.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontStyle.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setItalic(boolean);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setLetterSpacing(androidx.wear.tiles.DimensionBuilders.EmProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setSize(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setUnderline(boolean);
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(androidx.wear.tiles.LayoutElementBuilders.FontVariantProp);
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setVariant(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(androidx.wear.tiles.LayoutElementBuilders.FontWeightProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder setWeight(int);
+  }
+
+  @Deprecated public static class LayoutElementBuilders.FontStyles {
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder body2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder button(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder caption2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder display3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title1(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title2(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.FontStyle.Builder title3(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+  }
+
+  @Deprecated @androidx.wear.tiles.TilesExperimental public static final class LayoutElementBuilders.FontVariantProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontVariantProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontVariantProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontVariantProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontWeightProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.FontWeightProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.FontWeightProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontWeightProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.HorizontalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.HorizontalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.HorizontalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Image implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ColorFilter? getColorFilter();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp? getContentScaleMode();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ImageDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Image.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Image.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setColorFilter(androidx.wear.tiles.LayoutElementBuilders.ColorFilter);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(androidx.wear.tiles.LayoutElementBuilders.ContentScaleModeProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setContentScaleMode(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setResourceId(String);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Image.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ImageDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Layout {
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public static androidx.wear.tiles.LayoutElementBuilders.Layout? fromByteArray(byte[]);
+    method @Deprecated public static androidx.wear.tiles.LayoutElementBuilders.Layout fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement? getRoot();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public byte[] toByteArray();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Layout.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Layout.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout.Builder setRoot(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.LayoutElement {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.LayoutElement.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.LayoutElement build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Row implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.LayoutElement!> getContents();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp? getVerticalAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.ContainerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Row.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Row.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder addContent(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setHeight(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setVerticalAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Row.Builder setWidth(androidx.wear.tiles.DimensionBuilders.ContainerDimension);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spacer implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpacerDimension? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spacer.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Spacer.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setHeight(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spacer.Builder setWidth(androidx.wear.tiles.DimensionBuilders.SpacerDimension);
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.Span {
+  }
+
+  @Deprecated public static interface LayoutElementBuilders.Span.Builder {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Span build();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanImage implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp? getAlignment();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getHeight();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getResourceId();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanImage.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanImage.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setHeight(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setResourceId(String);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanImage.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanText implements androidx.wear.tiles.LayoutElementBuilders.Span {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanText.Builder implements androidx.wear.tiles.LayoutElementBuilders.Span.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanText.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.SpanModifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanText.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanVerticalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.SpanVerticalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.SpanVerticalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.SpanVerticalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spannable implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp? getMultilineAlignment();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method @Deprecated public java.util.List<androidx.wear.tiles.LayoutElementBuilders.Span!> getSpans();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Spannable.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Spannable.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder addSpan(androidx.wear.tiles.LayoutElementBuilders.Span);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.HorizontalAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Spannable.Builder setOverflow(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Text implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement {
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.FontStyle? getFontStyle();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.SpProp? getLineHeight();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop? getMaxLines();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers? getModifiers();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp? getMultilineAlignment();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp? getOverflow();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp? getText();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.Text.Builder implements androidx.wear.tiles.LayoutElementBuilders.LayoutElement.Builder {
+    ctor @Deprecated public LayoutElementBuilders.Text.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setFontStyle(androidx.wear.tiles.LayoutElementBuilders.FontStyle);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setLineHeight(androidx.wear.tiles.DimensionBuilders.SpProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(androidx.wear.tiles.TypeBuilders.Int32Prop);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMaxLines(@IntRange(from=1) int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setModifiers(androidx.wear.tiles.ModifiersBuilders.Modifiers);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setMultilineAlignment(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setOverflow(int);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(androidx.wear.tiles.TypeBuilders.StringProp);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Text.Builder setText(String);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.TextAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextOverflowProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.TextOverflowProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.TextOverflowProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.TextOverflowProp.Builder setValue(int);
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.VerticalAlignmentProp {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class LayoutElementBuilders.VerticalAlignmentProp.Builder {
+    ctor @Deprecated public LayoutElementBuilders.VerticalAlignmentProp.Builder();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp build();
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.VerticalAlignmentProp.Builder setValue(int);
+  }
+
+  @Deprecated public final class ModifiersBuilders {
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ArcModifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ArcModifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.ArcModifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ArcModifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Background {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner? getCorner();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Background.Builder {
+    ctor @Deprecated public ModifiersBuilders.Background.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background.Builder setCorner(androidx.wear.tiles.ModifiersBuilders.Corner);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Border {
+    method @Deprecated public androidx.wear.tiles.ColorBuilders.ColorProp? getColor();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getWidth();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Border.Builder {
+    ctor @Deprecated public ModifiersBuilders.Border.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border.Builder setColor(androidx.wear.tiles.ColorBuilders.ColorProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border.Builder setWidth(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Clickable {
+    method @Deprecated public String getId();
+    method @Deprecated public androidx.wear.tiles.ActionBuilders.Action? getOnClick();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Clickable.Builder {
+    ctor @Deprecated public ModifiersBuilders.Clickable.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setId(String);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable.Builder setOnClick(androidx.wear.tiles.ActionBuilders.Action);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Corner {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getRadius();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Corner.Builder {
+    ctor @Deprecated public ModifiersBuilders.Corner.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Corner.Builder setRadius(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ElementMetadata {
+    method @Deprecated public byte[] getTagData();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.ElementMetadata.Builder {
+    ctor @Deprecated public ModifiersBuilders.ElementMetadata.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata.Builder setTagData(byte[]);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Modifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Background? getBackground();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Border? getBorder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.ElementMetadata? getMetadata();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding? getPadding();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics? getSemantics();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Modifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.Modifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBackground(androidx.wear.tiles.ModifiersBuilders.Background);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setBorder(androidx.wear.tiles.ModifiersBuilders.Border);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setMetadata(androidx.wear.tiles.ModifiersBuilders.ElementMetadata);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setPadding(androidx.wear.tiles.ModifiersBuilders.Padding);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Modifiers.Builder setSemantics(androidx.wear.tiles.ModifiersBuilders.Semantics);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Padding {
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getBottom();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getEnd();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp? getRtlAware();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getStart();
+    method @Deprecated public androidx.wear.tiles.DimensionBuilders.DpProp? getTop();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Padding.Builder {
+    ctor @Deprecated public ModifiersBuilders.Padding.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setAll(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setBottom(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setEnd(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(androidx.wear.tiles.TypeBuilders.BoolProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setRtlAware(boolean);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setStart(androidx.wear.tiles.DimensionBuilders.DpProp);
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Padding.Builder setTop(androidx.wear.tiles.DimensionBuilders.DpProp);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Semantics {
+    method @Deprecated public String getContentDescription();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.Semantics.Builder {
+    ctor @Deprecated public ModifiersBuilders.Semantics.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Semantics.Builder setContentDescription(String);
+  }
+
+  @Deprecated public static final class ModifiersBuilders.SpanModifiers {
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.Clickable? getClickable();
+  }
+
+  @Deprecated public static final class ModifiersBuilders.SpanModifiers.Builder {
+    ctor @Deprecated public ModifiersBuilders.SpanModifiers.Builder();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers build();
+    method @Deprecated public androidx.wear.tiles.ModifiersBuilders.SpanModifiers.Builder setClickable(androidx.wear.tiles.ModifiersBuilders.Clickable);
+  }
+
+  public final class RequestBuilders {
+  }
+
+  public static final class RequestBuilders.ResourcesRequest {
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method public java.util.List<java.lang.String!> getResourceIds();
+    method public int getTileId();
+    method public String getVersion();
+  }
+
+  public static final class RequestBuilders.ResourcesRequest.Builder {
+    ctor public RequestBuilders.ResourcesRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder addResourceId(String);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest build();
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setTileId(int);
+    method public androidx.wear.tiles.RequestBuilders.ResourcesRequest.Builder setVersion(String);
+  }
+
+  public static final class RequestBuilders.TileRequest {
+    method public androidx.wear.protolayout.StateBuilders.State getCurrentState();
+    method public androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters getDeviceConfiguration();
+    method @Deprecated public androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters? getDeviceParameters();
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State? getState();
+    method public int getTileId();
+  }
+
+  public static final class RequestBuilders.TileRequest.Builder {
+    ctor public RequestBuilders.TileRequest.Builder();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest build();
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setCurrentState(androidx.wear.protolayout.StateBuilders.State);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceConfiguration(androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setDeviceParameters(androidx.wear.tiles.DeviceParametersBuilders.DeviceParameters);
+    method @Deprecated public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setState(androidx.wear.tiles.StateBuilders.State);
+    method public androidx.wear.tiles.RequestBuilders.TileRequest.Builder setTileId(int);
+  }
+
+  @Deprecated public final class ResourceBuilders {
+    field @Deprecated public static final int IMAGE_FORMAT_RGB_565 = 1; // 0x1
+    field @Deprecated public static final int IMAGE_FORMAT_UNDEFINED = 0; // 0x0
+  }
+
+  @Deprecated public static final class ResourceBuilders.AndroidImageResourceByResId {
+    method @Deprecated @DrawableRes public int getResourceId();
+  }
+
+  @Deprecated public static final class ResourceBuilders.AndroidImageResourceByResId.Builder {
+    ctor @Deprecated public ResourceBuilders.AndroidImageResourceByResId.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId.Builder setResourceId(@DrawableRes int);
+  }
+
+  @Deprecated public static final class ResourceBuilders.ImageResource {
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId? getAndroidResourceByResId();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource? getInlineResource();
+  }
+
+  @Deprecated public static final class ResourceBuilders.ImageResource.Builder {
+    ctor @Deprecated public ResourceBuilders.ImageResource.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setAndroidResourceByResId(androidx.wear.tiles.ResourceBuilders.AndroidImageResourceByResId);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.ImageResource.Builder setInlineResource(androidx.wear.tiles.ResourceBuilders.InlineImageResource);
+  }
+
+  @Deprecated public static final class ResourceBuilders.InlineImageResource {
+    method @Deprecated public byte[] getData();
+    method @Deprecated public int getFormat();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.PX) public int getHeightPx();
+    method @Deprecated @Dimension(unit=androidx.annotation.Dimension.PX) public int getWidthPx();
+  }
+
+  @Deprecated public static final class ResourceBuilders.InlineImageResource.Builder {
+    ctor @Deprecated public ResourceBuilders.InlineImageResource.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setData(byte[]);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setFormat(int);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setHeightPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.InlineImageResource.Builder setWidthPx(@Dimension(unit=androidx.annotation.Dimension.PX) int);
+  }
+
+  @Deprecated public static final class ResourceBuilders.Resources {
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public static androidx.wear.tiles.ResourceBuilders.Resources? fromByteArray(byte[]);
+    method @Deprecated public java.util.Map<java.lang.String!,androidx.wear.tiles.ResourceBuilders.ImageResource!> getIdToImageMapping();
+    method @Deprecated public String getVersion();
+    method @Deprecated @androidx.wear.tiles.TilesExperimental public byte[] toByteArray();
+  }
+
+  @Deprecated public static final class ResourceBuilders.Resources.Builder {
+    ctor @Deprecated public ResourceBuilders.Resources.Builder();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources.Builder addIdToImageMapping(String, androidx.wear.tiles.ResourceBuilders.ImageResource);
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources build();
+    method @Deprecated public androidx.wear.tiles.ResourceBuilders.Resources.Builder setVersion(String);
+  }
+
+  @Deprecated public final class StateBuilders {
+  }
+
+  @Deprecated public static final class StateBuilders.State {
+    method @Deprecated public String getLastClickableId();
+  }
+
+  @Deprecated public static final class StateBuilders.State.Builder {
+    ctor @Deprecated public StateBuilders.State.Builder();
+    method @Deprecated public androidx.wear.tiles.StateBuilders.State build();
+  }
+
+  public final class TileBuilders {
+  }
+
+  public static final class TileBuilders.Tile {
+    method public long getFreshnessIntervalMillis();
+    method public String getResourcesVersion();
+    method public androidx.wear.protolayout.StateBuilders.State? getState();
+    method public androidx.wear.protolayout.TimelineBuilders.Timeline? getTileTimeline();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline? getTimeline();
+  }
+
+  public static final class TileBuilders.Tile.Builder {
+    ctor public TileBuilders.Tile.Builder();
+    method public androidx.wear.tiles.TileBuilders.Tile build();
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setFreshnessIntervalMillis(long);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setResourcesVersion(String);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setState(androidx.wear.protolayout.StateBuilders.State);
+    method public androidx.wear.tiles.TileBuilders.Tile.Builder setTileTimeline(androidx.wear.protolayout.TimelineBuilders.Timeline);
+    method @Deprecated public androidx.wear.tiles.TileBuilders.Tile.Builder setTimeline(androidx.wear.tiles.TimelineBuilders.Timeline);
+  }
+
+  public abstract class TileService extends android.app.Service {
+    ctor public TileService();
+    method public static androidx.wear.tiles.TileUpdateRequester getUpdater(android.content.Context);
+    method public android.os.IBinder? onBind(android.content.Intent);
+    method @Deprecated @MainThread protected com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.ResourceBuilders.Resources!> onResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    method @MainThread protected void onTileAddEvent(androidx.wear.tiles.EventBuilders.TileAddEvent);
+    method @MainThread protected void onTileEnterEvent(androidx.wear.tiles.EventBuilders.TileEnterEvent);
+    method @MainThread protected void onTileLeaveEvent(androidx.wear.tiles.EventBuilders.TileLeaveEvent);
+    method @MainThread protected void onTileRemoveEvent(androidx.wear.tiles.EventBuilders.TileRemoveEvent);
+    method @MainThread protected abstract com.google.common.util.concurrent.ListenableFuture<androidx.wear.tiles.TileBuilders.Tile!> onTileRequest(androidx.wear.tiles.RequestBuilders.TileRequest);
+    method @MainThread protected com.google.common.util.concurrent.ListenableFuture<androidx.wear.protolayout.ResourceBuilders.Resources!> onTileResourcesRequest(androidx.wear.tiles.RequestBuilders.ResourcesRequest);
+    field public static final String ACTION_BIND_TILE_PROVIDER = "androidx.wear.tiles.action.BIND_TILE_PROVIDER";
+    field public static final String EXTRA_CLICKABLE_ID = "androidx.wear.tiles.extra.CLICKABLE_ID";
+    field public static final String METADATA_PREVIEW_KEY = "androidx.wear.tiles.PREVIEW";
+  }
+
+  public interface TileUpdateRequester {
+    method public void requestUpdate(Class<? extends androidx.wear.tiles.TileService>);
+  }
+
+  @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface TilesExperimental {
+  }
+
+  @Deprecated public final class TimelineBuilders {
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimeInterval {
+    method @Deprecated public long getEndMillis();
+    method @Deprecated public long getStartMillis();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimeInterval.Builder {
+    ctor @Deprecated public TimelineBuilders.TimeInterval.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval build();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setEndMillis(long);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval.Builder setStartMillis(long);
+  }
+
+  @Deprecated public static final class TimelineBuilders.Timeline {
+    method @Deprecated public static androidx.wear.tiles.TimelineBuilders.Timeline fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public java.util.List<androidx.wear.tiles.TimelineBuilders.TimelineEntry!> getTimelineEntries();
+  }
+
+  @Deprecated public static final class TimelineBuilders.Timeline.Builder {
+    ctor @Deprecated public TimelineBuilders.Timeline.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline.Builder addTimelineEntry(androidx.wear.tiles.TimelineBuilders.TimelineEntry);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.Timeline build();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimelineEntry {
+    method @Deprecated public static androidx.wear.tiles.TimelineBuilders.TimelineEntry fromLayoutElement(androidx.wear.tiles.LayoutElementBuilders.LayoutElement);
+    method @Deprecated public androidx.wear.tiles.LayoutElementBuilders.Layout? getLayout();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimeInterval? getValidity();
+  }
+
+  @Deprecated public static final class TimelineBuilders.TimelineEntry.Builder {
+    ctor @Deprecated public TimelineBuilders.TimelineEntry.Builder();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry build();
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setLayout(androidx.wear.tiles.LayoutElementBuilders.Layout);
+    method @Deprecated public androidx.wear.tiles.TimelineBuilders.TimelineEntry.Builder setValidity(androidx.wear.tiles.TimelineBuilders.TimeInterval);
+  }
+
+  @Deprecated public final class TypeBuilders {
+  }
+
+  @Deprecated public static final class TypeBuilders.BoolProp {
+    method @Deprecated public boolean getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.BoolProp.Builder {
+    ctor @Deprecated public TypeBuilders.BoolProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.BoolProp.Builder setValue(boolean);
+  }
+
+  @Deprecated public static final class TypeBuilders.FloatProp {
+    method @Deprecated public float getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.FloatProp.Builder {
+    ctor @Deprecated public TypeBuilders.FloatProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.FloatProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.FloatProp.Builder setValue(float);
+  }
+
+  @Deprecated public static final class TypeBuilders.Int32Prop {
+    method @Deprecated public int getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.Int32Prop.Builder {
+    ctor @Deprecated public TypeBuilders.Int32Prop.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.Int32Prop.Builder setValue(int);
+  }
+
+  @Deprecated public static final class TypeBuilders.StringProp {
+    method @Deprecated public String getValue();
+  }
+
+  @Deprecated public static final class TypeBuilders.StringProp.Builder {
+    ctor @Deprecated public TypeBuilders.StringProp.Builder();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp build();
+    method @Deprecated public androidx.wear.tiles.TypeBuilders.StringProp.Builder setValue(String);
+  }
+
+}
+
diff --git a/wear/tiles/tiles/src/test/resources/robolectric.properties b/wear/tiles/tiles/src/test/resources/robolectric.properties
index 27d4acf..69fde47 100644
--- a/wear/tiles/tiles/src/test/resources/robolectric.properties
+++ b/wear/tiles/tiles/src/test/resources/robolectric.properties
@@ -1,18 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
 # robolectric properties
-
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-client/src/test/resources/robolectric.properties b/wear/watchface/watchface-client/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/wear/watchface/watchface-client/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-client/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-complications-data-source-ktx/src/test/resources/robolectric.properties b/wear/watchface/watchface-complications-data-source-ktx/src/test/resources/robolectric.properties
index 4b7155e..69fde47 100644
--- a/wear/watchface/watchface-complications-data-source-ktx/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-complications-data-source-ktx/src/test/resources/robolectric.properties
@@ -1,17 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-complications-data-source/src/test/resources/robolectric.properties b/wear/watchface/watchface-complications-data-source/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/wear/watchface/watchface-complications-data-source/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-complications-data-source/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-complications-data/src/test/resources/robolectric.properties b/wear/watchface/watchface-complications-data/src/test/resources/robolectric.properties
index ce87047..69fde47 100644
--- a/wear/watchface/watchface-complications-data/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-complications-data/src/test/resources/robolectric.properties
@@ -1,3 +1,3 @@
-# Robolectric currently doesn't support API 30, so we have to explicitly specify 29 as the target
-# sdk for now. Remove when no longer necessary.
-sdk=29
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
index ecf03eb..1313236 100644
--- a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
+++ b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
@@ -23,18 +23,10 @@
 }
 
 dependencies {
-    compileOnly(project(":annotation:annotation-sampled"))
     api("androidx.fragment:fragment:1.2.0")
     api(libs.kotlinStdlib)
 }
 
-androidx {
-    name = "Wear Watchface Permission Dialog Samples"
-    type = LibraryType.SAMPLES
-    inceptionYear = "2021"
-    description = "Contains sample code for building Watchface Permission Dialogs"
-}
-
 android {
     defaultConfig {
         minSdkVersion 26
diff --git a/wear/watchface/watchface-complications-rendering/src/test/resources/robolectric.properties b/wear/watchface/watchface-complications-rendering/src/test/resources/robolectric.properties
index ce87047..69fde47 100644
--- a/wear/watchface/watchface-complications-rendering/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-complications-rendering/src/test/resources/robolectric.properties
@@ -1,3 +1,3 @@
-# Robolectric currently doesn't support API 30, so we have to explicitly specify 29 as the target
-# sdk for now. Remove when no longer necessary.
-sdk=29
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-complications/src/test/resources/robolectric.properties b/wear/watchface/watchface-complications/src/test/resources/robolectric.properties
index ce87047..34d9449 100644
--- a/wear/watchface/watchface-complications/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-complications/src/test/resources/robolectric.properties
@@ -1,3 +1,3 @@
-# Robolectric currently doesn't support API 30, so we have to explicitly specify 29 as the target
-# sdk for now. Remove when no longer necessary.
+# robolectric properties
+# Temporary until Wear team fixes their tests to work against sdk=33 (b/281072091).
 sdk=29
diff --git a/wear/watchface/watchface-editor/samples/build.gradle b/wear/watchface/watchface-editor/samples/build.gradle
index 4fa0e56..aeeaa59 100644
--- a/wear/watchface/watchface-editor/samples/build.gradle
+++ b/wear/watchface/watchface-editor/samples/build.gradle
@@ -24,23 +24,15 @@
 }
 
 dependencies {
-    compileOnly(project(":annotation:annotation-sampled"))
     api("androidx.fragment:fragment:1.3.0")
     implementation("androidx.wear:wear:1.1.0-rc01")
     api(project(":wear:watchface:watchface-editor"))
     api(libs.kotlinStdlib)
 }
 
-androidx {
-    name = "Wear Editor Samples"
-    type = LibraryType.SAMPLES
-    inceptionYear = "2020"
-    description = "Contains sample code for the Androidx Wear Editor library"
-}
-
 android {
     defaultConfig {
         minSdkVersion 26
     }
     namespace "androidx.wear.watchface.editor.samples"
-}
\ No newline at end of file
+}
diff --git a/wear/watchface/watchface-guava/src/test/resources/robolectric.properties b/wear/watchface/watchface-guava/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/wear/watchface/watchface-guava/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-guava/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface-style/src/test/resources/robolectric.properties b/wear/watchface/watchface-style/src/test/resources/robolectric.properties
index 80e2a6f..69fde47 100644
--- a/wear/watchface/watchface-style/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface-style/src/test/resources/robolectric.properties
@@ -1 +1,3 @@
 # robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/watchface/watchface/src/test/resources/robolectric.properties b/wear/watchface/watchface/src/test/resources/robolectric.properties
index ce87047..69fde47 100644
--- a/wear/watchface/watchface/src/test/resources/robolectric.properties
+++ b/wear/watchface/watchface/src/test/resources/robolectric.properties
@@ -1,3 +1,3 @@
-# Robolectric currently doesn't support API 30, so we have to explicitly specify 29 as the target
-# sdk for now. Remove when no longer necessary.
-sdk=29
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/wear-input/src/test/resources/robolectric.properties b/wear/wear-input/src/test/resources/robolectric.properties
index 4b7155e..69fde47 100644
--- a/wear/wear-input/src/test/resources/robolectric.properties
+++ b/wear/wear-input/src/test/resources/robolectric.properties
@@ -1,17 +1,3 @@
-#
-# Copyright 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# robolectric properties
\ No newline at end of file
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
index 23cfd65..c564a62 100644
--- a/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
+++ b/wear/wear-phone-interactions/src/main/java/androidx/wear/phone/interactions/authentication/RemoteAuthClient.kt
@@ -161,11 +161,11 @@
             return RemoteAuthClient(
                 object : ServiceBinder {
                     override fun bindService(
-                        intent: Intent?,
-                        connection: ServiceConnection?,
+                        intent: Intent,
+                        connection: ServiceConnection,
                         flags: Int
                     ): Boolean {
-                        return appContext.bindService(intent, connection!!, flags)
+                        return appContext.bindService(intent, connection, flags)
                     }
 
                     override fun unbindService(connection: ServiceConnection?) {
@@ -276,7 +276,7 @@
 
     internal interface ServiceBinder {
         /** See [Context.bindService].  */
-        fun bindService(intent: Intent?, connection: ServiceConnection?, flags: Int): Boolean
+        fun bindService(intent: Intent, connection: ServiceConnection, flags: Int): Boolean
 
         /** See [Context.unbindService].  */
         fun unbindService(connection: ServiceConnection?)
diff --git a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
index 1f175a9..f53fb50 100644
--- a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
+++ b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
@@ -209,11 +209,11 @@
         var state = ConnectionState.DISCONNECTED
         private var serviceConnection: ServiceConnection? = null
         override fun bindService(
-            intent: Intent?,
-            connection: ServiceConnection?,
+            intent: Intent,
+            connection: ServiceConnection,
             flags: Int
         ): Boolean {
-            if (intent!!.getPackage() != RemoteAuthClient.WEARABLE_PACKAGE_NAME) {
+            if (intent.getPackage() != RemoteAuthClient.WEARABLE_PACKAGE_NAME) {
                 throw UnsupportedOperationException()
             }
             if (intent.action != RemoteAuthClient.ACTION_AUTH) {
diff --git a/wear/wear/src/test/resources/robolectric.properties b/wear/wear/src/test/resources/robolectric.properties
new file mode 100644
index 0000000..69fde47
--- /dev/null
+++ b/wear/wear/src/test/resources/robolectric.properties
@@ -0,0 +1,3 @@
+# robolectric properties
+# Temporary until we update Robolectric to support API level 34.
+sdk=33
diff --git a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/AssetLoaderAjaxActivityTestAppTest.java b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/AssetLoaderAjaxActivityTestAppTest.java
index 7325510..a84374d 100644
--- a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/AssetLoaderAjaxActivityTestAppTest.java
+++ b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/AssetLoaderAjaxActivityTestAppTest.java
@@ -20,10 +20,10 @@
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,10 +52,10 @@
                 activity.getUriIdlingResource()));
     }
 
-    @Ignore("b/283485965")
     @Test
     public void testAssetLoaderAjaxActivity() {
-        mRule.getScenario().onActivity(activity -> activity.loadUrl());
+        mRule.getScenario().onActivity(AssetLoaderAjaxActivity::loadUrl);
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
         WebkitTestHelpers.assertHtmlElementContainsText(R.id.webview_asset_loader_webview,
                 "title", "Loaded HTML should appear below on success");
         WebkitTestHelpers.assertHtmlElementContainsText(R.id.webview_asset_loader_webview,
diff --git a/webkit/webkit/api/1.6.0-beta02.txt b/webkit/webkit/api/1.6.0-beta02.txt
deleted file mode 100644
index faf13cb..0000000
--- a/webkit/webkit/api/1.6.0-beta02.txt
+++ /dev/null
@@ -1,300 +0,0 @@
-// Signature format: 4.0
-package androidx.webkit {
-
-  public class CookieManagerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_COOKIE_INFO, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.List<java.lang.String!> getCookieInfo(android.webkit.CookieManager, String);
-  }
-
-  public abstract class JavaScriptReplyProxy {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
-  }
-
-  public class ProcessGlobalConfig {
-    ctor public ProcessGlobalConfig();
-    method public static void apply(androidx.webkit.ProcessGlobalConfig);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDataDirectorySuffix(android.content.Context, String);
-  }
-
-  public final class ProxyConfig {
-    method public java.util.List<java.lang.String!> getBypassRules();
-    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
-    method public boolean isReverseBypassEnabled();
-    field public static final String MATCH_ALL_SCHEMES = "*";
-    field public static final String MATCH_HTTP = "http";
-    field public static final String MATCH_HTTPS = "https";
-  }
-
-  public static final class ProxyConfig.Builder {
-    ctor public ProxyConfig.Builder();
-    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
-    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect();
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
-    method public androidx.webkit.ProxyConfig build();
-    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
-    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.ProxyConfig.Builder setReverseBypassEnabled(boolean);
-  }
-
-  public static final class ProxyConfig.ProxyRule {
-    method public String getSchemeFilter();
-    method public String getUrl();
-  }
-
-  public abstract class ProxyController {
-    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
-    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
-  }
-
-  public abstract class SafeBrowsingResponseCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
-  }
-
-  public abstract class ServiceWorkerClientCompat {
-    ctor public ServiceWorkerClientCompat();
-    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
-  }
-
-  public abstract class ServiceWorkerControllerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
-    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
-    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
-  }
-
-  public abstract class ServiceWorkerWebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setRequestedWithHeaderOriginAllowList(java.util.Set<java.lang.String!>);
-  }
-
-  public class TracingConfig {
-    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
-    method public int getPredefinedCategories();
-    method public int getTracingMode();
-    field public static final int CATEGORIES_ALL = 1; // 0x1
-    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
-    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
-    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
-    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
-    field public static final int CATEGORIES_NONE = 0; // 0x0
-    field public static final int CATEGORIES_RENDERING = 16; // 0x10
-    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
-    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
-    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
-  }
-
-  public static class TracingConfig.Builder {
-    ctor public TracingConfig.Builder();
-    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
-    method public androidx.webkit.TracingConfig build();
-    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
-  }
-
-  public abstract class TracingController {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
-    method public abstract boolean isTracing();
-    method public abstract void start(androidx.webkit.TracingConfig);
-    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
-  }
-
-  public class WebMessageCompat {
-    ctor public WebMessageCompat(String?);
-    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
-    method public String? getData();
-    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
-  }
-
-  public abstract class WebMessagePortCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-  }
-
-  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
-    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
-    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
-  }
-
-  public abstract class WebResourceErrorCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
-  }
-
-  public class WebResourceRequestCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
-  }
-
-  public class WebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings, boolean);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
-    field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
-    field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
-    field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_AUTO = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_OFF = 0; // 0x0
-    field @Deprecated public static final int FORCE_DARK_ON = 2; // 0x2
-  }
-
-  public final class WebViewAssetLoader {
-    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
-    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
-  }
-
-  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.Builder {
-    ctor public WebViewAssetLoader.Builder();
-    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
-    method public androidx.webkit.WebViewAssetLoader build();
-    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
-    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
-  }
-
-  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
-    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
-  }
-
-  public static interface WebViewAssetLoader.PathHandler {
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public class WebViewClientCompat extends android.webkit.WebViewClient {
-    ctor public WebViewClientCompat();
-    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
-    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
-    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
-    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
-  }
-
-  public class WebViewCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
-    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_VARIATIONS_HEADER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static String getVariationsHeader();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ALLOWLIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingAllowlist(java.util.Set<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
-  }
-
-  public static interface WebViewCompat.VisualStateCallback {
-    method @UiThread public void onComplete(long);
-  }
-
-  public static interface WebViewCompat.WebMessageListener {
-    method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
-  }
-
-  public class WebViewFeature {
-    method public static boolean isFeatureSupported(String);
-    method public static boolean isStartupFeatureSupported(android.content.Context, String);
-    field public static final String ALGORITHMIC_DARKENING = "ALGORITHMIC_DARKENING";
-    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
-    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
-    field public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
-    field public static final String FORCE_DARK = "FORCE_DARK";
-    field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
-    field public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
-    field public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER";
-    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
-    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
-    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
-    field public static final String MULTI_PROCESS = "MULTI_PROCESS";
-    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
-    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
-    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
-    field public static final String PROXY_OVERRIDE_REVERSE_BYPASS = "PROXY_OVERRIDE_REVERSE_BYPASS";
-    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
-    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
-    field public static final String SAFE_BROWSING_ALLOWLIST = "SAFE_BROWSING_ALLOWLIST";
-    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
-    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
-    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
-    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
-    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
-    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
-    field @Deprecated public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
-    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
-    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
-    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
-    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
-    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
-    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
-    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
-    field public static final String STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX = "STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX";
-    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
-    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
-    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
-    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
-    field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
-    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
-    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
-    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
-    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
-    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
-    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
-    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
-    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
-  }
-
-  public abstract class WebViewRenderProcess {
-    ctor public WebViewRenderProcess();
-    method public abstract boolean terminate();
-  }
-
-  public abstract class WebViewRenderProcessClient {
-    ctor public WebViewRenderProcessClient();
-    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-  }
-
-}
-
diff --git a/webkit/webkit/api/public_plus_experimental_1.6.0-beta02.txt b/webkit/webkit/api/public_plus_experimental_1.6.0-beta02.txt
deleted file mode 100644
index faf13cb..0000000
--- a/webkit/webkit/api/public_plus_experimental_1.6.0-beta02.txt
+++ /dev/null
@@ -1,300 +0,0 @@
-// Signature format: 4.0
-package androidx.webkit {
-
-  public class CookieManagerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_COOKIE_INFO, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.List<java.lang.String!> getCookieInfo(android.webkit.CookieManager, String);
-  }
-
-  public abstract class JavaScriptReplyProxy {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
-  }
-
-  public class ProcessGlobalConfig {
-    ctor public ProcessGlobalConfig();
-    method public static void apply(androidx.webkit.ProcessGlobalConfig);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDataDirectorySuffix(android.content.Context, String);
-  }
-
-  public final class ProxyConfig {
-    method public java.util.List<java.lang.String!> getBypassRules();
-    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
-    method public boolean isReverseBypassEnabled();
-    field public static final String MATCH_ALL_SCHEMES = "*";
-    field public static final String MATCH_HTTP = "http";
-    field public static final String MATCH_HTTPS = "https";
-  }
-
-  public static final class ProxyConfig.Builder {
-    ctor public ProxyConfig.Builder();
-    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
-    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect();
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
-    method public androidx.webkit.ProxyConfig build();
-    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
-    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.ProxyConfig.Builder setReverseBypassEnabled(boolean);
-  }
-
-  public static final class ProxyConfig.ProxyRule {
-    method public String getSchemeFilter();
-    method public String getUrl();
-  }
-
-  public abstract class ProxyController {
-    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
-    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
-  }
-
-  public abstract class SafeBrowsingResponseCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
-  }
-
-  public abstract class ServiceWorkerClientCompat {
-    ctor public ServiceWorkerClientCompat();
-    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
-  }
-
-  public abstract class ServiceWorkerControllerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
-    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
-    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
-  }
-
-  public abstract class ServiceWorkerWebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setRequestedWithHeaderOriginAllowList(java.util.Set<java.lang.String!>);
-  }
-
-  public class TracingConfig {
-    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
-    method public int getPredefinedCategories();
-    method public int getTracingMode();
-    field public static final int CATEGORIES_ALL = 1; // 0x1
-    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
-    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
-    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
-    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
-    field public static final int CATEGORIES_NONE = 0; // 0x0
-    field public static final int CATEGORIES_RENDERING = 16; // 0x10
-    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
-    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
-    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
-  }
-
-  public static class TracingConfig.Builder {
-    ctor public TracingConfig.Builder();
-    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
-    method public androidx.webkit.TracingConfig build();
-    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
-  }
-
-  public abstract class TracingController {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
-    method public abstract boolean isTracing();
-    method public abstract void start(androidx.webkit.TracingConfig);
-    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
-  }
-
-  public class WebMessageCompat {
-    ctor public WebMessageCompat(String?);
-    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
-    method public String? getData();
-    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
-  }
-
-  public abstract class WebMessagePortCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-  }
-
-  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
-    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
-    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
-  }
-
-  public abstract class WebResourceErrorCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
-  }
-
-  public class WebResourceRequestCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
-  }
-
-  public class WebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings, boolean);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
-    field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
-    field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
-    field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_AUTO = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_OFF = 0; // 0x0
-    field @Deprecated public static final int FORCE_DARK_ON = 2; // 0x2
-  }
-
-  public final class WebViewAssetLoader {
-    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
-    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
-  }
-
-  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.Builder {
-    ctor public WebViewAssetLoader.Builder();
-    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
-    method public androidx.webkit.WebViewAssetLoader build();
-    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
-    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
-  }
-
-  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
-    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
-  }
-
-  public static interface WebViewAssetLoader.PathHandler {
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public class WebViewClientCompat extends android.webkit.WebViewClient {
-    ctor public WebViewClientCompat();
-    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
-    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
-    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
-    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
-  }
-
-  public class WebViewCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
-    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_VARIATIONS_HEADER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static String getVariationsHeader();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ALLOWLIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingAllowlist(java.util.Set<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
-  }
-
-  public static interface WebViewCompat.VisualStateCallback {
-    method @UiThread public void onComplete(long);
-  }
-
-  public static interface WebViewCompat.WebMessageListener {
-    method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
-  }
-
-  public class WebViewFeature {
-    method public static boolean isFeatureSupported(String);
-    method public static boolean isStartupFeatureSupported(android.content.Context, String);
-    field public static final String ALGORITHMIC_DARKENING = "ALGORITHMIC_DARKENING";
-    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
-    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
-    field public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
-    field public static final String FORCE_DARK = "FORCE_DARK";
-    field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
-    field public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
-    field public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER";
-    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
-    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
-    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
-    field public static final String MULTI_PROCESS = "MULTI_PROCESS";
-    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
-    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
-    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
-    field public static final String PROXY_OVERRIDE_REVERSE_BYPASS = "PROXY_OVERRIDE_REVERSE_BYPASS";
-    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
-    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
-    field public static final String SAFE_BROWSING_ALLOWLIST = "SAFE_BROWSING_ALLOWLIST";
-    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
-    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
-    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
-    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
-    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
-    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
-    field @Deprecated public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
-    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
-    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
-    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
-    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
-    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
-    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
-    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
-    field public static final String STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX = "STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX";
-    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
-    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
-    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
-    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
-    field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
-    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
-    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
-    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
-    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
-    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
-    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
-    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
-    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
-  }
-
-  public abstract class WebViewRenderProcess {
-    ctor public WebViewRenderProcess();
-    method public abstract boolean terminate();
-  }
-
-  public abstract class WebViewRenderProcessClient {
-    ctor public WebViewRenderProcessClient();
-    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-  }
-
-}
-
diff --git a/webkit/webkit/api/restricted_1.6.0-beta02.txt b/webkit/webkit/api/restricted_1.6.0-beta02.txt
deleted file mode 100644
index faf13cb..0000000
--- a/webkit/webkit/api/restricted_1.6.0-beta02.txt
+++ /dev/null
@@ -1,300 +0,0 @@
-// Signature format: 4.0
-package androidx.webkit {
-
-  public class CookieManagerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_COOKIE_INFO, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.List<java.lang.String!> getCookieInfo(android.webkit.CookieManager, String);
-  }
-
-  public abstract class JavaScriptReplyProxy {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
-  }
-
-  public class ProcessGlobalConfig {
-    ctor public ProcessGlobalConfig();
-    method public static void apply(androidx.webkit.ProcessGlobalConfig);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX, enforcement="androidx.webkit.WebViewFeature#isConfigFeatureSupported(String, Context)") public androidx.webkit.ProcessGlobalConfig setDataDirectorySuffix(android.content.Context, String);
-  }
-
-  public final class ProxyConfig {
-    method public java.util.List<java.lang.String!> getBypassRules();
-    method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
-    method public boolean isReverseBypassEnabled();
-    field public static final String MATCH_ALL_SCHEMES = "*";
-    field public static final String MATCH_HTTP = "http";
-    field public static final String MATCH_HTTPS = "https";
-  }
-
-  public static final class ProxyConfig.Builder {
-    ctor public ProxyConfig.Builder();
-    ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
-    method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect(String);
-    method public androidx.webkit.ProxyConfig.Builder addDirect();
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
-    method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
-    method public androidx.webkit.ProxyConfig build();
-    method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
-    method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE_REVERSE_BYPASS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public androidx.webkit.ProxyConfig.Builder setReverseBypassEnabled(boolean);
-  }
-
-  public static final class ProxyConfig.ProxyRule {
-    method public String getSchemeFilter();
-    method public String getUrl();
-  }
-
-  public abstract class ProxyController {
-    method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
-    method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
-  }
-
-  public abstract class SafeBrowsingResponseCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
-  }
-
-  public abstract class ServiceWorkerClientCompat {
-    ctor public ServiceWorkerClientCompat();
-    method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
-  }
-
-  public abstract class ServiceWorkerControllerCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
-    method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
-    method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
-  }
-
-  public abstract class ServiceWorkerWebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setRequestedWithHeaderOriginAllowList(java.util.Set<java.lang.String!>);
-  }
-
-  public class TracingConfig {
-    method public java.util.List<java.lang.String!> getCustomIncludedCategories();
-    method public int getPredefinedCategories();
-    method public int getTracingMode();
-    field public static final int CATEGORIES_ALL = 1; // 0x1
-    field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
-    field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
-    field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
-    field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
-    field public static final int CATEGORIES_NONE = 0; // 0x0
-    field public static final int CATEGORIES_RENDERING = 16; // 0x10
-    field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
-    field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
-    field public static final int RECORD_UNTIL_FULL = 0; // 0x0
-  }
-
-  public static class TracingConfig.Builder {
-    ctor public TracingConfig.Builder();
-    method public androidx.webkit.TracingConfig.Builder addCategories(int...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
-    method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
-    method public androidx.webkit.TracingConfig build();
-    method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
-  }
-
-  public abstract class TracingController {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
-    method public abstract boolean isTracing();
-    method public abstract void start(androidx.webkit.TracingConfig);
-    method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
-  }
-
-  public class WebMessageCompat {
-    ctor public WebMessageCompat(String?);
-    ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
-    method public String? getData();
-    method public androidx.webkit.WebMessagePortCompat![]? getPorts();
-  }
-
-  public abstract class WebMessagePortCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
-  }
-
-  public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
-    ctor public WebMessagePortCompat.WebMessageCallbackCompat();
-    method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
-  }
-
-  public abstract class WebResourceErrorCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
-  }
-
-  public class WebResourceRequestCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
-  }
-
-  public class WebSettingsCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static java.util.Set<java.lang.String!> getRequestedWithHeaderOriginAllowList(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isAlgorithmicDarkeningAllowed(android.webkit.WebSettings);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ALGORITHMIC_DARKENING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setAlgorithmicDarkeningAllowed(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setEnterpriseAuthenticationAppLinkPolicyEnabled(android.webkit.WebSettings, boolean);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
-    method @RequiresFeature(name="REQUESTED_WITH_HEADER_ALLOW_LIST", enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setRequestedWithHeaderOriginAllowList(android.webkit.WebSettings, java.util.Set<java.lang.String!>);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
-    field @Deprecated public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
-    field @Deprecated public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
-    field @Deprecated public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_AUTO = 1; // 0x1
-    field @Deprecated public static final int FORCE_DARK_OFF = 0; // 0x0
-    field @Deprecated public static final int FORCE_DARK_ON = 2; // 0x2
-  }
-
-  public final class WebViewAssetLoader {
-    method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
-    field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
-  }
-
-  public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.Builder {
-    ctor public WebViewAssetLoader.Builder();
-    method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
-    method public androidx.webkit.WebViewAssetLoader build();
-    method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
-    method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
-  }
-
-  public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
-    method @WorkerThread public android.webkit.WebResourceResponse handle(String);
-  }
-
-  public static interface WebViewAssetLoader.PathHandler {
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
-    ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
-    method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
-  }
-
-  public class WebViewClientCompat extends android.webkit.WebViewClient {
-    ctor public WebViewClientCompat();
-    method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
-    method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
-    method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
-    method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
-  }
-
-  public class WebViewCompat {
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
-    method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_VARIATIONS_HEADER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static String getVariationsHeader();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ALLOWLIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingAllowlist(java.util.Set<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @Deprecated @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
-    method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
-  }
-
-  public static interface WebViewCompat.VisualStateCallback {
-    method @UiThread public void onComplete(long);
-  }
-
-  public static interface WebViewCompat.WebMessageListener {
-    method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
-  }
-
-  public class WebViewFeature {
-    method public static boolean isFeatureSupported(String);
-    method public static boolean isStartupFeatureSupported(android.content.Context, String);
-    field public static final String ALGORITHMIC_DARKENING = "ALGORITHMIC_DARKENING";
-    field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
-    field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
-    field public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY = "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
-    field public static final String FORCE_DARK = "FORCE_DARK";
-    field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
-    field public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
-    field public static final String GET_VARIATIONS_HEADER = "GET_VARIATIONS_HEADER";
-    field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
-    field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
-    field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
-    field public static final String MULTI_PROCESS = "MULTI_PROCESS";
-    field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
-    field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
-    field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
-    field public static final String PROXY_OVERRIDE_REVERSE_BYPASS = "PROXY_OVERRIDE_REVERSE_BYPASS";
-    field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
-    field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
-    field public static final String SAFE_BROWSING_ALLOWLIST = "SAFE_BROWSING_ALLOWLIST";
-    field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
-    field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
-    field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
-    field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
-    field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
-    field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
-    field @Deprecated public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
-    field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
-    field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
-    field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
-    field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
-    field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
-    field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
-    field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
-    field public static final String STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX = "STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX";
-    field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
-    field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
-    field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
-    field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
-    field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
-    field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
-    field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
-    field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
-    field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
-    field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
-    field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
-    field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
-    field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
-  }
-
-  public abstract class WebViewRenderProcess {
-    ctor public WebViewRenderProcess();
-    method public abstract boolean terminate();
-  }
-
-  public abstract class WebViewRenderProcessClient {
-    ctor public WebViewRenderProcessClient();
-    method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-    method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
-  }
-
-}
-
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaPresentation.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaPresentation.java
index ddb8e8a..0ce24b8 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaPresentation.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaPresentation.java
@@ -25,7 +25,7 @@
  * An interface representing a container in an extension window area in which app content can be
  * shown.
  *
- * @since {@link androidx.window.extensions.WindowExtensions#VENDOR_API_LEVEL_3}
+ * Since {@link androidx.window.extensions.WindowExtensions#VENDOR_API_LEVEL_3}
  * @see WindowAreaComponent#getRearDisplayPresentation()
  */
 public interface ExtensionWindowAreaPresentation {
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaStatus.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaStatus.java
index 2f521bc..0dcd47f 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaStatus.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/ExtensionWindowAreaStatus.java
@@ -23,7 +23,7 @@
 /**
  * Interface to provide information around the current status of a window area feature.
  *
- * @since {@link androidx.window.extensions.WindowExtensions#VENDOR_API_LEVEL_3}
+ * Since {@link androidx.window.extensions.WindowExtensions#VENDOR_API_LEVEL_3}
  * @see WindowAreaComponent#addRearDisplayPresentationStatusListener
  */
 public interface ExtensionWindowAreaStatus {
diff --git a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
index e20584c..e5705ac 100644
--- a/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
+++ b/window/extensions/extensions/src/main/java/androidx/window/extensions/area/WindowAreaComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2023 The Android Open Source Project
+ * Copyright 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@
  * @see WindowExtensions#getWindowLayoutComponent()
  */
 public interface WindowAreaComponent {
+
     /**
      * WindowArea status constant to signify that the feature is
      * unsupported on this device. Could be due to the device not supporting that
diff --git a/window/extensions/extensions/src/test/resources/robolectric.properties b/window/extensions/extensions/src/test/resources/robolectric.properties
index 69fde47..34f4360 100644
--- a/window/extensions/extensions/src/test/resources/robolectric.properties
+++ b/window/extensions/extensions/src/test/resources/robolectric.properties
@@ -1,3 +1,5 @@
 # robolectric properties
+# Used for calling Android API, ex: Color.Blue
+# The value cannot be reported without using robolectric.
 # Temporary until we update Robolectric to support API level 34.
 sdk=33
diff --git a/window/window-demos/demo/src/main/AndroidManifest.xml b/window/window-demos/demo/src/main/AndroidManifest.xml
index dff69ac..230cb82 100644
--- a/window/window-demos/demo/src/main/AndroidManifest.xml
+++ b/window/window-demos/demo/src/main/AndroidManifest.xml
@@ -220,6 +220,34 @@
             android:taskAffinity="androidx.window.demo.split_device_state_activity_affinity">
         </activity>
 
+        <!-- The demo app to show how to change layout with runtime APIs -->
+        <activity
+            android:name=".embedding.SplitAttributesToggleMainActivity"
+            android:exported="true"
+            android:label="Split Toggle at Runtime"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen"
+            android:taskAffinity="androidx.window.demo.split_attributes_toggle_activity_affinity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity
+            android:name=".embedding.SplitAttributesTogglePrimaryActivity"
+            android:label="Split Toggle Activity A"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen"
+            android:taskAffinity="androidx.window.demo.split_attributes_toggle_activity_affinity" />
+        <activity
+            android:name=".embedding.SplitAttributesToggleSecondaryActivity"
+            android:label="Split Toggle Activity B"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen"
+            android:taskAffinity="androidx.window.demo.split_attributes_toggle_activity_affinity" />
+        <activity
+            android:name=".embedding.SplitAttributesTogglePlaceholderActivity"
+            android:label="Split Toggle Placeholder"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density|touchscreen"
+            android:taskAffinity="androidx.window.demo.split_attributes_toggle_activity_affinity" />
+
         <!-- The demo app that shows various IME-related use cases -->
 
         <activity android:name=".ImeActivity"
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateCallbackActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateCallbackActivity.kt
index bd39f74..2122cbd 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateCallbackActivity.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateCallbackActivity.kt
@@ -16,6 +16,7 @@
 
 package androidx.window.demo.coresdk
 
+import android.content.ComponentCallbacks
 import android.content.Context
 import android.content.res.Configuration
 import android.hardware.display.DisplayManager
@@ -36,11 +37,18 @@
 /** Activity to show display configuration from different system callbacks. */
 class WindowStateCallbackActivity : AppCompatActivity() {
 
-    private lateinit var displayManager: DisplayManager
+    /**
+     * [DisplayManager]s from `Activity` and `Application` are updated from different resource
+     * configurations, so we listen on them separately.
+     */
+    private lateinit var applicationDisplayManager: DisplayManager
+    private lateinit var activityDisplayManager: DisplayManager
     private lateinit var handler: Handler
 
     private lateinit var latestUpdateView: WindowStateView
-    private lateinit var displayListenerView: WindowStateView
+    private lateinit var applicationDisplayListenerView: WindowStateView
+    private lateinit var activityDisplayListenerView: WindowStateView
+    private lateinit var applicationConfigurationView: WindowStateView
     private lateinit var activityConfigurationView: WindowStateView
     private lateinit var displayFeatureView: WindowStateView
 
@@ -56,7 +64,8 @@
         }
     }
 
-    private val displayListener = object : DisplayListener {
+    /** [DisplayListener] on `Application`. */
+    private val applicationDisplayListener = object : DisplayListener {
         override fun onDisplayAdded(displayId: Int) {
         }
 
@@ -65,23 +74,55 @@
 
         override fun onDisplayChanged(displayId: Int) {
             if (displayId == DEFAULT_DISPLAY) {
-                displayListenerView.onWindowStateCallbackInvoked()
+                applicationDisplayListenerView.onWindowStateCallbackInvoked()
             }
         }
     }
 
+    /** [DisplayListener] on `Activity`. */
+    private val activityDisplayListener = object : DisplayListener {
+        override fun onDisplayAdded(displayId: Int) {
+        }
+
+        override fun onDisplayRemoved(displayId: Int) {
+        }
+
+        override fun onDisplayChanged(displayId: Int) {
+            if (displayId == DEFAULT_DISPLAY) {
+                activityDisplayListenerView.onWindowStateCallbackInvoked()
+            }
+        }
+    }
+
+    /** [onConfigurationChanged] on `Application`. */
+    private val applicationComponentCallback = object : ComponentCallbacks {
+        override fun onConfigurationChanged(p0: Configuration) {
+            applicationConfigurationView.onWindowStateCallbackInvoked()
+        }
+
+        override fun onLowMemory() {
+        }
+    }
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         val viewBinding = ActivityCoresdkWindowStateCallbackLayoutBinding.inflate(layoutInflater)
         setContentView(viewBinding.root)
         latestUpdateView = viewBinding.latestUpdateView
-        displayListenerView = viewBinding.displayListenerView
+        applicationDisplayListenerView = viewBinding.applicationDisplayListenerView
+        activityDisplayListenerView = viewBinding.activityDisplayListenerView
+        applicationConfigurationView = viewBinding.applicationConfigurationView
         activityConfigurationView = viewBinding.activityConfigurationView
         displayFeatureView = viewBinding.displayFeatureView
 
-        displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+        applicationDisplayManager =
+            application.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+        activityDisplayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
         handler = Handler(Looper.getMainLooper())
-        displayManager.registerDisplayListener(displayListener, handler)
+
+        applicationDisplayManager.registerDisplayListener(applicationDisplayListener, handler)
+        activityDisplayManager.registerDisplayListener(activityDisplayListener, handler)
+        application.registerComponentCallbacks(applicationComponentCallback)
         // Collect windowInfo when STARTED and stop when STOPPED.
         lifecycleScope.launch(Dispatchers.Main) {
             lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
@@ -96,7 +137,9 @@
 
     override fun onDestroy() {
         super.onDestroy()
-        displayManager.unregisterDisplayListener(displayListener)
+        applicationDisplayManager.unregisterDisplayListener(applicationDisplayListener)
+        activityDisplayManager.unregisterDisplayListener(activityDisplayListener)
+        application.unregisterComponentCallbacks(applicationComponentCallback)
     }
 
     override fun onResume() {
@@ -110,8 +153,13 @@
         handler.removeCallbacks(updateWindowStateIfChanged)
     }
 
+    /** [onConfigurationChanged] on `Activity`. */
     override fun onConfigurationChanged(newConfig: Configuration) {
         super.onConfigurationChanged(newConfig)
         activityConfigurationView.onWindowStateCallbackInvoked()
     }
+
+    companion object {
+        val TAG = WindowStateCallbackActivity::class.simpleName
+    }
 }
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateView.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateView.kt
index c569e8f..df757f9 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateView.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/coresdk/WindowStateView.kt
@@ -20,12 +20,14 @@
 import android.graphics.Rect
 import android.hardware.display.DisplayManager
 import android.util.AttributeSet
+import android.util.Log
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.LayoutInflater
 import android.view.WindowManager
 import android.widget.LinearLayout
 import androidx.window.demo.R
 import androidx.window.demo.databinding.WindowStateViewBinding
+import androidx.window.layout.WindowMetricsCalculator
 import java.text.SimpleDateFormat
 import java.util.Date
 
@@ -37,29 +39,48 @@
     defStyleRes: Int = 0
 ) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
 
-    private val displayManager: DisplayManager
-    private val windowManager: WindowManager
+    private var title: String = "N/A"
+
+    /**
+     * [DisplayManager]s and [WindowManager]s from `Activity` and `Application` are updated from
+     * different resource configurations, so we show config from them separately.
+     */
+    private val applicationDisplayManager: DisplayManager
+    private val activityDisplayManager: DisplayManager
+    private val windowMetricsCalculator: WindowMetricsCalculator
 
     private val timestampView: WindowStateConfigView
-    private val displayRotationView: WindowStateConfigView
-    private val displayBoundsView: WindowStateConfigView
-    private val prevDisplayRotationView: WindowStateConfigView
-    private val prevDisplayBoundsView: WindowStateConfigView
+    private val applicationDisplayRotationView: WindowStateConfigView
+    private val activityDisplayRotationView: WindowStateConfigView
+    private val applicationDisplayBoundsView: WindowStateConfigView
+    private val activityDisplayBoundsView: WindowStateConfigView
+    private val prevApplicationDisplayRotationView: WindowStateConfigView
+    private val prevActivityDisplayRotationView: WindowStateConfigView
+    private val prevApplicationDisplayBoundsView: WindowStateConfigView
+    private val prevActivityDisplayBoundsView: WindowStateConfigView
 
     private val shouldHidePrevConfig: Boolean
-    private var lastDisplayRotation = -1
-    private val lastDisplayBounds = Rect()
+    private var lastApplicationDisplayRotation = -1
+    private var lastActivityDisplayRotation = -1
+    private val lastApplicationDisplayBounds = Rect()
+    private val lastActivityDisplayBounds = Rect()
 
     init {
-        displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
-        windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+        applicationDisplayManager =
+            context.applicationContext.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+        activityDisplayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+        windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
 
         val viewBinding = WindowStateViewBinding.inflate(LayoutInflater.from(context), this, true)
         timestampView = viewBinding.timestampView
-        displayRotationView = viewBinding.displayRotationView
-        displayBoundsView = viewBinding.displayBoundsView
-        prevDisplayRotationView = viewBinding.prevDisplayRotationView
-        prevDisplayBoundsView = viewBinding.prevDisplayBoundsView
+        applicationDisplayRotationView = viewBinding.applicationDisplayRotationView
+        activityDisplayRotationView = viewBinding.activityDisplayRotationView
+        applicationDisplayBoundsView = viewBinding.applicationDisplayBoundsView
+        activityDisplayBoundsView = viewBinding.activityDisplayBoundsView
+        prevApplicationDisplayRotationView = viewBinding.prevApplicationDisplayRotationView
+        prevActivityDisplayRotationView = viewBinding.prevActivityDisplayRotationView
+        prevApplicationDisplayBoundsView = viewBinding.prevApplicationDisplayBoundsView
+        prevActivityDisplayBoundsView = viewBinding.prevActivityDisplayBoundsView
 
         context.theme.obtainStyledAttributes(
             attrs,
@@ -68,19 +89,26 @@
             try {
                 getString(R.styleable.WindowStateView_title)?.let {
                     viewBinding.callbackTitle.text = it
+                    title = it
                 }
                 shouldHidePrevConfig = getBoolean(
                     R.styleable.WindowStateView_hidePrevConfig,
                     false)
                 if (shouldHidePrevConfig) {
                     timestampView.visibility = GONE
-                    displayRotationView.shouldHighlightChange = false
-                    displayBoundsView.shouldHighlightChange = false
-                    prevDisplayRotationView.visibility = GONE
-                    prevDisplayBoundsView.visibility = GONE
+                    applicationDisplayRotationView.shouldHighlightChange = false
+                    activityDisplayRotationView.shouldHighlightChange = false
+                    applicationDisplayBoundsView.shouldHighlightChange = false
+                    activityDisplayBoundsView.shouldHighlightChange = false
+                    prevApplicationDisplayRotationView.visibility = GONE
+                    prevActivityDisplayRotationView.visibility = GONE
+                    prevApplicationDisplayBoundsView.visibility = GONE
+                    prevActivityDisplayBoundsView.visibility = GONE
                 } else {
-                    displayRotationView.shouldHighlightChange = true
-                    displayBoundsView.shouldHighlightChange = true
+                    applicationDisplayRotationView.shouldHighlightChange = true
+                    activityDisplayRotationView.shouldHighlightChange = true
+                    applicationDisplayBoundsView.shouldHighlightChange = true
+                    activityDisplayBoundsView.shouldHighlightChange = true
                 }
             } finally {
                 recycle()
@@ -90,28 +118,50 @@
 
     /** Called when the corresponding system callback is invoked. */
     fun onWindowStateCallbackInvoked() {
-        val displayRotation = displayManager.getDisplay(DEFAULT_DISPLAY).rotation
-        val displayBounds = windowManager.maximumWindowMetrics.bounds
+        val applicationDisplayRotation =
+            applicationDisplayManager.getDisplay(DEFAULT_DISPLAY).rotation
+        val activityDisplayRotation =
+            activityDisplayManager.getDisplay(DEFAULT_DISPLAY).rotation
+        val applicationDisplayBounds = windowMetricsCalculator
+            .computeMaximumWindowMetrics(context.applicationContext)
+            .bounds
+        val activityDisplayBounds = windowMetricsCalculator
+            .computeMaximumWindowMetrics(context)
+            .bounds
 
         if (shouldHidePrevConfig &&
-            displayRotation == lastDisplayRotation &&
-            displayBounds == lastDisplayBounds) {
+            applicationDisplayRotation == lastApplicationDisplayRotation &&
+            activityDisplayRotation == lastActivityDisplayRotation &&
+            applicationDisplayBounds == lastApplicationDisplayBounds &&
+            activityDisplayBounds == lastActivityDisplayBounds) {
             // Skip if the state is unchanged.
             return
         }
 
-        timestampView.updateValue(TIME_FORMAT.format(Date()))
-        displayRotationView.updateValue(displayRotation.toString())
-        displayBoundsView.updateValue(displayBounds.toString())
-
-        if (!shouldHidePrevConfig && lastDisplayRotation != -1) {
-            // Skip if there is no previous value.
-            prevDisplayRotationView.updateValue(lastDisplayRotation.toString())
-            prevDisplayBoundsView.updateValue(lastDisplayBounds.toString())
+        if (!shouldHidePrevConfig) {
+            // Debug log for the change title.
+            Log.d(WindowStateCallbackActivity.TAG, title)
         }
 
-        lastDisplayRotation = displayRotation
-        lastDisplayBounds.set(displayBounds)
+        timestampView.updateValue(TIME_FORMAT.format(Date()))
+        applicationDisplayRotationView.updateValue(applicationDisplayRotation.toString())
+        activityDisplayRotationView.updateValue(activityDisplayRotation.toString())
+        applicationDisplayBoundsView.updateValue(applicationDisplayBounds.toString())
+        activityDisplayBoundsView.updateValue(activityDisplayBounds.toString())
+
+        if (!shouldHidePrevConfig && lastApplicationDisplayRotation != -1) {
+            // Skip if there is no previous value.
+            prevApplicationDisplayRotationView.updateValue(
+                lastApplicationDisplayRotation.toString())
+            prevActivityDisplayRotationView.updateValue(lastActivityDisplayRotation.toString())
+            prevApplicationDisplayBoundsView.updateValue(lastApplicationDisplayBounds.toString())
+            prevActivityDisplayBoundsView.updateValue(lastActivityDisplayBounds.toString())
+        }
+
+        lastApplicationDisplayRotation = applicationDisplayRotation
+        lastActivityDisplayRotation = activityDisplayRotation
+        lastApplicationDisplayBounds.set(applicationDisplayBounds)
+        lastActivityDisplayBounds.set(activityDisplayBounds)
     }
 
     companion object {
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt
new file mode 100644
index 0000000..d8130d1
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/DemoActivityEmbeddingController.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.window.demo.embedding
+
+import androidx.annotation.GuardedBy
+import androidx.window.embedding.SplitAttributes
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
+
+/** A singleton controller to manage the global config. */
+class DemoActivityEmbeddingController private constructor() {
+    private val lock = ReentrantLock()
+
+    /** Indicates that whether to expand the secondary container or not */
+    internal var shouldExpandSecondaryContainer = AtomicBoolean(false)
+
+    internal var splitAttributesCustomizationEnabled = AtomicBoolean(false)
+
+    internal var customizedLayoutDirection: SplitAttributes.LayoutDirection
+        get() {
+            lock.withLock {
+                return layoutDirectionLocked
+            }
+        }
+        set(value) {
+            lock.withLock {
+                layoutDirectionLocked = value
+            }
+        }
+
+    @GuardedBy("lock")
+    private var layoutDirectionLocked = SplitAttributes.LayoutDirection.LOCALE
+
+    internal var customizedSplitType: SplitAttributes.SplitType
+        get() {
+            lock.withLock {
+                return splitTypeLocked
+            }
+        }
+        set(value) {
+            lock.withLock {
+                splitTypeLocked = value
+            }
+        }
+
+    @GuardedBy("lock")
+    private var splitTypeLocked = SplitAttributes.SplitType.SPLIT_TYPE_EQUAL
+
+    companion object {
+        @Volatile
+        private var globalInstance: DemoActivityEmbeddingController? = null
+        private val globalLock = ReentrantLock()
+
+        /**
+         * Obtains the singleton instance of [DemoActivityEmbeddingController].
+         */
+        @JvmStatic
+        fun getInstance(): DemoActivityEmbeddingController {
+            if (globalInstance == null) {
+                globalLock.withLock {
+                    if (globalInstance == null) {
+                        globalInstance = DemoActivityEmbeddingController()
+                    }
+                }
+            }
+            return globalInstance!!
+        }
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
index 505a365..a797d43 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
@@ -19,6 +19,9 @@
 import android.content.Context
 import androidx.startup.Initializer
 import androidx.window.demo.R
+import androidx.window.demo.embedding.SplitAttributesToggleMainActivity.Companion.PREFIX_FULLSCREEN_TOGGLE
+import androidx.window.demo.embedding.SplitAttributesToggleMainActivity.Companion.PREFIX_PLACEHOLDER
+import androidx.window.demo.embedding.SplitAttributesToggleMainActivity.Companion.TAG_CUSTOMIZED_SPLIT_ATTRIBUTES
 import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.SUFFIX_AND_FULLSCREEN_IN_BOOK_MODE
 import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP
 import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.SUFFIX_REVERSED
@@ -34,6 +37,7 @@
 import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.RIGHT_TO_LEFT
 import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.TOP_TO_BOTTOM
 import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EQUAL
+import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EXPAND
 import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
 import androidx.window.embedding.SplitAttributesCalculatorParams
 import androidx.window.embedding.SplitController
@@ -47,6 +51,8 @@
  */
 class ExampleWindowInitializer : Initializer<RuleController> {
 
+    private val mDemoActivityEmbeddingController = DemoActivityEmbeddingController.getInstance()
+
     override fun create(context: Context): RuleController {
         SplitController.getInstance(context).apply {
             if (isSplitAttributesCalculatorSupported()) {
@@ -68,16 +74,21 @@
     private fun sampleSplitAttributesCalculator(
         params: SplitAttributesCalculatorParams
     ): SplitAttributes {
+        val tag = params.splitRuleTag
+        // The SplitAttributes to occupy the whole task bounds
+        val expandContainersAttrs = SplitAttributes.Builder()
+            .setSplitType(SPLIT_TYPE_EXPAND)
+            .build()
+        if (tag?.startsWith(PREFIX_FULLSCREEN_TOGGLE) == true &&
+            mDemoActivityEmbeddingController.shouldExpandSecondaryContainer.get()
+        ) {
+            return expandContainersAttrs
+        }
         val isPortrait = params.parentWindowMetrics.isPortrait()
         val windowLayoutInfo = params.parentWindowLayoutInfo
         val isTabletop = windowLayoutInfo.isTabletop()
         val isBookMode = windowLayoutInfo.isBookMode()
         val config = params.parentConfiguration
-        // The SplitAttributes to occupy the whole task bounds
-        val expandContainersAttrs = SplitAttributes.Builder()
-            .setSplitType(SplitAttributes.SplitType.SPLIT_TYPE_EXPAND)
-            .build()
-        val tag = params.splitRuleTag
         val shouldReversed = tag?.contains(SUFFIX_REVERSED) ?: false
         // Make a copy of the default splitAttributes, but replace the animation background
         // color to what is configured in the Demo app.
@@ -85,7 +96,11 @@
             .setLayoutDirection(params.defaultSplitAttributes.layoutDirection)
             .setSplitType(params.defaultSplitAttributes.splitType)
             .build()
-        when (tag?.substringBefore(SUFFIX_REVERSED)) {
+        when (tag
+            ?.removePrefix(PREFIX_FULLSCREEN_TOGGLE)
+            ?.removePrefix(PREFIX_PLACEHOLDER)
+            ?.removeSuffix(SUFFIX_REVERSED)
+        ) {
             TAG_USE_DEFAULT_SPLIT_ATTRIBUTES, null -> {
                 return if (params.areDefaultConstraintsSatisfied) {
                     defaultSplitAttributes
@@ -203,6 +218,12 @@
                         .build()
                 }
             }
+            TAG_CUSTOMIZED_SPLIT_ATTRIBUTES -> {
+                return SplitAttributes.Builder()
+                    .setSplitType(mDemoActivityEmbeddingController.customizedSplitType)
+                    .setLayoutDirection(mDemoActivityEmbeddingController.customizedLayoutDirection)
+                    .build()
+            }
         }
         return defaultSplitAttributes
     }
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleActivityBase.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleActivityBase.kt
new file mode 100644
index 0000000..ccde719
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleActivityBase.kt
@@ -0,0 +1,116 @@
+/*
+ * 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.window.demo.embedding
+
+import android.os.Bundle
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.window.demo.R
+import androidx.window.embedding.RuleController
+import androidx.window.embedding.SplitAttributes
+import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EXPAND
+import androidx.window.embedding.SplitController
+import androidx.window.embedding.SplitPairRule
+import androidx.window.embedding.SplitPlaceholderRule
+import androidx.window.embedding.SplitRule
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+open class SplitAttributesToggleActivityBase : AppCompatActivity() {
+    internal lateinit var splitController: SplitController
+    internal lateinit var ruleController: RuleController
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        splitController = SplitController.getInstance(this)
+        ruleController = RuleController.getInstance(this)
+
+        lifecycleScope.launch {
+            // The block passed to repeatOnLifecycle is executed when the lifecycle
+            // is at least STARTED and is cancelled when the lifecycle is STOPPED.
+            // It automatically restarts the block when the lifecycle is STARTED again.
+            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                splitController.splitInfoList(this@SplitAttributesToggleActivityBase)
+                    .map { splitInfoList ->
+                        if (splitInfoList.isEmpty()) {
+                            EXPAND_ATTRS
+                        } else {
+                            splitInfoList.last().splitAttributes
+                        }
+                    }.collect { attrs -> updateSplitAttributesText(attrs) }
+            }
+        }
+    }
+
+    private suspend fun updateSplitAttributesText(splitAttributes: SplitAttributes) =
+        withContext(Dispatchers.Main) {
+            window.decorView.findViewById<TextView>(R.id.activity_pair_split_attributes_text_view)
+                .text = resources.getString(R.string.current_split_attributes) + splitAttributes
+        }
+
+    /** Returns the [SplitRule] this activity participates in. */
+    internal inline fun <reified T : SplitRule> getSplitRule(): T? =
+        ruleController.getRules().find { rule ->
+            if (rule !is T) {
+                return@find false
+            }
+            when (rule) {
+                is SplitPairRule -> {
+                    rule.filters.any { filter ->
+                        filter.primaryActivityName == componentName ||
+                            filter.secondaryActivityName == componentName
+                    }
+                }
+
+                is SplitPlaceholderRule -> {
+                    rule.filters.any { filter -> filter.matchesActivity(this) } ||
+                        rule.placeholderIntent.component == componentName
+                }
+
+                else -> false
+            }
+        } as? T?
+
+    companion object {
+        internal val EXPAND_ATTRS = SplitAttributes.Builder()
+            .setSplitType(SPLIT_TYPE_EXPAND)
+            .build()
+        internal val CUSTOMIZED_SPLIT_TYPES_TEXT = arrayOf(
+            "ratio(0.3)",
+            "ratio(0.5)",
+            "ratio(0.7)",
+            "expand",
+        )
+        internal val CUSTOMIZED_SPLIT_TYPES_VALUE = arrayOf(
+            SplitAttributes.SplitType.ratio(0.3f),
+            SplitAttributes.SplitType.SPLIT_TYPE_EQUAL,
+            SplitAttributes.SplitType.ratio(0.7f),
+            SPLIT_TYPE_EXPAND,
+        )
+        internal val CUSTOMIZED_LAYOUT_DIRECTIONS_TEXT = arrayOf("locale", "bottom_to_top")
+        internal val CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE = arrayOf(
+            SplitAttributes.LayoutDirection.LOCALE,
+            SplitAttributes.LayoutDirection.BOTTOM_TO_TOP,
+        )
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleMainActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleMainActivity.kt
new file mode 100644
index 0000000..1ee12e7
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleMainActivity.kt
@@ -0,0 +1,426 @@
+/*
+ * 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.window.demo.embedding
+
+import android.content.ComponentName
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.AdapterView
+import android.widget.ArrayAdapter
+import android.widget.CompoundButton
+import android.widget.RadioGroup
+import androidx.collection.ArraySet
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.demo.R
+import androidx.window.demo.databinding.ActivitySplitAttributesTogglePrimaryActivityBinding
+import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP
+import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.TAG_SHOW_FULLSCREEN_IN_PORTRAIT
+import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.TAG_USE_DEFAULT_SPLIT_ATTRIBUTES
+import androidx.window.embedding.ActivityEmbeddingController
+import androidx.window.embedding.ActivityFilter
+import androidx.window.embedding.EmbeddingRule
+import androidx.window.embedding.SplitPairFilter
+import androidx.window.embedding.SplitPairRule
+import androidx.window.embedding.SplitPlaceholderRule
+import androidx.window.embedding.SplitRule
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+@OptIn(ExperimentalWindowApi::class)
+open class SplitAttributesToggleMainActivity : SplitAttributesToggleActivityBase(),
+    View.OnClickListener, RadioGroup.OnCheckedChangeListener, AdapterView.OnItemSelectedListener,
+    CompoundButton.OnCheckedChangeListener {
+
+    protected lateinit var viewBinding: ActivitySplitAttributesTogglePrimaryActivityBinding
+    private val pendingRules = ArraySet<EmbeddingRule>()
+
+    internal lateinit var activityEmbeddingController: ActivityEmbeddingController
+
+    private val demoActivityEmbeddingController = DemoActivityEmbeddingController.getInstance()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        viewBinding = ActivitySplitAttributesTogglePrimaryActivityBinding.inflate(layoutInflater)
+        setContentView(viewBinding.root)
+
+        val placeholderFoldingAwareAttrsRadioButton =
+            viewBinding.placeholderUseFoldingAwareSplitAttributes
+        val splitRuleFoldingAwareAttrsRadioButton =
+            viewBinding.splitRuleUseFoldingAwareSplitAttributes
+
+        activityEmbeddingController = ActivityEmbeddingController.getInstance(this)
+
+        if (!splitController.isSplitAttributesCalculatorSupported()) {
+            placeholderFoldingAwareAttrsRadioButton.isEnabled = false
+            viewBinding.placeholderUseCustomizedSplitAttributes.isEnabled = false
+            splitRuleFoldingAwareAttrsRadioButton.isEnabled = false
+            viewBinding.splitRuleUseCustomizedSplitAttributes.isEnabled = false
+        }
+        viewBinding.startPrimaryActivityButton.setOnClickListener(this)
+        viewBinding.useStickyPlaceholderCheckBox.setOnCheckedChangeListener(this)
+        viewBinding.usePlaceholderCheckBox.setOnCheckedChangeListener(this)
+        viewBinding.placeholderSplitLayoutOption.setOnCheckedChangeListener(this)
+        val placeholderSplitTypeSpinner = viewBinding.placeholderSplitTypeSpinner
+        placeholderSplitTypeSpinner.adapter = ArrayAdapter(
+            this,
+            android.R.layout.simple_spinner_dropdown_item,
+            CUSTOMIZED_SPLIT_TYPES_TEXT,
+        )
+        placeholderSplitTypeSpinner.onItemSelectedListener = this
+        val placeholderLayoutDirectionSpinner = viewBinding.placeholderLayoutDirectionSpinner
+        placeholderLayoutDirectionSpinner.adapter = ArrayAdapter(
+            this,
+            android.R.layout.simple_spinner_dropdown_item,
+            CUSTOMIZED_LAYOUT_DIRECTIONS_TEXT,
+        )
+        placeholderLayoutDirectionSpinner.onItemSelectedListener = this
+
+        viewBinding.startActivityPairButton.setOnClickListener(this)
+        viewBinding.useSplitRuleCheckBox.setOnCheckedChangeListener(this)
+        viewBinding.splitRuleSplitLayoutOption.setOnCheckedChangeListener(this)
+        val splitRuleSplitTypeSpinner = viewBinding.splitRuleSplitTypeSpinner
+        splitRuleSplitTypeSpinner.adapter = ArrayAdapter(
+            this,
+            android.R.layout.simple_spinner_dropdown_item,
+            CUSTOMIZED_SPLIT_TYPES_TEXT,
+        )
+        splitRuleSplitTypeSpinner.onItemSelectedListener = this
+        val splitRuleLayoutDirectionSpinner = viewBinding.splitRuleLayoutDirectionSpinner
+        splitRuleLayoutDirectionSpinner.adapter = ArrayAdapter(
+            this,
+            android.R.layout.simple_spinner_dropdown_item,
+            CUSTOMIZED_LAYOUT_DIRECTIONS_TEXT,
+        )
+        splitRuleLayoutDirectionSpinner.onItemSelectedListener = this
+
+        lifecycleScope.launch {
+            // The block passed to repeatOnLifecycle is executed when the lifecycle
+            // is at least STARTED and is cancelled when the lifecycle is STOPPED.
+            // It automatically restarts the block when the lifecycle is STARTED again.
+            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                splitController.splitInfoList(this@SplitAttributesToggleMainActivity)
+                    .collect { updateUiFromRules() }
+            }
+        }
+    }
+
+    open suspend fun updateUiFromRules() {
+        withContext(Dispatchers.Main) {
+            updateWarningMessages()
+            ruleController.getRules().apply {
+                val splitPlaceholderRule = getSplitRule<SplitPlaceholderRule>()
+
+                val hasPlaceholderRule = splitPlaceholderRule != null
+                val usePlaceholderCheckBox = viewBinding.usePlaceholderCheckBox
+
+                var shouldShowSpinner = false
+
+                usePlaceholderCheckBox.isChecked = hasPlaceholderRule
+                onCheckedChanged(usePlaceholderCheckBox, usePlaceholderCheckBox.isChecked)
+                viewBinding.useStickyPlaceholderCheckBox.isChecked =
+                    splitPlaceholderRule?.isSticky ?: false
+                viewBinding.placeholderSplitLayoutOption.check(
+                    when (
+                        splitPlaceholderRule?.tag
+                            ?.removePrefix(PREFIX_FULLSCREEN_TOGGLE)
+                            ?.removePrefix(PREFIX_PLACEHOLDER)
+                    ) {
+                        TAG_USE_DEFAULT_SPLIT_ATTRIBUTES ->
+                            R.id.placeholder_use_default_split_attributes
+                        TAG_SHOW_FULLSCREEN_IN_PORTRAIT +
+                            SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP ->
+                            R.id.placeholder_use_folding_aware_split_attributes
+                        TAG_CUSTOMIZED_SPLIT_ATTRIBUTES ->
+                            R.id.placeholder_use_customized_split_attributes
+                        else -> 0
+                    }
+                )
+                if (viewBinding.placeholderSplitLayoutOption.checkedRadioButtonId ==
+                    R.id.placeholder_use_customized_split_attributes) {
+                    viewBinding.placeholderSplitTypeSpinner.setSelection(
+                        CUSTOMIZED_SPLIT_TYPES_VALUE.indexOf(
+                            demoActivityEmbeddingController.customizedSplitType
+                        )
+                    )
+                    viewBinding.placeholderSplitTypeSpinner.setSelection(
+                        CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE.indexOf(
+                            demoActivityEmbeddingController.customizedLayoutDirection
+                        )
+                    )
+                    shouldShowSpinner = true
+                }
+
+                val splitPairRule = getSplitRule<SplitPairRule>()
+                val useSplitRuleCheckBox = viewBinding.useSplitRuleCheckBox
+                useSplitRuleCheckBox.isChecked = splitPairRule != null
+                onCheckedChanged(useSplitRuleCheckBox, useSplitRuleCheckBox.isChecked)
+                viewBinding.splitRuleSplitLayoutOption.check(
+                    when (
+                        splitPairRule?.tag
+                            ?.removePrefix(PREFIX_FULLSCREEN_TOGGLE)
+                            ?.removePrefix(PREFIX_PLACEHOLDER)
+                    ) {
+                        TAG_USE_DEFAULT_SPLIT_ATTRIBUTES ->
+                            R.id.split_rule_use_single_split_attributes
+                        TAG_SHOW_FULLSCREEN_IN_PORTRAIT +
+                            SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP ->
+                            R.id.split_rule_use_folding_aware_split_attributes
+                        TAG_CUSTOMIZED_SPLIT_ATTRIBUTES ->
+                            R.id.split_rule_use_customized_split_attributes
+                        else -> 0
+                    }
+                )
+                if (viewBinding.splitRuleSplitLayoutOption.checkedRadioButtonId ==
+                    R.id.split_rule_use_customized_split_attributes) {
+                    viewBinding.splitRuleSplitTypeSpinner.setSelection(
+                        CUSTOMIZED_SPLIT_TYPES_VALUE.indexOf(
+                            demoActivityEmbeddingController.customizedSplitType
+                        )
+                    )
+                    viewBinding.splitRuleLayoutDirectionSpinner.setSelection(
+                        CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE.indexOf(
+                            demoActivityEmbeddingController.customizedLayoutDirection
+                        )
+                    )
+                    shouldShowSpinner = true
+                }
+                demoActivityEmbeddingController.splitAttributesCustomizationEnabled
+                    .set(shouldShowSpinner)
+            }
+        }
+    }
+
+    private suspend fun updateWarningMessages() {
+        val warningMessages = StringBuilder().apply {
+            if (!splitController.isSplitAttributesCalculatorSupported()) {
+                append(resources.getString(R.string.split_attributes_calculator_not_supported))
+                append("\n")
+            }
+            if (!activityEmbeddingController.isFinishingActivityStacksSupported()) {
+                append("Finishing secondary activities is not supported on this device!\n")
+            }
+            if (viewBinding.finishSecondaryActivitiesButton.isEnabled &&
+                getSplitRule<SplitPlaceholderRule>() != null
+            ) {
+                append(resources.getString(R.string.show_placeholder_warning))
+                append("\n")
+            }
+        }
+        withContext(Dispatchers.Main) {
+            viewBinding.warningMessageTextView.text = warningMessages
+        }
+    }
+
+    override fun onClick(button: View) {
+        // Update the rules to ruleController before starting the Activity.
+        applyRules()
+        // Set the status to the default.
+        demoActivityEmbeddingController.shouldExpandSecondaryContainer.set(false)
+        val intent = Intent(this, SplitAttributesTogglePrimaryActivity::class.java)
+        when (button.id) {
+            R.id.start_primary_activity_button -> startActivity(intent)
+            R.id.start_activity_pair_button -> {
+                startActivity(intent.putExtra(EXTRA_LAUNCH_SECONDARY, true))
+            }
+        }
+    }
+
+    open fun applyRules() {
+        // Only remove rules with tag specified
+        ruleController.getRules()
+            .filter { rule -> rule.tag?.contains(PREFIX_FULLSCREEN_TOGGLE) ?: false }
+            .forEach { rule -> ruleController.removeRule(rule) }
+
+        for (rule in pendingRules) {
+            ruleController.addRule(rule)
+        }
+    }
+
+    override fun onCheckedChanged(c: CompoundButton, isChecked: Boolean) {
+        val checkBoxId = c.id
+        if (isChecked) {
+            showSubItems(checkBoxId)
+        } else {
+            hideSubItems(checkBoxId)
+        }
+        updatePendingRulesFromUi()
+    }
+
+    private fun showSubItems(checkBoxId: Int) {
+        when (checkBoxId) {
+            R.id.use_placeholder_check_box -> {
+                viewBinding.placeholderChooseLayoutTextView.visibility = View.VISIBLE
+                viewBinding.placeholderSplitLayoutOption.visibility = View.VISIBLE
+                viewBinding.placeholderUseDefaultSplitAttributes.isChecked = true
+                viewBinding.useStickyPlaceholderCheckBox.visibility = View.VISIBLE
+            }
+            R.id.use_split_rule_check_box -> {
+                viewBinding.splitRuleChooseLayoutTextView.visibility = View.VISIBLE
+                viewBinding.splitRuleSplitLayoutOption.visibility = View.VISIBLE
+                viewBinding.splitRuleUseSingleSplitAttributes.isChecked = true
+            }
+        }
+    }
+
+    private fun hideSubItems(checkBoxId: Int) {
+        when (checkBoxId) {
+            R.id.use_placeholder_check_box -> {
+                viewBinding.placeholderChooseLayoutTextView.visibility = View.GONE
+                viewBinding.placeholderSplitLayoutOption.visibility = View.GONE
+                viewBinding.useStickyPlaceholderCheckBox.visibility = View.GONE
+            }
+            R.id.use_split_rule_check_box -> {
+                viewBinding.splitRuleChooseLayoutTextView.visibility = View.GONE
+                viewBinding.splitRuleSplitLayoutOption.visibility = View.GONE
+            }
+        }
+    }
+
+    override fun onCheckedChanged(group: RadioGroup, id: Int) {
+        updatePendingRulesFromUi()
+        updateSpinnerVisibilitiesIfNeeded(id)
+    }
+
+    private fun updatePendingRulesFromUi() {
+        pendingRules.clear()
+        if (viewBinding.usePlaceholderCheckBox.isChecked) {
+            // Create the SplitPlaceholderRule
+            val placeholderFilter = ActivityFilter(
+                ComponentName(
+                    this@SplitAttributesToggleMainActivity,
+                    SplitAttributesTogglePrimaryActivity::class.java
+                ),
+                intentAction = null,
+            )
+            val placeholderIntent = Intent(
+                this@SplitAttributesToggleMainActivity,
+                SplitAttributesTogglePlaceholderActivity::class.java
+            )
+            val splitPlaceholderRule = SplitPlaceholderRule.Builder(
+                setOf(placeholderFilter),
+                placeholderIntent
+            )
+                .setFinishPrimaryWithPlaceholder(SplitRule.FinishBehavior.ALWAYS)
+                .setTag(
+                    PREFIX_FULLSCREEN_TOGGLE + PREFIX_PLACEHOLDER +
+                    when (viewBinding.placeholderSplitLayoutOption.checkedRadioButtonId) {
+                        R.id.placeholder_use_default_split_attributes ->
+                            TAG_USE_DEFAULT_SPLIT_ATTRIBUTES
+                        R.id.placeholder_use_folding_aware_split_attributes ->
+                            TAG_SHOW_FULLSCREEN_IN_PORTRAIT +
+                                SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP
+                        R.id.placeholder_use_customized_split_attributes ->
+                            TAG_CUSTOMIZED_SPLIT_ATTRIBUTES
+                        else -> null
+                    }
+                ).setSticky(viewBinding.useStickyPlaceholderCheckBox.isChecked)
+                .build()
+            pendingRules.add(splitPlaceholderRule)
+        }
+        if (viewBinding.useSplitRuleCheckBox.isChecked) {
+            // Create the SplitPairRule
+            val splitActivityFilter = SplitPairFilter(
+                ComponentName(
+                    this@SplitAttributesToggleMainActivity,
+                    SplitAttributesTogglePrimaryActivity::class.java
+                ),
+                ComponentName(
+                    this@SplitAttributesToggleMainActivity,
+                    SplitAttributesToggleSecondaryActivity::class.java
+                ),
+                secondaryActivityIntentAction = null,
+            )
+            val splitPairRule = SplitPairRule.Builder(setOf(splitActivityFilter))
+                .setFinishPrimaryWithSecondary(SplitRule.FinishBehavior.ALWAYS)
+                .setFinishSecondaryWithPrimary(SplitRule.FinishBehavior.ALWAYS)
+                .setTag(
+                    PREFIX_FULLSCREEN_TOGGLE +
+                    when (viewBinding.splitRuleSplitLayoutOption.checkedRadioButtonId) {
+                        R.id.split_rule_use_single_split_attributes ->
+                            TAG_USE_DEFAULT_SPLIT_ATTRIBUTES
+                        R.id.split_rule_use_folding_aware_split_attributes ->
+                            TAG_SHOW_FULLSCREEN_IN_PORTRAIT +
+                                SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP
+                        R.id.split_rule_use_customized_split_attributes ->
+                            TAG_CUSTOMIZED_SPLIT_ATTRIBUTES
+                        else -> null
+                    }
+                ).build()
+            pendingRules.add(splitPairRule)
+        }
+    }
+
+    private fun updateSpinnerVisibilitiesIfNeeded(id: Int) {
+        when (id) {
+            R.id.placeholder_use_customized_split_attributes,
+            R.id.split_rule_use_customized_split_attributes ->
+                updateSpinnerVisibility(id, View.VISIBLE)
+            else -> {
+                updateSpinnerVisibility(R.id.placeholder_use_customized_split_attributes, View.GONE)
+                updateSpinnerVisibility(R.id.split_rule_use_customized_split_attributes, View.GONE)
+            }
+        }
+    }
+
+    private fun updateSpinnerVisibility(id: Int, visibility: Int) {
+        demoActivityEmbeddingController.splitAttributesCustomizationEnabled
+            .set(visibility == View.VISIBLE)
+        when (id) {
+            R.id.placeholder_use_customized_split_attributes -> {
+                viewBinding.placeholderSplitTypeTextView.visibility = visibility
+                viewBinding.placeholderSplitTypeSpinner.visibility = visibility
+                viewBinding.placeholderLayoutDirectionTextView.visibility = visibility
+                viewBinding.placeholderLayoutDirectionSpinner.visibility = visibility
+            }
+            R.id.split_rule_use_customized_split_attributes -> {
+                viewBinding.splitRuleSplitTypeTextView.visibility = visibility
+                viewBinding.splitRuleSplitTypeSpinner.visibility = visibility
+                viewBinding.splitRuleLayoutDirectionTextView.visibility = visibility
+                viewBinding.splitRuleLayoutDirectionSpinner.visibility = visibility
+            }
+        }
+    }
+
+    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+        when (parent?.id) {
+            R.id.placeholder_split_type_spinner, R.id.split_rule_split_type_spinner ->
+                demoActivityEmbeddingController.customizedSplitType =
+                    CUSTOMIZED_SPLIT_TYPES_VALUE[position]
+            R.id.placeholder_layout_direction_spinner, R.id.split_rule_layout_direction_spinner ->
+                demoActivityEmbeddingController.customizedLayoutDirection =
+                    CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE[position]
+        }
+        splitController.invalidateTopVisibleSplitAttributes()
+    }
+
+    override fun onNothingSelected(view: AdapterView<*>?) {
+        // Auto-generated method stub
+    }
+
+    companion object {
+        internal const val PREFIX_FULLSCREEN_TOGGLE = "fullscreen_toggle_"
+        internal const val PREFIX_PLACEHOLDER = "placeholder_"
+        internal const val EXTRA_LAUNCH_SECONDARY = "launch_secondary"
+        internal const val TAG_CUSTOMIZED_SPLIT_ATTRIBUTES = "customized_split_attributes"
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePlaceholderActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePlaceholderActivity.kt
new file mode 100644
index 0000000..e9fc3b7
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePlaceholderActivity.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.window.demo.embedding
+
+import android.graphics.Color
+import android.os.Bundle
+
+class SplitAttributesTogglePlaceholderActivity : SplitAttributesToggleSecondaryActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        viewBinding.rootSplitActivityLayout.setBackgroundColor(Color.parseColor("#eeeeee"))
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePrimaryActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePrimaryActivity.kt
new file mode 100644
index 0000000..07f269d
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesTogglePrimaryActivity.kt
@@ -0,0 +1,109 @@
+/*
+ * 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.window.demo.embedding
+
+import android.app.Activity
+import android.content.Intent
+import android.graphics.Color
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.demo.R
+import androidx.window.embedding.ActivityStack
+import androidx.window.embedding.SplitInfo
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+
+@OptIn(ExperimentalWindowApi::class)
+class SplitAttributesTogglePrimaryActivity : SplitAttributesToggleMainActivity(),
+    View.OnClickListener {
+
+    private lateinit var secondaryActivityIntent: Intent
+    private var activityStacks: Set<ActivityStack> = emptySet()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        viewBinding.rootSplitActivityLayout.setBackgroundColor(Color.parseColor("#e8f5e9"))
+
+        val isRuntimeApiSupported = activityEmbeddingController
+            .isFinishingActivityStacksSupported()
+
+        secondaryActivityIntent = Intent(
+            this,
+            SplitAttributesToggleSecondaryActivity::class.java
+        )
+
+        if (intent.getBooleanExtra(EXTRA_LAUNCH_SECONDARY, false)) {
+            startActivity(secondaryActivityIntent)
+            // Remove the extra in case the secondary activity is started again when the primary
+            // activity is relaunched.
+            intent.removeExtra(EXTRA_LAUNCH_SECONDARY)
+        }
+
+        // Enable to finish secondary ActivityStacks for primary Activity.
+        viewBinding.finishSecondaryActivitiesDivider.visibility = View.VISIBLE
+        val finishSecondaryActivitiesButton =
+            viewBinding.finishSecondaryActivitiesButton.apply {
+                visibility = View.VISIBLE
+                if (!isRuntimeApiSupported) {
+                    isEnabled = false
+                } else {
+                    setOnClickListener(this@SplitAttributesTogglePrimaryActivity)
+                }
+            }
+
+        lifecycleScope.launch {
+            // The block passed to repeatOnLifecycle is executed when the lifecycle
+            // is at least STARTED and is cancelled when the lifecycle is STOPPED.
+            // It automatically restarts the block when the lifecycle is STARTED again.
+            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                splitController
+                    .splitInfoList(this@SplitAttributesTogglePrimaryActivity)
+                    .onEach { updateUiFromRules() }
+                    .collect { splitInfoList ->
+                        finishSecondaryActivitiesButton.isEnabled = splitInfoList.isNotEmpty()
+                        activityStacks = splitInfoList.mapTo(mutableSetOf()) { splitInfo ->
+                            splitInfo.getTheOtherActivityStack(
+                                this@SplitAttributesTogglePrimaryActivity
+                            )
+                        }
+                    }
+            }
+        }
+    }
+
+    private fun SplitInfo.getTheOtherActivityStack(activity: Activity): ActivityStack =
+        if (activity in primaryActivityStack) {
+            secondaryActivityStack
+        } else {
+            primaryActivityStack
+        }
+
+    override fun onClick(button: View) {
+        super.onClick(button)
+        when (button.id) {
+            R.id.finish_secondary_activities_button -> {
+                applyRules()
+                activityEmbeddingController.finishActivityStacks(activityStacks)
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleSecondaryActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleSecondaryActivity.kt
new file mode 100644
index 0000000..502fb72
--- /dev/null
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitAttributesToggleSecondaryActivity.kt
@@ -0,0 +1,202 @@
+/*
+ * 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.window.demo.embedding
+
+import android.graphics.Color
+import android.os.Bundle
+import android.view.View
+import android.widget.AdapterView
+import android.widget.ArrayAdapter
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.window.core.ExperimentalWindowApi
+import androidx.window.demo.R
+import androidx.window.demo.databinding.ActivitySplitAttributesToggleSecondaryActivityBinding
+import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP
+import androidx.window.demo.embedding.SplitDeviceStateActivityBase.Companion.TAG_SHOW_FULLSCREEN_IN_PORTRAIT
+import androidx.window.embedding.ActivityEmbeddingController
+import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EXPAND
+import androidx.window.embedding.SplitInfo
+import androidx.window.embedding.SplitPlaceholderRule
+import androidx.window.embedding.SplitRule
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.launch
+
+@OptIn(ExperimentalWindowApi::class)
+open class SplitAttributesToggleSecondaryActivity : SplitAttributesToggleActivityBase(),
+    View.OnClickListener, AdapterView.OnItemSelectedListener {
+
+    protected lateinit var viewBinding: ActivitySplitAttributesToggleSecondaryActivityBinding
+
+    private var lastSplitInfo: SplitInfo? = null
+
+    private val demoActivityEmbeddingController = DemoActivityEmbeddingController.getInstance()
+    private lateinit var activityEmbeddingController: ActivityEmbeddingController
+    private var splitAttributesUpdatesSupported: Boolean = false
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        viewBinding = ActivitySplitAttributesToggleSecondaryActivityBinding.inflate(layoutInflater)
+        setContentView(viewBinding.root)
+        val fullscreenToggleButton = viewBinding.fullscreenToggleButton
+
+        viewBinding.rootSplitActivityLayout.setBackgroundColor(Color.parseColor("#fff3e0"))
+
+        // Disable fullscreen mode in case it's enabled by other activities.
+        demoActivityEmbeddingController.shouldExpandSecondaryContainer.set(false)
+
+        activityEmbeddingController = ActivityEmbeddingController.getInstance(this)
+        val splitAttributesCustomizationEnabled = demoActivityEmbeddingController
+            .splitAttributesCustomizationEnabled.get()
+        splitAttributesUpdatesSupported =
+            splitController.isInvalidatingTopVisibleSplitAttributesSupported() &&
+                splitController.isUpdatingSplitAttributesSupported() &&
+                !splitAttributesCustomizationEnabled
+
+        fullscreenToggleButton.apply {
+            // Disable the toggle fullscreen feature if the device doesn't support runtime
+            // SplitAttributes API or split attributes customization is enabled
+            if (!splitAttributesUpdatesSupported) {
+                isEnabled = false
+            } else {
+                setOnClickListener(this@SplitAttributesToggleSecondaryActivity)
+            }
+        }
+
+        if (demoActivityEmbeddingController.splitAttributesCustomizationEnabled.get()) {
+            val splitTypeSpinner = viewBinding.splitTypeSpinner
+            splitTypeSpinner.visibility = View.VISIBLE
+            splitTypeSpinner.adapter = ArrayAdapter(
+                this,
+                android.R.layout.simple_spinner_dropdown_item,
+                CUSTOMIZED_SPLIT_TYPES_TEXT,
+            )
+            splitTypeSpinner.onItemSelectedListener = this
+
+            val layoutDirectionSpinner = viewBinding.layoutDirectionSpinner
+            layoutDirectionSpinner.visibility = View.VISIBLE
+            layoutDirectionSpinner.adapter = ArrayAdapter(
+                this,
+                android.R.layout.simple_spinner_dropdown_item,
+                CUSTOMIZED_LAYOUT_DIRECTIONS_TEXT,
+            )
+            layoutDirectionSpinner.onItemSelectedListener = this
+        }
+
+        lifecycleScope.launch {
+            // The block passed to repeatOnLifecycle is executed when the lifecycle
+            // is at least STARTED and is cancelled when the lifecycle is STOPPED.
+            // It automatically restarts the block when the lifecycle is STARTED again.
+            lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
+                splitController.splitInfoList(this@SplitAttributesToggleSecondaryActivity)
+                    .onEach {
+                        updateWarningMessages()
+                        updateSpinnerFromDemoController()
+                    }
+                    .collect { splitInfoList ->
+                        // Empty split info means this activity doesn't participate any split rule:
+                        // neither the secondary activity of the split pair rule nor the placeholder
+                        // activity of placeholder rule.
+                        fullscreenToggleButton.isEnabled = splitAttributesUpdatesSupported &&
+                            splitInfoList.isNotEmpty()
+
+                        lastSplitInfo = if (splitInfoList.isEmpty()) {
+                            null
+                        } else {
+                            splitInfoList.last()
+                        }
+                    }
+            }
+        }
+    }
+
+    private fun updateSpinnerFromDemoController() {
+        viewBinding.splitTypeSpinner.setSelection(
+            CUSTOMIZED_SPLIT_TYPES_VALUE.indexOf(
+                demoActivityEmbeddingController.customizedSplitType
+            )
+        )
+        viewBinding.layoutDirectionSpinner.setSelection(
+            CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE.indexOf(
+                demoActivityEmbeddingController.customizedLayoutDirection
+            )
+        )
+    }
+
+    private fun updateWarningMessages() {
+        val warningMessages = StringBuilder().apply {
+            if (!splitAttributesUpdatesSupported) {
+                append("Toggling fullscreen mode is not supported on this device!\n")
+            }
+            val splitPlaceholderRule = getSplitRule<SplitPlaceholderRule>()
+            if (splitPlaceholderRule?.isSticky == false) {
+                append("Placeholder activity may show again " +
+                    "when clicking \"TOGGLE FULLSCREEN MODE\". " +
+                    "Clear the placeholder rule and launch Activity again " +
+                    "to remove placeholder rule.\n")
+            }
+        }
+        viewBinding.warningMessageTextView.text = warningMessages
+    }
+
+    override fun onClick(button: View) {
+        when (button.id) {
+            R.id.fullscreen_toggle_button -> {
+                val splitRule = getSplitRule<SplitRule>() ?: return
+                // Toggle the fullscreen mode and trigger SplitAttributes calculation if
+                // the splitAttributes is customized.
+                if (splitRule.tag?.contains(TAG_SHOW_FULLSCREEN_IN_PORTRAIT +
+                    SUFFIX_AND_HORIZONTAL_LAYOUT_IN_TABLETOP) == true
+                ) {
+                    val enableFullscreenMode = DemoActivityEmbeddingController.getInstance()
+                        .shouldExpandSecondaryContainer
+                    enableFullscreenMode.set(!enableFullscreenMode.get())
+                    splitController.invalidateTopVisibleSplitAttributes()
+                } else {
+                    // Update the top splitInfo if single default split Attributes is used.
+                    splitController.updateSplitAttributes(
+                        splitInfo = lastSplitInfo ?: return,
+                        splitAttributes = if (
+                            lastSplitInfo!!.splitAttributes.splitType == SPLIT_TYPE_EXPAND
+                        ) {
+                            splitRule.defaultSplitAttributes
+                        } else {
+                            EXPAND_ATTRS
+                        }
+                    )
+                }
+            }
+        }
+    }
+
+    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
+        when (parent?.id) {
+            R.id.split_type_spinner ->
+                demoActivityEmbeddingController.customizedSplitType =
+                    CUSTOMIZED_SPLIT_TYPES_VALUE[position]
+            R.id.layout_direction_spinner ->
+                demoActivityEmbeddingController.customizedLayoutDirection =
+                    CUSTOMIZED_LAYOUT_DIRECTIONS_VALUE[position]
+        }
+        splitController.invalidateTopVisibleSplitAttributes()
+    }
+
+    override fun onNothingSelected(view: AdapterView<*>?) {
+        // Auto-generated method stub
+    }
+}
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
index e95997c..dbb25ec 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitDeviceStateActivityBase.kt
@@ -94,7 +94,8 @@
             // launched from the primary.
             viewBinding.chooseLayoutTextView.visibility = View.GONE
             radioGroup.visibility = View.GONE
-            viewBinding.launchActivityToSide.text = "Finish this Activity"
+            viewBinding.launchActivityToSide.text = resources
+                .getString(R.string.finish_this_activity)
         }
 
         viewBinding.showHorizontalLayoutInTabletopCheckBox.setOnCheckedChangeListener(this)
@@ -111,7 +112,8 @@
             viewBinding.splitByHingeWhenSeparatingRadioButton.isEnabled = false
             hideAllSubCheckBoxes()
             // Add the error message to notify the SplitAttributesCalculator is not available.
-            viewBinding.errorMessageTextView.text = "SplitAttributesCalculator is not supported!"
+            viewBinding.warningMessageTextView.text = resources
+                .getString(R.string.split_attributes_calculator_not_supported)
         }
 
         lifecycleScope.launch {
@@ -315,7 +317,7 @@
                 // Don't update the error message if the callback is not supported.
                 return@withContext
             }
-            viewBinding.errorMessageTextView.text =
+            viewBinding.warningMessageTextView.text =
                 if (suggestToFinishItself) {
                     "Please finish the activity to try other split configurations."
                 } else {
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitPipActivityBase.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitPipActivityBase.kt
index 4ab221f..7e62662 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitPipActivityBase.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/SplitPipActivityBase.kt
@@ -141,7 +141,7 @@
                 viewBinding.finishSecondaryWithPrimaryCheckBox.isChecked = false
             }
         }
-        if (button.id == R.id.use_place_holder_check_box) {
+        if (button.id == R.id.use_placeholder_check_box) {
             if (isChecked) {
                 viewBinding.useStickyPlaceHolderCheckBox.isEnabled = true
             } else {
diff --git a/window/window-demos/demo/src/main/res/layout/activity_coresdk_window_state_callback_layout.xml b/window/window-demos/demo/src/main/res/layout/activity_coresdk_window_state_callback_layout.xml
index 64c3b56..449fe9a 100644
--- a/window/window-demos/demo/src/main/res/layout/activity_coresdk_window_state_callback_layout.xml
+++ b/window/window-demos/demo/src/main/res/layout/activity_coresdk_window_state_callback_layout.xml
@@ -42,12 +42,40 @@
             android:layout_marginBottom="10dp"
             android:background="#AAAAAA" />
 
-        <!-- Update from DisplayListener. -->
+        <!-- Update from Application DisplayListener. -->
         <androidx.window.demo.coresdk.WindowStateView
-            android:id="@+id/display_listener_view"
+            android:id="@+id/application_display_listener_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            app:title="@string/display_listener_title"/>
+            app:title="@string/application_display_listener_title"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:background="#AAAAAA" />
+
+        <!-- Update from Activity DisplayListener. -->
+        <androidx.window.demo.coresdk.WindowStateView
+            android:id="@+id/activity_display_listener_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:title="@string/activity_display_listener_title"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:background="#AAAAAA" />
+
+        <!-- Update from Application#onConfigurationChanged. -->
+        <androidx.window.demo.coresdk.WindowStateView
+            android:id="@+id/application_configuration_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:title="@string/application_configuration_title"/>
 
         <View
             android:layout_width="match_parent"
diff --git a/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_primary_activity.xml b/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_primary_activity.xml
new file mode 100644
index 0000000..cee9425
--- /dev/null
+++ b/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_primary_activity.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root_split_activity_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:padding="10dp">
+
+        <TextView
+            android:id="@+id/activity_pair_split_attributes_text_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/current_split_attributes"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:background="#AAAAAA" />
+
+        <Button
+            android:id="@+id/start_primary_activity_button"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_centerHorizontal="true"
+            android:text="Launch A" />
+
+        <CheckBox
+            android:id="@+id/use_placeholder_check_box"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Use a placeholder for A" />
+        <CheckBox
+            android:id="@+id/use_sticky_placeholder_check_box"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Placeholder is sticky"
+            android:visibility="gone"/>
+        <TextView
+            android:id="@+id/placeholder_choose_layout_text_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Choose the configuration to update the layout:"
+            android:visibility="gone"/>
+
+        <RadioGroup
+            android:id="@+id/placeholder_split_layout_option"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <RadioButton
+                android:id="@+id/placeholder_use_default_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_default_split_attributes"
+                android:checked="true"/>
+            <RadioButton
+                android:id="@+id/placeholder_use_folding_aware_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_folding_aware_split_attributes"
+                android:checked="false"/>
+            <RadioButton
+                android:id="@+id/placeholder_use_customized_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_customized_split_attributes"
+                android:checked="false"/>
+
+                <TextView
+                    android:id="@+id/placeholder_split_type_text_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:text="@string/choose_split_type"
+                    android:visibility="gone"/>
+                <Spinner
+                    android:id="@+id/placeholder_split_type_spinner"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"/>
+                <TextView
+                    android:id="@+id/placeholder_layout_direction_text_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:text="@string/choose_layout_direction"
+                    android:visibility="gone"/>
+                <Spinner
+                    android:id="@+id/placeholder_layout_direction_spinner"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"/>
+        </RadioGroup>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:background="#AAAAAA" />
+
+        <Button
+            android:id="@+id/start_activity_pair_button"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_centerHorizontal="true"
+            android:text="Launch A and B" />
+
+        <CheckBox
+            android:id="@+id/use_split_rule_check_box"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Split A With B" />
+
+        <TextView
+            android:id="@+id/split_rule_choose_layout_text_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="Choose the configuration to update the layout:"
+            android:visibility="gone"/>
+
+        <RadioGroup
+            android:id="@+id/split_rule_split_layout_option"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+            <RadioButton
+                android:id="@+id/split_rule_use_single_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_default_split_attributes"
+                android:checked="true"/>
+            <RadioButton
+                android:id="@+id/split_rule_use_folding_aware_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_folding_aware_split_attributes"
+                android:checked="false"/>
+            <RadioButton
+                android:id="@+id/split_rule_use_customized_split_attributes"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/use_customized_split_attributes"
+                android:checked="false"/>
+
+                <TextView
+                    android:id="@+id/split_rule_split_type_text_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:text="@string/choose_split_type"
+                    android:visibility="gone"/>
+                <Spinner
+                    android:id="@+id/split_rule_split_type_spinner"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"/>
+                <TextView
+                    android:id="@+id/split_rule_layout_direction_text_view"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:text="@string/choose_layout_direction"
+                    android:visibility="gone"/>
+                <Spinner
+                    android:id="@+id/split_rule_layout_direction_spinner"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:visibility="gone"/>
+        </RadioGroup>
+
+        <View
+            android:id="@+id/finish_secondary_activities_divider"
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:visibility="gone"
+            android:background="#AAAAAA" />
+
+        <Button
+            android:id="@+id/finish_secondary_activities_button"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_centerHorizontal="true"
+            android:text="Finish secondary activities"
+            android:visibility="gone"/>
+
+        <View
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:layout_marginTop="10dp"
+            android:layout_marginBottom="10dp"
+            android:background="#AAAAAA" />
+        <TextView
+            android:id="@+id/warning_message_text_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+    </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_secondary_activity.xml b/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_secondary_activity.xml
new file mode 100644
index 0000000..ba65442
--- /dev/null
+++ b/window/window-demos/demo/src/main/res/layout/activity_split_attributes_toggle_secondary_activity.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/root_split_activity_layout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:padding="10dp">
+
+    <TextView
+        android:id="@+id/activity_pair_split_attributes_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/current_split_attributes"/>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="10dp"
+        android:background="#AAAAAA" />
+
+    <TextView
+        android:id="@+id/split_type_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:text="@string/choose_split_type"
+        android:visibility="gone"/>
+    <Spinner
+        android:id="@+id/split_type_spinner"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"/>
+    <TextView
+        android:id="@+id/layout_direction_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:text="@string/choose_layout_direction"
+        android:visibility="gone"/>
+    <Spinner
+        android:id="@+id/layout_direction_spinner"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:visibility="gone"/>
+
+    <Button
+        android:id="@+id/fullscreen_toggle_button"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:layout_centerHorizontal="true"
+        android:text="Toggle fullscreen mode"/>
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_marginTop="10dp"
+        android:layout_marginBottom="10dp"
+        android:background="#AAAAAA" />
+    <TextView
+        android:id="@+id/warning_message_text_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/res/layout/activity_split_device_state_layout.xml b/window/window-demos/demo/src/main/res/layout/activity_split_device_state_layout.xml
index dcc8ab4..c71a541 100644
--- a/window/window-demos/demo/src/main/res/layout/activity_split_device_state_layout.xml
+++ b/window/window-demos/demo/src/main/res/layout/activity_split_device_state_layout.xml
@@ -54,7 +54,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:text="Use the default split attributes"
+                android:text="@string/use_default_split_attributes"
                 android:checked="true"/>
 
             <!-- The fullscreen option group -->
@@ -157,7 +157,7 @@
             android:layout_marginBottom="10dp"
             android:background="#AAAAAA" />
         <TextView
-            android:id="@+id/error_message_text_view"
+            android:id="@+id/warning_message_text_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>
     </LinearLayout>
diff --git a/window/window-demos/demo/src/main/res/layout/window_state_view.xml b/window/window-demos/demo/src/main/res/layout/window_state_view.xml
index 1944b95..4a03bbd 100644
--- a/window/window-demos/demo/src/main/res/layout/window_state_view.xml
+++ b/window/window-demos/demo/src/main/res/layout/window_state_view.xml
@@ -37,32 +37,60 @@
         android:layout_height="wrap_content"
         app:configName="@string/timestamp_title"/>
 
-    <!-- Display rotation -->
+    <!-- Application Display rotation -->
     <androidx.window.demo.coresdk.WindowStateConfigView
-        android:id="@+id/display_rotation_view"
+        android:id="@+id/application_display_rotation_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:configName="@string/display_rotation_title"/>
+        app:configName="@string/application_display_rotation_title"/>
 
-    <!-- Display bounds -->
+    <!-- Activity Display rotation -->
     <androidx.window.demo.coresdk.WindowStateConfigView
-        android:id="@+id/display_bounds_view"
+        android:id="@+id/activity_display_rotation_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:configName="@string/display_bounds_title"/>
+        app:configName="@string/activity_display_rotation_title"/>
 
-    <!-- Previous Display rotation -->
+    <!-- Application Display bounds -->
     <androidx.window.demo.coresdk.WindowStateConfigView
-        android:id="@+id/prev_display_rotation_view"
+        android:id="@+id/application_display_bounds_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:configName="@string/prev_display_rotation_title"/>
+        app:configName="@string/application_display_bounds_title"/>
 
-    <!-- Previous Display bounds -->
+    <!-- Activity Display bounds -->
     <androidx.window.demo.coresdk.WindowStateConfigView
-        android:id="@+id/prev_display_bounds_view"
+        android:id="@+id/activity_display_bounds_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        app:configName="@string/prev_display_bounds_title"/>
+        app:configName="@string/activity_display_bounds_title"/>
+
+    <!-- Previous Application Display rotation -->
+    <androidx.window.demo.coresdk.WindowStateConfigView
+        android:id="@+id/prev_application_display_rotation_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:configName="@string/prev_application_display_rotation_title"/>
+
+    <!-- Previous Activity Display rotation -->
+    <androidx.window.demo.coresdk.WindowStateConfigView
+        android:id="@+id/prev_activity_display_rotation_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:configName="@string/prev_activity_display_rotation_title"/>
+
+    <!-- Previous Application Display bounds -->
+    <androidx.window.demo.coresdk.WindowStateConfigView
+        android:id="@+id/prev_application_display_bounds_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:configName="@string/prev_application_display_bounds_title"/>
+
+    <!-- Previous Activity Display bounds -->
+    <androidx.window.demo.coresdk.WindowStateConfigView
+        android:id="@+id/prev_activity_display_bounds_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:configName="@string/prev_activity_display_bounds_title"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/window/window-demos/demo/src/main/res/values/strings.xml b/window/window-demos/demo/src/main/res/values/strings.xml
index e9ce55f..fb13fde 100644
--- a/window/window-demos/demo/src/main/res/values/strings.xml
+++ b/window/window-demos/demo/src/main/res/values/strings.xml
@@ -59,13 +59,27 @@
     <string name="install_samples_2">Install window-demos:demo-second-app to launch activities from a different UID.</string>
     <string name="toast_split_not_support">Please enable PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED and ensure device supports splits.</string>
     <string name="latest_configuration_title">Latest Configuration</string>
-    <string name="display_listener_title">DisplayListener#onDisplayChanged</string>
+    <string name="application_display_listener_title">Application DisplayListener#onDisplayChanged</string>
+    <string name="activity_display_listener_title">Activity DisplayListener#onDisplayChanged</string>
+    <string name="application_configuration_title">Application#onConfigurationChanged</string>
     <string name="activity_configuration_title">Activity#onConfigurationChanged</string>
     <string name="display_feature_title">WindowInfoTracker</string>
     <string name="timestamp_title">Timestamp:</string>
-    <string name="display_rotation_title">Display Rotation:</string>
-    <string name="display_bounds_title">Display Bounds:</string>
-    <string name="prev_display_rotation_title">Previous Display Rotation:</string>
-    <string name="prev_display_bounds_title">Previous Display Bounds:</string>
+    <string name="application_display_rotation_title">Application Display Rotation:</string>
+    <string name="activity_display_rotation_title">Activity Display Rotation:</string>
+    <string name="application_display_bounds_title">Application Display Bounds:</string>
+    <string name="activity_display_bounds_title">Activity Display Bounds:</string>
+    <string name="prev_application_display_rotation_title">Previous Application Display Rotation:</string>
+    <string name="prev_activity_display_rotation_title">Previous Activity Display Rotation:</string>
+    <string name="prev_application_display_bounds_title">Previous Application Display Bounds:</string>
+    <string name="prev_activity_display_bounds_title">Previous Activity Display Bounds:</string>
     <string name="window_state_placeholder">N/A</string>
+    <string name="split_attributes_calculator_not_supported">SplitAttributesCalculator is not supported!</string>
+    <string name="finish_this_activity">Finish this Activity</string>
+    <string name="use_default_split_attributes">Use default split attributes</string>
+    <string name="use_folding_aware_split_attributes">Show fullscreen in portrait and horizontal split in tabletop</string>
+    <string name="use_customized_split_attributes">Use runtime changed split attributes</string>
+    <string name="choose_split_type">Choose the split type</string>
+    <string name="choose_layout_direction">Choose the layout direction</string>
+    <string name="show_placeholder_warning">Placeholder Activity may show (again) because "Use a placeholder for A is checked". Clear the check box to expand Activity A to fill the task by either clicking "FINISH SECONDARY ACTIVITIES".</string>
 </resources>
diff --git a/window/window-java/lint-baseline.xml b/window/window-java/lint-baseline.xml
deleted file mode 100644
index 9539a61..0000000
--- a/window/window-java/lint-baseline.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
-
-    <issue
-        id="BanHideAnnotation"
-        message="@hide is not allowed in Javadoc"
-        errorLine1="class WindowAreaControllerJavaAdapter("
-        errorLine2="      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt"/>
-    </issue>
-
-</issues>
diff --git a/window/window-testing/lint-baseline.xml b/window/window-testing/lint-baseline.xml
new file mode 100644
index 0000000..4225368
--- /dev/null
+++ b/window/window-testing/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+
+    <issue
+        id="BanHideAnnotation"
+        message="@hide is not allowed in Javadoc"
+        errorLine1="val TEST_ACTIVITY_STACK_TOKEN = Binder()"
+        errorLine2="    ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt"/>
+    </issue>
+
+</issues>
diff --git a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
index 879ed68..396936b 100644
--- a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
+++ b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
@@ -42,6 +42,7 @@
     isEmpty: Boolean = false,
 ): ActivityStack = ActivityStack(activitiesInProcess, isEmpty, TEST_ACTIVITY_STACK_TOKEN)
 
+/** @hide */
 @RestrictTo(RestrictTo.Scope.LIBRARY)
 @VisibleForTesting
 @JvmField
diff --git a/window/window/api/api_lint.ignore b/window/window/api/api_lint.ignore
index b709875..d427dda 100644
--- a/window/window/api/api_lint.ignore
+++ b/window/window/api/api_lint.ignore
@@ -1,8 +1,6 @@
 // Baseline format: 1.0
 ContextFirst: androidx.window.embedding.ActivityEmbeddingOptions#setLaunchingActivityStack(android.app.ActivityOptions, android.content.Context, androidx.window.embedding.ActivityStack) parameter #1:
-    Context is distinct, so it must be the first argument (method `setLaunchingActivityStack`)
-
-
+    Context is distinct, so it must be the first argument (method `windowLayoutInfoFlowable`)
 GetterSetterNames: field ActivityRule.alwaysExpand:
     Invalid name for boolean property `alwaysExpand`. Should start with one of `has`, `can`, `should`, `is`.
 GetterSetterNames: field SplitAttributesCalculatorParams.areDefaultConstraintsSatisfied:
diff --git a/window/window/src/androidTest/java/androidx/window/WindowPropertiesTest.kt b/window/window/src/androidTest/java/androidx/window/WindowPropertiesTest.kt
index c7cf2f9..57f5d51 100644
--- a/window/window/src/androidTest/java/androidx/window/WindowPropertiesTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/WindowPropertiesTest.kt
@@ -87,6 +87,43 @@
         }
     }
 
+    @Test
+    fun test_property_allow_min_aspect_ratio_override() {
+        assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            // No-op, but to suppress lint
+            return
+        }
+        activityRule.scenario.onActivity { activity ->
+            // Should be false as defined in AndroidManifest.xml
+            assertFalse(
+                getProperty(
+                    activity,
+                    WindowProperties.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE
+                )
+            )
+        }
+    }
+
+    @Test
+    fun test_property_allow_resizeable_activity_overrides() {
+        assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+            // No-op, but to suppress lint
+            return
+        }
+        activityRule.scenario.onActivity { activity ->
+            // Should be false as defined in AndroidManifest.xml
+            assertFalse(
+                getProperty(
+                    activity,
+                    WindowProperties
+                        .PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES
+                )
+            )
+        }
+    }
+
     @RequiresApi(Build.VERSION_CODES.S)
     @Throws(PackageManager.NameNotFoundException::class)
     private fun getProperty(context: Context, propertyName: String): Boolean {
diff --git a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
index 4bda6b5..e664813f 100644
--- a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
@@ -83,7 +83,7 @@
             val extensionComponent = FakeWindowAreaComponent()
             val controller = WindowAreaControllerImpl(
                 windowAreaComponent = extensionComponent,
-                vendorApiLevel = 3
+                vendorApiLevel = FEATURE_VENDOR_API_LEVEL
             )
             extensionComponent.currentRearDisplayStatus = STATUS_UNAVAILABLE
             extensionComponent.currentRearDisplayPresentationStatus = STATUS_UNAVAILABLE
@@ -169,7 +169,7 @@
         val extensions = FakeWindowAreaComponent()
         val controller = WindowAreaControllerImpl(
             windowAreaComponent = extensions,
-            vendorApiLevel = 3
+            vendorApiLevel = FEATURE_VENDOR_API_LEVEL
         )
         extensions.currentRearDisplayStatus = STATUS_AVAILABLE
         val callback = TestWindowAreaSessionCallback()
@@ -233,7 +233,7 @@
         val extensions = FakeWindowAreaComponent()
         val controller = WindowAreaControllerImpl(
             windowAreaComponent = extensions,
-            vendorApiLevel = 2
+            vendorApiLevel = FEATURE_VENDOR_API_LEVEL
         )
         extensions.currentRearDisplayStatus = initialState
         val callback = TestWindowAreaSessionCallback()
@@ -276,7 +276,7 @@
         val extensions = FakeWindowAreaComponent()
         val controller = WindowAreaControllerImpl(
             windowAreaComponent = extensions,
-            vendorApiLevel = 3
+            vendorApiLevel = FEATURE_VENDOR_API_LEVEL
         )
 
         extensions.updateRearDisplayStatusListeners(STATUS_AVAILABLE)
@@ -440,7 +440,7 @@
         val extensionComponent = FakeWindowAreaComponent()
         val controller = WindowAreaControllerImpl(
             windowAreaComponent = extensionComponent,
-            vendorApiLevel = 3
+            vendorApiLevel = FEATURE_VENDOR_API_LEVEL
         )
 
         extensionComponent.updateRearDisplayStatusListeners(STATUS_AVAILABLE)
@@ -650,5 +650,7 @@
 
     companion object {
         private const val REAR_FACING_BINDER_DESCRIPTION = "TEST_WINDOW_AREA_REAR_FACING"
+
+        private const val FEATURE_VENDOR_API_LEVEL = 3
     }
 }
\ No newline at end of file
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt b/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
index 4991be0..d0c39b2 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitAttributes.kt
@@ -50,9 +50,9 @@
  *     attributes are parsed as [SplitType], [LayoutDirection], and
  *     [BackgroundColor], respectively. Note that [SplitType.HingeSplitType]
  *     is not supported XML format.
- *   - Using
- *     [SplitAttributesCalculator.computeSplitAttributesForParams] to customize
- *     the `SplitAttributes` for a given device and window state.
+ *   - Set `SplitAttributes` calculation function by
+ *     [SplitController.setSplitAttributesCalculator]
+ *     to customize the `SplitAttributes` for a given device and window state.
  *
  * @see SplitAttributes.SplitType
  * @see SplitAttributes.LayoutDirection
diff --git a/window/window/src/main/java/androidx/window/embedding/SplitRule.kt b/window/window/src/main/java/androidx/window/embedding/SplitRule.kt
index a69cebc..765876e 100644
--- a/window/window/src/main/java/androidx/window/embedding/SplitRule.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SplitRule.kt
@@ -235,7 +235,11 @@
             return false
         }
         val bounds = Api30Impl.getBounds(parentMetrics)
-        val density = context.resources.displayMetrics.density
+        val density = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
+            context.resources.displayMetrics.density
+        } else {
+            Api34Impl.getDensity(parentMetrics, context)
+        }
         return checkParentBounds(density, bounds)
     }
 
@@ -284,6 +288,19 @@
         }
     }
 
+    @RequiresApi(34)
+    internal object Api34Impl {
+        @DoNotInline
+        fun getDensity(windowMetrics: WindowMetrics, context: Context): Float {
+            // TODO(b/265089843) remove the try catch after U is finalized.
+            return try {
+                windowMetrics.density
+            } catch (e: NoSuchMethodError) {
+                context.resources.displayMetrics.density
+            }
+        }
+    }
+
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other !is SplitRule) return false
diff --git a/window/window/src/main/res/values/attrs.xml b/window/window/src/main/res/values/attrs.xml
index a2880ca..5342612 100644
--- a/window/window/src/main/res/values/attrs.xml
+++ b/window/window/src/main/res/values/attrs.xml
@@ -43,7 +43,7 @@
          `ActivityRule`. The suggested usage is to set the tag to be able to differentiate between
          different rules in the callbacks.
          For example, it can be used to compute the right `SplitAttributes` for the given split rule
-         in `SplitAttributesCalculator.computeSplitAttributesForParams`. -->
+         in `SplitAttributes` calculator function. -->
     <attr name="tag" format="string" />
     <!-- An attribute for Activity Embedding rules.
          Background color of Activity Embedding window animation if the animation requires a
diff --git a/work/work-datatransfer/build.gradle b/work/work-datatransfer/build.gradle
new file mode 100644
index 0000000..77f47f7
--- /dev/null
+++ b/work/work-datatransfer/build.gradle
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import androidx.build.Publish
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+android {
+    namespace "androidx.work.datatransfer"
+}
+
+dependencies {
+    api(project(":work:work-runtime-ktx"))
+    api(libs.kotlinStdlib)
+}
+
+androidx {
+    name = "WorkManager Data Transfer"
+    publish = Publish.SNAPSHOT_ONLY
+    inceptionYear = "2023"
+    description = "Android WorkManager Data Transfer library"
+}
diff --git a/work/work-inspection/lint-baseline.xml b/work/work-inspection/lint-baseline.xml
deleted file mode 100644
index 2ddb484..0000000
--- a/work/work-inspection/lint-baseline.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.4.0-alpha08" type="baseline" client="gradle" dependencies="false" name="AGP (7.4.0-alpha08)" variant="all" version="7.4.0-alpha08">
-
-    <issue
-        id="RemoveWorkManagerInitializer"
-        message="Remove androidx.work.WorkManagerInitializer from your AndroidManifest.xml when using on-demand initialization.">
-        <location
-            file="work-inspection"/>
-    </issue>
-
-</issues>
diff --git a/work/work-runtime/lint-baseline.xml b/work/work-runtime/lint-baseline.xml
index 9b1a604..a920a9d 100644
--- a/work/work-runtime/lint-baseline.xml
+++ b/work/work-runtime/lint-baseline.xml
@@ -139,24 +139,6 @@
     <issue
         id="BanThreadSleep"
         message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(5000L);"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/androidTest/java/androidx/work/impl/WorkContinuationImplTest.java"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
-        errorLine1="        Thread.sleep(1000L);"
-        errorLine2="               ~~~~~">
-        <location
-            file="src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java"/>
-    </issue>
-
-    <issue
-        id="BanThreadSleep"
-        message="Uses Thread.sleep()"
         errorLine1="        Thread.sleep(SLEEP_DURATION_SMALL_MILLIS);"
         errorLine2="               ~~~~~">
         <location
diff --git a/work/work-runtime/src/androidTest/AndroidManifest.xml b/work/work-runtime/src/androidTest/AndroidManifest.xml
index e636ee9..3f130ae 100644
--- a/work/work-runtime/src/androidTest/AndroidManifest.xml
+++ b/work/work-runtime/src/androidTest/AndroidManifest.xml
@@ -14,7 +14,8 @@
   ~ limitations under the License.
   -->
 
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
 
     <!--
       ~ Adding these permissions to the test-app's AndroidManifest.xml. This is because
@@ -24,5 +25,9 @@
     <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
         android:maxSdkVersion="32"/>
     <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
-    <application android:name="androidx.multidex.MultiDexApplication"/>
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
+    <application android:name="androidx.multidex.MultiDexApplication">
+        <service android:name="androidx.work.impl.foreground.SystemForegroundService"
+            android:foregroundServiceType="specialUse" />
+    </application>
 </manifest>
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/ProcessorTests.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/ProcessorTests.kt
index 8c2df9c..8f0fc53 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/ProcessorTests.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/ProcessorTests.kt
@@ -17,6 +17,7 @@
 package androidx.work.impl
 
 import android.content.Context
+import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
 import androidx.core.app.NotificationChannelCompat
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationManagerCompat
@@ -147,7 +148,7 @@
             .setContentText("content text")
             .setSmallIcon(androidx.core.R.drawable.notification_bg)
             .build()
-        val info = ForegroundInfo(1, notification)
+        val info = ForegroundInfo(1, notification, FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
         processor.startForeground(startStopToken.id.workSpecId, info)
         // won't actually stopWork, because stopForeground should be used
         processor.stopWork(startStopToken, 0)